nexus site path corrected
[portal.git] / ecomp-portal-FE / client / bower_components / lodash / lodash.js
1 /**
2  * @license
3  * lodash <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.13.1';
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)\]|(?=(\.|\[\])(?:\4|$))/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     '_', '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 escape characters for inclusion in compiled string literals. */
332   var stringEscapes = {
333     '\\': '\\',
334     "'": "'",
335     '\n': 'n',
336     '\r': 'r',
337     '\u2028': 'u2028',
338     '\u2029': 'u2029'
339   };
340
341   /** Built-in method references without a dependency on `root`. */
342   var freeParseFloat = parseFloat,
343       freeParseInt = parseInt;
344
345   /** Detect free variable `exports`. */
346   var freeExports = typeof exports == 'object' && exports;
347
348   /** Detect free variable `module`. */
349   var freeModule = freeExports && typeof module == 'object' && module;
350
351   /** Detect the popular CommonJS extension `module.exports`. */
352   var moduleExports = freeModule && freeModule.exports === freeExports;
353
354   /** Detect free variable `global` from Node.js. */
355   var freeGlobal = checkGlobal(typeof global == 'object' && global);
356
357   /** Detect free variable `self`. */
358   var freeSelf = checkGlobal(typeof self == 'object' && self);
359
360   /** Detect `this` as the global object. */
361   var thisGlobal = checkGlobal(typeof this == 'object' && this);
362
363   /** Used as a reference to the global object. */
364   var root = freeGlobal || freeSelf || thisGlobal || Function('return this')();
365
366   /*--------------------------------------------------------------------------*/
367
368   /**
369    * Adds the key-value `pair` to `map`.
370    *
371    * @private
372    * @param {Object} map The map to modify.
373    * @param {Array} pair The key-value pair to add.
374    * @returns {Object} Returns `map`.
375    */
376   function addMapEntry(map, pair) {
377     // Don't return `Map#set` because it doesn't return the map instance in IE 11.
378     map.set(pair[0], pair[1]);
379     return map;
380   }
381
382   /**
383    * Adds `value` to `set`.
384    *
385    * @private
386    * @param {Object} set The set to modify.
387    * @param {*} value The value to add.
388    * @returns {Object} Returns `set`.
389    */
390   function addSetEntry(set, value) {
391     set.add(value);
392     return set;
393   }
394
395   /**
396    * A faster alternative to `Function#apply`, this function invokes `func`
397    * with the `this` binding of `thisArg` and the arguments of `args`.
398    *
399    * @private
400    * @param {Function} func The function to invoke.
401    * @param {*} thisArg The `this` binding of `func`.
402    * @param {Array} args The arguments to invoke `func` with.
403    * @returns {*} Returns the result of `func`.
404    */
405   function apply(func, thisArg, args) {
406     var length = args.length;
407     switch (length) {
408       case 0: return func.call(thisArg);
409       case 1: return func.call(thisArg, args[0]);
410       case 2: return func.call(thisArg, args[0], args[1]);
411       case 3: return func.call(thisArg, args[0], args[1], args[2]);
412     }
413     return func.apply(thisArg, args);
414   }
415
416   /**
417    * A specialized version of `baseAggregator` for arrays.
418    *
419    * @private
420    * @param {Array} [array] The array to iterate over.
421    * @param {Function} setter The function to set `accumulator` values.
422    * @param {Function} iteratee The iteratee to transform keys.
423    * @param {Object} accumulator The initial aggregated object.
424    * @returns {Function} Returns `accumulator`.
425    */
426   function arrayAggregator(array, setter, iteratee, accumulator) {
427     var index = -1,
428         length = array ? array.length : 0;
429
430     while (++index < length) {
431       var value = array[index];
432       setter(accumulator, value, iteratee(value), array);
433     }
434     return accumulator;
435   }
436
437   /**
438    * A specialized version of `_.forEach` for arrays without support for
439    * iteratee shorthands.
440    *
441    * @private
442    * @param {Array} [array] The array to iterate over.
443    * @param {Function} iteratee The function invoked per iteration.
444    * @returns {Array} Returns `array`.
445    */
446   function arrayEach(array, iteratee) {
447     var index = -1,
448         length = array ? array.length : 0;
449
450     while (++index < length) {
451       if (iteratee(array[index], index, array) === false) {
452         break;
453       }
454     }
455     return array;
456   }
457
458   /**
459    * A specialized version of `_.forEachRight` for arrays without support for
460    * iteratee shorthands.
461    *
462    * @private
463    * @param {Array} [array] The array to iterate over.
464    * @param {Function} iteratee The function invoked per iteration.
465    * @returns {Array} Returns `array`.
466    */
467   function arrayEachRight(array, iteratee) {
468     var length = array ? array.length : 0;
469
470     while (length--) {
471       if (iteratee(array[length], length, array) === false) {
472         break;
473       }
474     }
475     return array;
476   }
477
478   /**
479    * A specialized version of `_.every` for arrays without support for
480    * iteratee shorthands.
481    *
482    * @private
483    * @param {Array} [array] The array to iterate over.
484    * @param {Function} predicate The function invoked per iteration.
485    * @returns {boolean} Returns `true` if all elements pass the predicate check,
486    *  else `false`.
487    */
488   function arrayEvery(array, predicate) {
489     var index = -1,
490         length = array ? array.length : 0;
491
492     while (++index < length) {
493       if (!predicate(array[index], index, array)) {
494         return false;
495       }
496     }
497     return true;
498   }
499
500   /**
501    * A specialized version of `_.filter` for arrays without support for
502    * iteratee shorthands.
503    *
504    * @private
505    * @param {Array} [array] The array to iterate over.
506    * @param {Function} predicate The function invoked per iteration.
507    * @returns {Array} Returns the new filtered array.
508    */
509   function arrayFilter(array, predicate) {
510     var index = -1,
511         length = array ? array.length : 0,
512         resIndex = 0,
513         result = [];
514
515     while (++index < length) {
516       var value = array[index];
517       if (predicate(value, index, array)) {
518         result[resIndex++] = value;
519       }
520     }
521     return result;
522   }
523
524   /**
525    * A specialized version of `_.includes` for arrays without support for
526    * specifying an index to search from.
527    *
528    * @private
529    * @param {Array} [array] The array to search.
530    * @param {*} target The value to search for.
531    * @returns {boolean} Returns `true` if `target` is found, else `false`.
532    */
533   function arrayIncludes(array, value) {
534     var length = array ? array.length : 0;
535     return !!length && baseIndexOf(array, value, 0) > -1;
536   }
537
538   /**
539    * This function is like `arrayIncludes` except that it accepts a comparator.
540    *
541    * @private
542    * @param {Array} [array] The array to search.
543    * @param {*} target The value to search for.
544    * @param {Function} comparator The comparator invoked per element.
545    * @returns {boolean} Returns `true` if `target` is found, else `false`.
546    */
547   function arrayIncludesWith(array, value, comparator) {
548     var index = -1,
549         length = array ? array.length : 0;
550
551     while (++index < length) {
552       if (comparator(value, array[index])) {
553         return true;
554       }
555     }
556     return false;
557   }
558
559   /**
560    * A specialized version of `_.map` for arrays without support for iteratee
561    * shorthands.
562    *
563    * @private
564    * @param {Array} [array] The array to iterate over.
565    * @param {Function} iteratee The function invoked per iteration.
566    * @returns {Array} Returns the new mapped array.
567    */
568   function arrayMap(array, iteratee) {
569     var index = -1,
570         length = array ? array.length : 0,
571         result = Array(length);
572
573     while (++index < length) {
574       result[index] = iteratee(array[index], index, array);
575     }
576     return result;
577   }
578
579   /**
580    * Appends the elements of `values` to `array`.
581    *
582    * @private
583    * @param {Array} array The array to modify.
584    * @param {Array} values The values to append.
585    * @returns {Array} Returns `array`.
586    */
587   function arrayPush(array, values) {
588     var index = -1,
589         length = values.length,
590         offset = array.length;
591
592     while (++index < length) {
593       array[offset + index] = values[index];
594     }
595     return array;
596   }
597
598   /**
599    * A specialized version of `_.reduce` for arrays without support for
600    * iteratee shorthands.
601    *
602    * @private
603    * @param {Array} [array] The array to iterate over.
604    * @param {Function} iteratee The function invoked per iteration.
605    * @param {*} [accumulator] The initial value.
606    * @param {boolean} [initAccum] Specify using the first element of `array` as
607    *  the initial value.
608    * @returns {*} Returns the accumulated value.
609    */
610   function arrayReduce(array, iteratee, accumulator, initAccum) {
611     var index = -1,
612         length = array ? array.length : 0;
613
614     if (initAccum && length) {
615       accumulator = array[++index];
616     }
617     while (++index < length) {
618       accumulator = iteratee(accumulator, array[index], index, array);
619     }
620     return accumulator;
621   }
622
623   /**
624    * A specialized version of `_.reduceRight` for arrays without support for
625    * iteratee shorthands.
626    *
627    * @private
628    * @param {Array} [array] The array to iterate over.
629    * @param {Function} iteratee The function invoked per iteration.
630    * @param {*} [accumulator] The initial value.
631    * @param {boolean} [initAccum] Specify using the last element of `array` as
632    *  the initial value.
633    * @returns {*} Returns the accumulated value.
634    */
635   function arrayReduceRight(array, iteratee, accumulator, initAccum) {
636     var length = array ? array.length : 0;
637     if (initAccum && length) {
638       accumulator = array[--length];
639     }
640     while (length--) {
641       accumulator = iteratee(accumulator, array[length], length, array);
642     }
643     return accumulator;
644   }
645
646   /**
647    * A specialized version of `_.some` for arrays without support for iteratee
648    * shorthands.
649    *
650    * @private
651    * @param {Array} [array] The array to iterate over.
652    * @param {Function} predicate The function invoked per iteration.
653    * @returns {boolean} Returns `true` if any element passes the predicate check,
654    *  else `false`.
655    */
656   function arraySome(array, predicate) {
657     var index = -1,
658         length = array ? array.length : 0;
659
660     while (++index < length) {
661       if (predicate(array[index], index, array)) {
662         return true;
663       }
664     }
665     return false;
666   }
667
668   /**
669    * The base implementation of methods like `_.findKey` and `_.findLastKey`,
670    * without support for iteratee shorthands, which iterates over `collection`
671    * using `eachFunc`.
672    *
673    * @private
674    * @param {Array|Object} collection The collection to search.
675    * @param {Function} predicate The function invoked per iteration.
676    * @param {Function} eachFunc The function to iterate over `collection`.
677    * @returns {*} Returns the found element or its key, else `undefined`.
678    */
679   function baseFindKey(collection, predicate, eachFunc) {
680     var result;
681     eachFunc(collection, function(value, key, collection) {
682       if (predicate(value, key, collection)) {
683         result = key;
684         return false;
685       }
686     });
687     return result;
688   }
689
690   /**
691    * The base implementation of `_.findIndex` and `_.findLastIndex` without
692    * support for iteratee shorthands.
693    *
694    * @private
695    * @param {Array} array The array to search.
696    * @param {Function} predicate The function invoked per iteration.
697    * @param {number} fromIndex The index to search from.
698    * @param {boolean} [fromRight] Specify iterating from right to left.
699    * @returns {number} Returns the index of the matched value, else `-1`.
700    */
701   function baseFindIndex(array, predicate, fromIndex, fromRight) {
702     var length = array.length,
703         index = fromIndex + (fromRight ? 1 : -1);
704
705     while ((fromRight ? index-- : ++index < length)) {
706       if (predicate(array[index], index, array)) {
707         return index;
708       }
709     }
710     return -1;
711   }
712
713   /**
714    * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
715    *
716    * @private
717    * @param {Array} array The array to search.
718    * @param {*} value The value to search for.
719    * @param {number} fromIndex The index to search from.
720    * @returns {number} Returns the index of the matched value, else `-1`.
721    */
722   function baseIndexOf(array, value, fromIndex) {
723     if (value !== value) {
724       return indexOfNaN(array, fromIndex);
725     }
726     var index = fromIndex - 1,
727         length = array.length;
728
729     while (++index < length) {
730       if (array[index] === value) {
731         return index;
732       }
733     }
734     return -1;
735   }
736
737   /**
738    * This function is like `baseIndexOf` except that it accepts a comparator.
739    *
740    * @private
741    * @param {Array} array The array to search.
742    * @param {*} value The value to search for.
743    * @param {number} fromIndex The index to search from.
744    * @param {Function} comparator The comparator invoked per element.
745    * @returns {number} Returns the index of the matched value, else `-1`.
746    */
747   function baseIndexOfWith(array, value, fromIndex, comparator) {
748     var index = fromIndex - 1,
749         length = array.length;
750
751     while (++index < length) {
752       if (comparator(array[index], value)) {
753         return index;
754       }
755     }
756     return -1;
757   }
758
759   /**
760    * The base implementation of `_.mean` and `_.meanBy` without support for
761    * iteratee shorthands.
762    *
763    * @private
764    * @param {Array} array The array to iterate over.
765    * @param {Function} iteratee The function invoked per iteration.
766    * @returns {number} Returns the mean.
767    */
768   function baseMean(array, iteratee) {
769     var length = array ? array.length : 0;
770     return length ? (baseSum(array, iteratee) / length) : NAN;
771   }
772
773   /**
774    * The base implementation of `_.reduce` and `_.reduceRight`, without support
775    * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
776    *
777    * @private
778    * @param {Array|Object} collection The collection to iterate over.
779    * @param {Function} iteratee The function invoked per iteration.
780    * @param {*} accumulator The initial value.
781    * @param {boolean} initAccum Specify using the first or last element of
782    *  `collection` as the initial value.
783    * @param {Function} eachFunc The function to iterate over `collection`.
784    * @returns {*} Returns the accumulated value.
785    */
786   function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
787     eachFunc(collection, function(value, index, collection) {
788       accumulator = initAccum
789         ? (initAccum = false, value)
790         : iteratee(accumulator, value, index, collection);
791     });
792     return accumulator;
793   }
794
795   /**
796    * The base implementation of `_.sortBy` which uses `comparer` to define the
797    * sort order of `array` and replaces criteria objects with their corresponding
798    * values.
799    *
800    * @private
801    * @param {Array} array The array to sort.
802    * @param {Function} comparer The function to define sort order.
803    * @returns {Array} Returns `array`.
804    */
805   function baseSortBy(array, comparer) {
806     var length = array.length;
807
808     array.sort(comparer);
809     while (length--) {
810       array[length] = array[length].value;
811     }
812     return array;
813   }
814
815   /**
816    * The base implementation of `_.sum` and `_.sumBy` without support for
817    * iteratee shorthands.
818    *
819    * @private
820    * @param {Array} array The array to iterate over.
821    * @param {Function} iteratee The function invoked per iteration.
822    * @returns {number} Returns the sum.
823    */
824   function baseSum(array, iteratee) {
825     var result,
826         index = -1,
827         length = array.length;
828
829     while (++index < length) {
830       var current = iteratee(array[index]);
831       if (current !== undefined) {
832         result = result === undefined ? current : (result + current);
833       }
834     }
835     return result;
836   }
837
838   /**
839    * The base implementation of `_.times` without support for iteratee shorthands
840    * or max array length checks.
841    *
842    * @private
843    * @param {number} n The number of times to invoke `iteratee`.
844    * @param {Function} iteratee The function invoked per iteration.
845    * @returns {Array} Returns the array of results.
846    */
847   function baseTimes(n, iteratee) {
848     var index = -1,
849         result = Array(n);
850
851     while (++index < n) {
852       result[index] = iteratee(index);
853     }
854     return result;
855   }
856
857   /**
858    * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
859    * of key-value pairs for `object` corresponding to the property names of `props`.
860    *
861    * @private
862    * @param {Object} object The object to query.
863    * @param {Array} props The property names to get values for.
864    * @returns {Object} Returns the key-value pairs.
865    */
866   function baseToPairs(object, props) {
867     return arrayMap(props, function(key) {
868       return [key, object[key]];
869     });
870   }
871
872   /**
873    * The base implementation of `_.unary` without support for storing wrapper metadata.
874    *
875    * @private
876    * @param {Function} func The function to cap arguments for.
877    * @returns {Function} Returns the new capped function.
878    */
879   function baseUnary(func) {
880     return function(value) {
881       return func(value);
882     };
883   }
884
885   /**
886    * The base implementation of `_.values` and `_.valuesIn` which creates an
887    * array of `object` property values corresponding to the property names
888    * of `props`.
889    *
890    * @private
891    * @param {Object} object The object to query.
892    * @param {Array} props The property names to get values for.
893    * @returns {Object} Returns the array of property values.
894    */
895   function baseValues(object, props) {
896     return arrayMap(props, function(key) {
897       return object[key];
898     });
899   }
900
901   /**
902    * Checks if a cache value for `key` exists.
903    *
904    * @private
905    * @param {Object} cache The cache to query.
906    * @param {string} key The key of the entry to check.
907    * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
908    */
909   function cacheHas(cache, key) {
910     return cache.has(key);
911   }
912
913   /**
914    * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
915    * that is not found in the character symbols.
916    *
917    * @private
918    * @param {Array} strSymbols The string symbols to inspect.
919    * @param {Array} chrSymbols The character symbols to find.
920    * @returns {number} Returns the index of the first unmatched string symbol.
921    */
922   function charsStartIndex(strSymbols, chrSymbols) {
923     var index = -1,
924         length = strSymbols.length;
925
926     while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
927     return index;
928   }
929
930   /**
931    * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
932    * that is not found in the character symbols.
933    *
934    * @private
935    * @param {Array} strSymbols The string symbols to inspect.
936    * @param {Array} chrSymbols The character symbols to find.
937    * @returns {number} Returns the index of the last unmatched string symbol.
938    */
939   function charsEndIndex(strSymbols, chrSymbols) {
940     var index = strSymbols.length;
941
942     while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
943     return index;
944   }
945
946   /**
947    * Checks if `value` is a global object.
948    *
949    * @private
950    * @param {*} value The value to check.
951    * @returns {null|Object} Returns `value` if it's a global object, else `null`.
952    */
953   function checkGlobal(value) {
954     return (value && value.Object === Object) ? value : null;
955   }
956
957   /**
958    * Gets the number of `placeholder` occurrences in `array`.
959    *
960    * @private
961    * @param {Array} array The array to inspect.
962    * @param {*} placeholder The placeholder to search for.
963    * @returns {number} Returns the placeholder count.
964    */
965   function countHolders(array, placeholder) {
966     var length = array.length,
967         result = 0;
968
969     while (length--) {
970       if (array[length] === placeholder) {
971         result++;
972       }
973     }
974     return result;
975   }
976
977   /**
978    * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
979    *
980    * @private
981    * @param {string} letter The matched letter to deburr.
982    * @returns {string} Returns the deburred letter.
983    */
984   function deburrLetter(letter) {
985     return deburredLetters[letter];
986   }
987
988   /**
989    * Used by `_.escape` to convert characters to HTML entities.
990    *
991    * @private
992    * @param {string} chr The matched character to escape.
993    * @returns {string} Returns the escaped character.
994    */
995   function escapeHtmlChar(chr) {
996     return htmlEscapes[chr];
997   }
998
999   /**
1000    * Used by `_.template` to escape characters for inclusion in compiled string literals.
1001    *
1002    * @private
1003    * @param {string} chr The matched character to escape.
1004    * @returns {string} Returns the escaped character.
1005    */
1006   function escapeStringChar(chr) {
1007     return '\\' + stringEscapes[chr];
1008   }
1009
1010   /**
1011    * Gets the value at `key` of `object`.
1012    *
1013    * @private
1014    * @param {Object} [object] The object to query.
1015    * @param {string} key The key of the property to get.
1016    * @returns {*} Returns the property value.
1017    */
1018   function getValue(object, key) {
1019     return object == null ? undefined : object[key];
1020   }
1021
1022   /**
1023    * Gets the index at which the first occurrence of `NaN` is found in `array`.
1024    *
1025    * @private
1026    * @param {Array} array The array to search.
1027    * @param {number} fromIndex The index to search from.
1028    * @param {boolean} [fromRight] Specify iterating from right to left.
1029    * @returns {number} Returns the index of the matched `NaN`, else `-1`.
1030    */
1031   function indexOfNaN(array, fromIndex, fromRight) {
1032     var length = array.length,
1033         index = fromIndex + (fromRight ? 1 : -1);
1034
1035     while ((fromRight ? index-- : ++index < length)) {
1036       var other = array[index];
1037       if (other !== other) {
1038         return index;
1039       }
1040     }
1041     return -1;
1042   }
1043
1044   /**
1045    * Checks if `value` is a host object in IE < 9.
1046    *
1047    * @private
1048    * @param {*} value The value to check.
1049    * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
1050    */
1051   function isHostObject(value) {
1052     // Many host objects are `Object` objects that can coerce to strings
1053     // despite having improperly defined `toString` methods.
1054     var result = false;
1055     if (value != null && typeof value.toString != 'function') {
1056       try {
1057         result = !!(value + '');
1058       } catch (e) {}
1059     }
1060     return result;
1061   }
1062
1063   /**
1064    * Converts `iterator` to an array.
1065    *
1066    * @private
1067    * @param {Object} iterator The iterator to convert.
1068    * @returns {Array} Returns the converted array.
1069    */
1070   function iteratorToArray(iterator) {
1071     var data,
1072         result = [];
1073
1074     while (!(data = iterator.next()).done) {
1075       result.push(data.value);
1076     }
1077     return result;
1078   }
1079
1080   /**
1081    * Converts `map` to its key-value pairs.
1082    *
1083    * @private
1084    * @param {Object} map The map to convert.
1085    * @returns {Array} Returns the key-value pairs.
1086    */
1087   function mapToArray(map) {
1088     var index = -1,
1089         result = Array(map.size);
1090
1091     map.forEach(function(value, key) {
1092       result[++index] = [key, value];
1093     });
1094     return result;
1095   }
1096
1097   /**
1098    * Replaces all `placeholder` elements in `array` with an internal placeholder
1099    * and returns an array of their indexes.
1100    *
1101    * @private
1102    * @param {Array} array The array to modify.
1103    * @param {*} placeholder The placeholder to replace.
1104    * @returns {Array} Returns the new array of placeholder indexes.
1105    */
1106   function replaceHolders(array, placeholder) {
1107     var index = -1,
1108         length = array.length,
1109         resIndex = 0,
1110         result = [];
1111
1112     while (++index < length) {
1113       var value = array[index];
1114       if (value === placeholder || value === PLACEHOLDER) {
1115         array[index] = PLACEHOLDER;
1116         result[resIndex++] = index;
1117       }
1118     }
1119     return result;
1120   }
1121
1122   /**
1123    * Converts `set` to an array of its values.
1124    *
1125    * @private
1126    * @param {Object} set The set to convert.
1127    * @returns {Array} Returns the values.
1128    */
1129   function setToArray(set) {
1130     var index = -1,
1131         result = Array(set.size);
1132
1133     set.forEach(function(value) {
1134       result[++index] = value;
1135     });
1136     return result;
1137   }
1138
1139   /**
1140    * Converts `set` to its value-value pairs.
1141    *
1142    * @private
1143    * @param {Object} set The set to convert.
1144    * @returns {Array} Returns the value-value pairs.
1145    */
1146   function setToPairs(set) {
1147     var index = -1,
1148         result = Array(set.size);
1149
1150     set.forEach(function(value) {
1151       result[++index] = [value, value];
1152     });
1153     return result;
1154   }
1155
1156   /**
1157    * Gets the number of symbols in `string`.
1158    *
1159    * @private
1160    * @param {string} string The string to inspect.
1161    * @returns {number} Returns the string size.
1162    */
1163   function stringSize(string) {
1164     if (!(string && reHasComplexSymbol.test(string))) {
1165       return string.length;
1166     }
1167     var result = reComplexSymbol.lastIndex = 0;
1168     while (reComplexSymbol.test(string)) {
1169       result++;
1170     }
1171     return result;
1172   }
1173
1174   /**
1175    * Converts `string` to an array.
1176    *
1177    * @private
1178    * @param {string} string The string to convert.
1179    * @returns {Array} Returns the converted array.
1180    */
1181   function stringToArray(string) {
1182     return string.match(reComplexSymbol);
1183   }
1184
1185   /**
1186    * Used by `_.unescape` to convert HTML entities to characters.
1187    *
1188    * @private
1189    * @param {string} chr The matched character to unescape.
1190    * @returns {string} Returns the unescaped character.
1191    */
1192   function unescapeHtmlChar(chr) {
1193     return htmlUnescapes[chr];
1194   }
1195
1196   /*--------------------------------------------------------------------------*/
1197
1198   /**
1199    * Create a new pristine `lodash` function using the `context` object.
1200    *
1201    * @static
1202    * @memberOf _
1203    * @since 1.1.0
1204    * @category Util
1205    * @param {Object} [context=root] The context object.
1206    * @returns {Function} Returns a new `lodash` function.
1207    * @example
1208    *
1209    * _.mixin({ 'foo': _.constant('foo') });
1210    *
1211    * var lodash = _.runInContext();
1212    * lodash.mixin({ 'bar': lodash.constant('bar') });
1213    *
1214    * _.isFunction(_.foo);
1215    * // => true
1216    * _.isFunction(_.bar);
1217    * // => false
1218    *
1219    * lodash.isFunction(lodash.foo);
1220    * // => false
1221    * lodash.isFunction(lodash.bar);
1222    * // => true
1223    *
1224    * // Use `context` to stub `Date#getTime` use in `_.now`.
1225    * var stubbed = _.runInContext({
1226    *   'Date': function() {
1227    *     return { 'getTime': stubGetTime };
1228    *   }
1229    * });
1230    *
1231    * // Create a suped-up `defer` in Node.js.
1232    * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
1233    */
1234   function runInContext(context) {
1235     context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
1236
1237     /** Built-in constructor references. */
1238     var Date = context.Date,
1239         Error = context.Error,
1240         Math = context.Math,
1241         RegExp = context.RegExp,
1242         TypeError = context.TypeError;
1243
1244     /** Used for built-in method references. */
1245     var arrayProto = context.Array.prototype,
1246         objectProto = context.Object.prototype,
1247         stringProto = context.String.prototype;
1248
1249     /** Used to detect overreaching core-js shims. */
1250     var coreJsData = context['__core-js_shared__'];
1251
1252     /** Used to detect methods masquerading as native. */
1253     var maskSrcKey = (function() {
1254       var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
1255       return uid ? ('Symbol(src)_1.' + uid) : '';
1256     }());
1257
1258     /** Used to resolve the decompiled source of functions. */
1259     var funcToString = context.Function.prototype.toString;
1260
1261     /** Used to check objects for own properties. */
1262     var hasOwnProperty = objectProto.hasOwnProperty;
1263
1264     /** Used to generate unique IDs. */
1265     var idCounter = 0;
1266
1267     /** Used to infer the `Object` constructor. */
1268     var objectCtorString = funcToString.call(Object);
1269
1270     /**
1271      * Used to resolve the
1272      * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
1273      * of values.
1274      */
1275     var objectToString = objectProto.toString;
1276
1277     /** Used to restore the original `_` reference in `_.noConflict`. */
1278     var oldDash = root._;
1279
1280     /** Used to detect if a method is native. */
1281     var reIsNative = RegExp('^' +
1282       funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1283       .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1284     );
1285
1286     /** Built-in value references. */
1287     var Buffer = moduleExports ? context.Buffer : undefined,
1288         Reflect = context.Reflect,
1289         Symbol = context.Symbol,
1290         Uint8Array = context.Uint8Array,
1291         enumerate = Reflect ? Reflect.enumerate : undefined,
1292         getOwnPropertySymbols = Object.getOwnPropertySymbols,
1293         iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
1294         objectCreate = Object.create,
1295         propertyIsEnumerable = objectProto.propertyIsEnumerable,
1296         splice = arrayProto.splice;
1297
1298     /** Built-in method references that are mockable. */
1299     var setTimeout = function(func, wait) { return context.setTimeout.call(root, func, wait); };
1300
1301     /* Built-in method references for those with the same name as other `lodash` methods. */
1302     var nativeCeil = Math.ceil,
1303         nativeFloor = Math.floor,
1304         nativeGetPrototype = Object.getPrototypeOf,
1305         nativeIsFinite = context.isFinite,
1306         nativeJoin = arrayProto.join,
1307         nativeKeys = Object.keys,
1308         nativeMax = Math.max,
1309         nativeMin = Math.min,
1310         nativeParseInt = context.parseInt,
1311         nativeRandom = Math.random,
1312         nativeReplace = stringProto.replace,
1313         nativeReverse = arrayProto.reverse,
1314         nativeSplit = stringProto.split;
1315
1316     /* Built-in method references that are verified to be native. */
1317     var DataView = getNative(context, 'DataView'),
1318         Map = getNative(context, 'Map'),
1319         Promise = getNative(context, 'Promise'),
1320         Set = getNative(context, 'Set'),
1321         WeakMap = getNative(context, 'WeakMap'),
1322         nativeCreate = getNative(Object, 'create');
1323
1324     /** Used to store function metadata. */
1325     var metaMap = WeakMap && new WeakMap;
1326
1327     /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */
1328     var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');
1329
1330     /** Used to lookup unminified function names. */
1331     var realNames = {};
1332
1333     /** Used to detect maps, sets, and weakmaps. */
1334     var dataViewCtorString = toSource(DataView),
1335         mapCtorString = toSource(Map),
1336         promiseCtorString = toSource(Promise),
1337         setCtorString = toSource(Set),
1338         weakMapCtorString = toSource(WeakMap);
1339
1340     /** Used to convert symbols to primitives and strings. */
1341     var symbolProto = Symbol ? Symbol.prototype : undefined,
1342         symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
1343         symbolToString = symbolProto ? symbolProto.toString : undefined;
1344
1345     /*------------------------------------------------------------------------*/
1346
1347     /**
1348      * Creates a `lodash` object which wraps `value` to enable implicit method
1349      * chain sequences. Methods that operate on and return arrays, collections,
1350      * and functions can be chained together. Methods that retrieve a single value
1351      * or may return a primitive value will automatically end the chain sequence
1352      * and return the unwrapped value. Otherwise, the value must be unwrapped
1353      * with `_#value`.
1354      *
1355      * Explicit chain sequences, which must be unwrapped with `_#value`, may be
1356      * enabled using `_.chain`.
1357      *
1358      * The execution of chained methods is lazy, that is, it's deferred until
1359      * `_#value` is implicitly or explicitly called.
1360      *
1361      * Lazy evaluation allows several methods to support shortcut fusion.
1362      * Shortcut fusion is an optimization to merge iteratee calls; this avoids
1363      * the creation of intermediate arrays and can greatly reduce the number of
1364      * iteratee executions. Sections of a chain sequence qualify for shortcut
1365      * fusion if the section is applied to an array of at least `200` elements
1366      * and any iteratees accept only one argument. The heuristic for whether a
1367      * section qualifies for shortcut fusion is subject to change.
1368      *
1369      * Chaining is supported in custom builds as long as the `_#value` method is
1370      * directly or indirectly included in the build.
1371      *
1372      * In addition to lodash methods, wrappers have `Array` and `String` methods.
1373      *
1374      * The wrapper `Array` methods are:
1375      * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
1376      *
1377      * The wrapper `String` methods are:
1378      * `replace` and `split`
1379      *
1380      * The wrapper methods that support shortcut fusion are:
1381      * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
1382      * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
1383      * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
1384      *
1385      * The chainable wrapper methods are:
1386      * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
1387      * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
1388      * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
1389      * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
1390      * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
1391      * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
1392      * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
1393      * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
1394      * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
1395      * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
1396      * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
1397      * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
1398      * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
1399      * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
1400      * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
1401      * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
1402      * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
1403      * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
1404      * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
1405      * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
1406      * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
1407      * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
1408      * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
1409      * `zipObject`, `zipObjectDeep`, and `zipWith`
1410      *
1411      * The wrapper methods that are **not** chainable by default are:
1412      * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
1413      * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `divide`, `each`,
1414      * `eachRight`, `endsWith`, `eq`, `escape`, `escapeRegExp`, `every`, `find`,
1415      * `findIndex`, `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `first`,
1416      * `floor`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
1417      * `forOwnRight`, `get`, `gt`, `gte`, `has`, `hasIn`, `head`, `identity`,
1418      * `includes`, `indexOf`, `inRange`, `invoke`, `isArguments`, `isArray`,
1419      * `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`,
1420      * `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`,
1421      * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMap`,
1422      * `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
1423      * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
1424      * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
1425      * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
1426      * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
1427      * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
1428      * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
1429      * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
1430      * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
1431      * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
1432      * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
1433      * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
1434      * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
1435      * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
1436      * `upperFirst`, `value`, and `words`
1437      *
1438      * @name _
1439      * @constructor
1440      * @category Seq
1441      * @param {*} value The value to wrap in a `lodash` instance.
1442      * @returns {Object} Returns the new `lodash` wrapper instance.
1443      * @example
1444      *
1445      * function square(n) {
1446      *   return n * n;
1447      * }
1448      *
1449      * var wrapped = _([1, 2, 3]);
1450      *
1451      * // Returns an unwrapped value.
1452      * wrapped.reduce(_.add);
1453      * // => 6
1454      *
1455      * // Returns a wrapped value.
1456      * var squares = wrapped.map(square);
1457      *
1458      * _.isArray(squares);
1459      * // => false
1460      *
1461      * _.isArray(squares.value());
1462      * // => true
1463      */
1464     function lodash(value) {
1465       if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
1466         if (value instanceof LodashWrapper) {
1467           return value;
1468         }
1469         if (hasOwnProperty.call(value, '__wrapped__')) {
1470           return wrapperClone(value);
1471         }
1472       }
1473       return new LodashWrapper(value);
1474     }
1475
1476     /**
1477      * The function whose prototype chain sequence wrappers inherit from.
1478      *
1479      * @private
1480      */
1481     function baseLodash() {
1482       // No operation performed.
1483     }
1484
1485     /**
1486      * The base constructor for creating `lodash` wrapper objects.
1487      *
1488      * @private
1489      * @param {*} value The value to wrap.
1490      * @param {boolean} [chainAll] Enable explicit method chain sequences.
1491      */
1492     function LodashWrapper(value, chainAll) {
1493       this.__wrapped__ = value;
1494       this.__actions__ = [];
1495       this.__chain__ = !!chainAll;
1496       this.__index__ = 0;
1497       this.__values__ = undefined;
1498     }
1499
1500     /**
1501      * By default, the template delimiters used by lodash are like those in
1502      * embedded Ruby (ERB). Change the following template settings to use
1503      * alternative delimiters.
1504      *
1505      * @static
1506      * @memberOf _
1507      * @type {Object}
1508      */
1509     lodash.templateSettings = {
1510
1511       /**
1512        * Used to detect `data` property values to be HTML-escaped.
1513        *
1514        * @memberOf _.templateSettings
1515        * @type {RegExp}
1516        */
1517       'escape': reEscape,
1518
1519       /**
1520        * Used to detect code to be evaluated.
1521        *
1522        * @memberOf _.templateSettings
1523        * @type {RegExp}
1524        */
1525       'evaluate': reEvaluate,
1526
1527       /**
1528        * Used to detect `data` property values to inject.
1529        *
1530        * @memberOf _.templateSettings
1531        * @type {RegExp}
1532        */
1533       'interpolate': reInterpolate,
1534
1535       /**
1536        * Used to reference the data object in the template text.
1537        *
1538        * @memberOf _.templateSettings
1539        * @type {string}
1540        */
1541       'variable': '',
1542
1543       /**
1544        * Used to import variables into the compiled template.
1545        *
1546        * @memberOf _.templateSettings
1547        * @type {Object}
1548        */
1549       'imports': {
1550
1551         /**
1552          * A reference to the `lodash` function.
1553          *
1554          * @memberOf _.templateSettings.imports
1555          * @type {Function}
1556          */
1557         '_': lodash
1558       }
1559     };
1560
1561     // Ensure wrappers are instances of `baseLodash`.
1562     lodash.prototype = baseLodash.prototype;
1563     lodash.prototype.constructor = lodash;
1564
1565     LodashWrapper.prototype = baseCreate(baseLodash.prototype);
1566     LodashWrapper.prototype.constructor = LodashWrapper;
1567
1568     /*------------------------------------------------------------------------*/
1569
1570     /**
1571      * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
1572      *
1573      * @private
1574      * @constructor
1575      * @param {*} value The value to wrap.
1576      */
1577     function LazyWrapper(value) {
1578       this.__wrapped__ = value;
1579       this.__actions__ = [];
1580       this.__dir__ = 1;
1581       this.__filtered__ = false;
1582       this.__iteratees__ = [];
1583       this.__takeCount__ = MAX_ARRAY_LENGTH;
1584       this.__views__ = [];
1585     }
1586
1587     /**
1588      * Creates a clone of the lazy wrapper object.
1589      *
1590      * @private
1591      * @name clone
1592      * @memberOf LazyWrapper
1593      * @returns {Object} Returns the cloned `LazyWrapper` object.
1594      */
1595     function lazyClone() {
1596       var result = new LazyWrapper(this.__wrapped__);
1597       result.__actions__ = copyArray(this.__actions__);
1598       result.__dir__ = this.__dir__;
1599       result.__filtered__ = this.__filtered__;
1600       result.__iteratees__ = copyArray(this.__iteratees__);
1601       result.__takeCount__ = this.__takeCount__;
1602       result.__views__ = copyArray(this.__views__);
1603       return result;
1604     }
1605
1606     /**
1607      * Reverses the direction of lazy iteration.
1608      *
1609      * @private
1610      * @name reverse
1611      * @memberOf LazyWrapper
1612      * @returns {Object} Returns the new reversed `LazyWrapper` object.
1613      */
1614     function lazyReverse() {
1615       if (this.__filtered__) {
1616         var result = new LazyWrapper(this);
1617         result.__dir__ = -1;
1618         result.__filtered__ = true;
1619       } else {
1620         result = this.clone();
1621         result.__dir__ *= -1;
1622       }
1623       return result;
1624     }
1625
1626     /**
1627      * Extracts the unwrapped value from its lazy wrapper.
1628      *
1629      * @private
1630      * @name value
1631      * @memberOf LazyWrapper
1632      * @returns {*} Returns the unwrapped value.
1633      */
1634     function lazyValue() {
1635       var array = this.__wrapped__.value(),
1636           dir = this.__dir__,
1637           isArr = isArray(array),
1638           isRight = dir < 0,
1639           arrLength = isArr ? array.length : 0,
1640           view = getView(0, arrLength, this.__views__),
1641           start = view.start,
1642           end = view.end,
1643           length = end - start,
1644           index = isRight ? end : (start - 1),
1645           iteratees = this.__iteratees__,
1646           iterLength = iteratees.length,
1647           resIndex = 0,
1648           takeCount = nativeMin(length, this.__takeCount__);
1649
1650       if (!isArr || arrLength < LARGE_ARRAY_SIZE ||
1651           (arrLength == length && takeCount == length)) {
1652         return baseWrapperValue(array, this.__actions__);
1653       }
1654       var result = [];
1655
1656       outer:
1657       while (length-- && resIndex < takeCount) {
1658         index += dir;
1659
1660         var iterIndex = -1,
1661             value = array[index];
1662
1663         while (++iterIndex < iterLength) {
1664           var data = iteratees[iterIndex],
1665               iteratee = data.iteratee,
1666               type = data.type,
1667               computed = iteratee(value);
1668
1669           if (type == LAZY_MAP_FLAG) {
1670             value = computed;
1671           } else if (!computed) {
1672             if (type == LAZY_FILTER_FLAG) {
1673               continue outer;
1674             } else {
1675               break outer;
1676             }
1677           }
1678         }
1679         result[resIndex++] = value;
1680       }
1681       return result;
1682     }
1683
1684     // Ensure `LazyWrapper` is an instance of `baseLodash`.
1685     LazyWrapper.prototype = baseCreate(baseLodash.prototype);
1686     LazyWrapper.prototype.constructor = LazyWrapper;
1687
1688     /*------------------------------------------------------------------------*/
1689
1690     /**
1691      * Creates a hash object.
1692      *
1693      * @private
1694      * @constructor
1695      * @param {Array} [entries] The key-value pairs to cache.
1696      */
1697     function Hash(entries) {
1698       var index = -1,
1699           length = entries ? entries.length : 0;
1700
1701       this.clear();
1702       while (++index < length) {
1703         var entry = entries[index];
1704         this.set(entry[0], entry[1]);
1705       }
1706     }
1707
1708     /**
1709      * Removes all key-value entries from the hash.
1710      *
1711      * @private
1712      * @name clear
1713      * @memberOf Hash
1714      */
1715     function hashClear() {
1716       this.__data__ = nativeCreate ? nativeCreate(null) : {};
1717     }
1718
1719     /**
1720      * Removes `key` and its value from the hash.
1721      *
1722      * @private
1723      * @name delete
1724      * @memberOf Hash
1725      * @param {Object} hash The hash to modify.
1726      * @param {string} key The key of the value to remove.
1727      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1728      */
1729     function hashDelete(key) {
1730       return this.has(key) && delete this.__data__[key];
1731     }
1732
1733     /**
1734      * Gets the hash value for `key`.
1735      *
1736      * @private
1737      * @name get
1738      * @memberOf Hash
1739      * @param {string} key The key of the value to get.
1740      * @returns {*} Returns the entry value.
1741      */
1742     function hashGet(key) {
1743       var data = this.__data__;
1744       if (nativeCreate) {
1745         var result = data[key];
1746         return result === HASH_UNDEFINED ? undefined : result;
1747       }
1748       return hasOwnProperty.call(data, key) ? data[key] : undefined;
1749     }
1750
1751     /**
1752      * Checks if a hash value for `key` exists.
1753      *
1754      * @private
1755      * @name has
1756      * @memberOf Hash
1757      * @param {string} key The key of the entry to check.
1758      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1759      */
1760     function hashHas(key) {
1761       var data = this.__data__;
1762       return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
1763     }
1764
1765     /**
1766      * Sets the hash `key` to `value`.
1767      *
1768      * @private
1769      * @name set
1770      * @memberOf Hash
1771      * @param {string} key The key of the value to set.
1772      * @param {*} value The value to set.
1773      * @returns {Object} Returns the hash instance.
1774      */
1775     function hashSet(key, value) {
1776       var data = this.__data__;
1777       data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
1778       return this;
1779     }
1780
1781     // Add methods to `Hash`.
1782     Hash.prototype.clear = hashClear;
1783     Hash.prototype['delete'] = hashDelete;
1784     Hash.prototype.get = hashGet;
1785     Hash.prototype.has = hashHas;
1786     Hash.prototype.set = hashSet;
1787
1788     /*------------------------------------------------------------------------*/
1789
1790     /**
1791      * Creates an list cache object.
1792      *
1793      * @private
1794      * @constructor
1795      * @param {Array} [entries] The key-value pairs to cache.
1796      */
1797     function ListCache(entries) {
1798       var index = -1,
1799           length = entries ? entries.length : 0;
1800
1801       this.clear();
1802       while (++index < length) {
1803         var entry = entries[index];
1804         this.set(entry[0], entry[1]);
1805       }
1806     }
1807
1808     /**
1809      * Removes all key-value entries from the list cache.
1810      *
1811      * @private
1812      * @name clear
1813      * @memberOf ListCache
1814      */
1815     function listCacheClear() {
1816       this.__data__ = [];
1817     }
1818
1819     /**
1820      * Removes `key` and its value from the list cache.
1821      *
1822      * @private
1823      * @name delete
1824      * @memberOf ListCache
1825      * @param {string} key The key of the value to remove.
1826      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1827      */
1828     function listCacheDelete(key) {
1829       var data = this.__data__,
1830           index = assocIndexOf(data, key);
1831
1832       if (index < 0) {
1833         return false;
1834       }
1835       var lastIndex = data.length - 1;
1836       if (index == lastIndex) {
1837         data.pop();
1838       } else {
1839         splice.call(data, index, 1);
1840       }
1841       return true;
1842     }
1843
1844     /**
1845      * Gets the list cache value for `key`.
1846      *
1847      * @private
1848      * @name get
1849      * @memberOf ListCache
1850      * @param {string} key The key of the value to get.
1851      * @returns {*} Returns the entry value.
1852      */
1853     function listCacheGet(key) {
1854       var data = this.__data__,
1855           index = assocIndexOf(data, key);
1856
1857       return index < 0 ? undefined : data[index][1];
1858     }
1859
1860     /**
1861      * Checks if a list cache value for `key` exists.
1862      *
1863      * @private
1864      * @name has
1865      * @memberOf ListCache
1866      * @param {string} key The key of the entry to check.
1867      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1868      */
1869     function listCacheHas(key) {
1870       return assocIndexOf(this.__data__, key) > -1;
1871     }
1872
1873     /**
1874      * Sets the list cache `key` to `value`.
1875      *
1876      * @private
1877      * @name set
1878      * @memberOf ListCache
1879      * @param {string} key The key of the value to set.
1880      * @param {*} value The value to set.
1881      * @returns {Object} Returns the list cache instance.
1882      */
1883     function listCacheSet(key, value) {
1884       var data = this.__data__,
1885           index = assocIndexOf(data, key);
1886
1887       if (index < 0) {
1888         data.push([key, value]);
1889       } else {
1890         data[index][1] = value;
1891       }
1892       return this;
1893     }
1894
1895     // Add methods to `ListCache`.
1896     ListCache.prototype.clear = listCacheClear;
1897     ListCache.prototype['delete'] = listCacheDelete;
1898     ListCache.prototype.get = listCacheGet;
1899     ListCache.prototype.has = listCacheHas;
1900     ListCache.prototype.set = listCacheSet;
1901
1902     /*------------------------------------------------------------------------*/
1903
1904     /**
1905      * Creates a map cache object to store key-value pairs.
1906      *
1907      * @private
1908      * @constructor
1909      * @param {Array} [entries] The key-value pairs to cache.
1910      */
1911     function MapCache(entries) {
1912       var index = -1,
1913           length = entries ? entries.length : 0;
1914
1915       this.clear();
1916       while (++index < length) {
1917         var entry = entries[index];
1918         this.set(entry[0], entry[1]);
1919       }
1920     }
1921
1922     /**
1923      * Removes all key-value entries from the map.
1924      *
1925      * @private
1926      * @name clear
1927      * @memberOf MapCache
1928      */
1929     function mapCacheClear() {
1930       this.__data__ = {
1931         'hash': new Hash,
1932         'map': new (Map || ListCache),
1933         'string': new Hash
1934       };
1935     }
1936
1937     /**
1938      * Removes `key` and its value from the map.
1939      *
1940      * @private
1941      * @name delete
1942      * @memberOf MapCache
1943      * @param {string} key The key of the value to remove.
1944      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1945      */
1946     function mapCacheDelete(key) {
1947       return getMapData(this, key)['delete'](key);
1948     }
1949
1950     /**
1951      * Gets the map value for `key`.
1952      *
1953      * @private
1954      * @name get
1955      * @memberOf MapCache
1956      * @param {string} key The key of the value to get.
1957      * @returns {*} Returns the entry value.
1958      */
1959     function mapCacheGet(key) {
1960       return getMapData(this, key).get(key);
1961     }
1962
1963     /**
1964      * Checks if a map value for `key` exists.
1965      *
1966      * @private
1967      * @name has
1968      * @memberOf MapCache
1969      * @param {string} key The key of the entry to check.
1970      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1971      */
1972     function mapCacheHas(key) {
1973       return getMapData(this, key).has(key);
1974     }
1975
1976     /**
1977      * Sets the map `key` to `value`.
1978      *
1979      * @private
1980      * @name set
1981      * @memberOf MapCache
1982      * @param {string} key The key of the value to set.
1983      * @param {*} value The value to set.
1984      * @returns {Object} Returns the map cache instance.
1985      */
1986     function mapCacheSet(key, value) {
1987       getMapData(this, key).set(key, value);
1988       return this;
1989     }
1990
1991     // Add methods to `MapCache`.
1992     MapCache.prototype.clear = mapCacheClear;
1993     MapCache.prototype['delete'] = mapCacheDelete;
1994     MapCache.prototype.get = mapCacheGet;
1995     MapCache.prototype.has = mapCacheHas;
1996     MapCache.prototype.set = mapCacheSet;
1997
1998     /*------------------------------------------------------------------------*/
1999
2000     /**
2001      *
2002      * Creates an array cache object to store unique values.
2003      *
2004      * @private
2005      * @constructor
2006      * @param {Array} [values] The values to cache.
2007      */
2008     function SetCache(values) {
2009       var index = -1,
2010           length = values ? values.length : 0;
2011
2012       this.__data__ = new MapCache;
2013       while (++index < length) {
2014         this.add(values[index]);
2015       }
2016     }
2017
2018     /**
2019      * Adds `value` to the array cache.
2020      *
2021      * @private
2022      * @name add
2023      * @memberOf SetCache
2024      * @alias push
2025      * @param {*} value The value to cache.
2026      * @returns {Object} Returns the cache instance.
2027      */
2028     function setCacheAdd(value) {
2029       this.__data__.set(value, HASH_UNDEFINED);
2030       return this;
2031     }
2032
2033     /**
2034      * Checks if `value` is in the array cache.
2035      *
2036      * @private
2037      * @name has
2038      * @memberOf SetCache
2039      * @param {*} value The value to search for.
2040      * @returns {number} Returns `true` if `value` is found, else `false`.
2041      */
2042     function setCacheHas(value) {
2043       return this.__data__.has(value);
2044     }
2045
2046     // Add methods to `SetCache`.
2047     SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
2048     SetCache.prototype.has = setCacheHas;
2049
2050     /*------------------------------------------------------------------------*/
2051
2052     /**
2053      * Creates a stack cache object to store key-value pairs.
2054      *
2055      * @private
2056      * @constructor
2057      * @param {Array} [entries] The key-value pairs to cache.
2058      */
2059     function Stack(entries) {
2060       this.__data__ = new ListCache(entries);
2061     }
2062
2063     /**
2064      * Removes all key-value entries from the stack.
2065      *
2066      * @private
2067      * @name clear
2068      * @memberOf Stack
2069      */
2070     function stackClear() {
2071       this.__data__ = new ListCache;
2072     }
2073
2074     /**
2075      * Removes `key` and its value from the stack.
2076      *
2077      * @private
2078      * @name delete
2079      * @memberOf Stack
2080      * @param {string} key The key of the value to remove.
2081      * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2082      */
2083     function stackDelete(key) {
2084       return this.__data__['delete'](key);
2085     }
2086
2087     /**
2088      * Gets the stack value for `key`.
2089      *
2090      * @private
2091      * @name get
2092      * @memberOf Stack
2093      * @param {string} key The key of the value to get.
2094      * @returns {*} Returns the entry value.
2095      */
2096     function stackGet(key) {
2097       return this.__data__.get(key);
2098     }
2099
2100     /**
2101      * Checks if a stack value for `key` exists.
2102      *
2103      * @private
2104      * @name has
2105      * @memberOf Stack
2106      * @param {string} key The key of the entry to check.
2107      * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2108      */
2109     function stackHas(key) {
2110       return this.__data__.has(key);
2111     }
2112
2113     /**
2114      * Sets the stack `key` to `value`.
2115      *
2116      * @private
2117      * @name set
2118      * @memberOf Stack
2119      * @param {string} key The key of the value to set.
2120      * @param {*} value The value to set.
2121      * @returns {Object} Returns the stack cache instance.
2122      */
2123     function stackSet(key, value) {
2124       var cache = this.__data__;
2125       if (cache instanceof ListCache && cache.__data__.length == LARGE_ARRAY_SIZE) {
2126         cache = this.__data__ = new MapCache(cache.__data__);
2127       }
2128       cache.set(key, value);
2129       return this;
2130     }
2131
2132     // Add methods to `Stack`.
2133     Stack.prototype.clear = stackClear;
2134     Stack.prototype['delete'] = stackDelete;
2135     Stack.prototype.get = stackGet;
2136     Stack.prototype.has = stackHas;
2137     Stack.prototype.set = stackSet;
2138
2139     /*------------------------------------------------------------------------*/
2140
2141     /**
2142      * Used by `_.defaults` to customize its `_.assignIn` use.
2143      *
2144      * @private
2145      * @param {*} objValue The destination value.
2146      * @param {*} srcValue The source value.
2147      * @param {string} key The key of the property to assign.
2148      * @param {Object} object The parent object of `objValue`.
2149      * @returns {*} Returns the value to assign.
2150      */
2151     function assignInDefaults(objValue, srcValue, key, object) {
2152       if (objValue === undefined ||
2153           (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
2154         return srcValue;
2155       }
2156       return objValue;
2157     }
2158
2159     /**
2160      * This function is like `assignValue` except that it doesn't assign
2161      * `undefined` values.
2162      *
2163      * @private
2164      * @param {Object} object The object to modify.
2165      * @param {string} key The key of the property to assign.
2166      * @param {*} value The value to assign.
2167      */
2168     function assignMergeValue(object, key, value) {
2169       if ((value !== undefined && !eq(object[key], value)) ||
2170           (typeof key == 'number' && value === undefined && !(key in object))) {
2171         object[key] = value;
2172       }
2173     }
2174
2175     /**
2176      * Assigns `value` to `key` of `object` if the existing value is not equivalent
2177      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
2178      * for equality comparisons.
2179      *
2180      * @private
2181      * @param {Object} object The object to modify.
2182      * @param {string} key The key of the property to assign.
2183      * @param {*} value The value to assign.
2184      */
2185     function assignValue(object, key, value) {
2186       var objValue = object[key];
2187       if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
2188           (value === undefined && !(key in object))) {
2189         object[key] = value;
2190       }
2191     }
2192
2193     /**
2194      * Gets the index at which the `key` is found in `array` of key-value pairs.
2195      *
2196      * @private
2197      * @param {Array} array The array to search.
2198      * @param {*} key The key to search for.
2199      * @returns {number} Returns the index of the matched value, else `-1`.
2200      */
2201     function assocIndexOf(array, key) {
2202       var length = array.length;
2203       while (length--) {
2204         if (eq(array[length][0], key)) {
2205           return length;
2206         }
2207       }
2208       return -1;
2209     }
2210
2211     /**
2212      * Aggregates elements of `collection` on `accumulator` with keys transformed
2213      * by `iteratee` and values set by `setter`.
2214      *
2215      * @private
2216      * @param {Array|Object} collection The collection to iterate over.
2217      * @param {Function} setter The function to set `accumulator` values.
2218      * @param {Function} iteratee The iteratee to transform keys.
2219      * @param {Object} accumulator The initial aggregated object.
2220      * @returns {Function} Returns `accumulator`.
2221      */
2222     function baseAggregator(collection, setter, iteratee, accumulator) {
2223       baseEach(collection, function(value, key, collection) {
2224         setter(accumulator, value, iteratee(value), collection);
2225       });
2226       return accumulator;
2227     }
2228
2229     /**
2230      * The base implementation of `_.assign` without support for multiple sources
2231      * or `customizer` functions.
2232      *
2233      * @private
2234      * @param {Object} object The destination object.
2235      * @param {Object} source The source object.
2236      * @returns {Object} Returns `object`.
2237      */
2238     function baseAssign(object, source) {
2239       return object && copyObject(source, keys(source), object);
2240     }
2241
2242     /**
2243      * The base implementation of `_.at` without support for individual paths.
2244      *
2245      * @private
2246      * @param {Object} object The object to iterate over.
2247      * @param {string[]} paths The property paths of elements to pick.
2248      * @returns {Array} Returns the picked elements.
2249      */
2250     function baseAt(object, paths) {
2251       var index = -1,
2252           isNil = object == null,
2253           length = paths.length,
2254           result = Array(length);
2255
2256       while (++index < length) {
2257         result[index] = isNil ? undefined : get(object, paths[index]);
2258       }
2259       return result;
2260     }
2261
2262     /**
2263      * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
2264      *
2265      * @private
2266      * @param {number} number The number to clamp.
2267      * @param {number} [lower] The lower bound.
2268      * @param {number} upper The upper bound.
2269      * @returns {number} Returns the clamped number.
2270      */
2271     function baseClamp(number, lower, upper) {
2272       if (number === number) {
2273         if (upper !== undefined) {
2274           number = number <= upper ? number : upper;
2275         }
2276         if (lower !== undefined) {
2277           number = number >= lower ? number : lower;
2278         }
2279       }
2280       return number;
2281     }
2282
2283     /**
2284      * The base implementation of `_.clone` and `_.cloneDeep` which tracks
2285      * traversed objects.
2286      *
2287      * @private
2288      * @param {*} value The value to clone.
2289      * @param {boolean} [isDeep] Specify a deep clone.
2290      * @param {boolean} [isFull] Specify a clone including symbols.
2291      * @param {Function} [customizer] The function to customize cloning.
2292      * @param {string} [key] The key of `value`.
2293      * @param {Object} [object] The parent object of `value`.
2294      * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
2295      * @returns {*} Returns the cloned value.
2296      */
2297     function baseClone(value, isDeep, isFull, customizer, key, object, stack) {
2298       var result;
2299       if (customizer) {
2300         result = object ? customizer(value, key, object, stack) : customizer(value);
2301       }
2302       if (result !== undefined) {
2303         return result;
2304       }
2305       if (!isObject(value)) {
2306         return value;
2307       }
2308       var isArr = isArray(value);
2309       if (isArr) {
2310         result = initCloneArray(value);
2311         if (!isDeep) {
2312           return copyArray(value, result);
2313         }
2314       } else {
2315         var tag = getTag(value),
2316             isFunc = tag == funcTag || tag == genTag;
2317
2318         if (isBuffer(value)) {
2319           return cloneBuffer(value, isDeep);
2320         }
2321         if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
2322           if (isHostObject(value)) {
2323             return object ? value : {};
2324           }
2325           result = initCloneObject(isFunc ? {} : value);
2326           if (!isDeep) {
2327             return copySymbols(value, baseAssign(result, value));
2328           }
2329         } else {
2330           if (!cloneableTags[tag]) {
2331             return object ? value : {};
2332           }
2333           result = initCloneByTag(value, tag, baseClone, isDeep);
2334         }
2335       }
2336       // Check for circular references and return its corresponding clone.
2337       stack || (stack = new Stack);
2338       var stacked = stack.get(value);
2339       if (stacked) {
2340         return stacked;
2341       }
2342       stack.set(value, result);
2343
2344       if (!isArr) {
2345         var props = isFull ? getAllKeys(value) : keys(value);
2346       }
2347       // Recursively populate clone (susceptible to call stack limits).
2348       arrayEach(props || value, function(subValue, key) {
2349         if (props) {
2350           key = subValue;
2351           subValue = value[key];
2352         }
2353         assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));
2354       });
2355       return result;
2356     }
2357
2358     /**
2359      * The base implementation of `_.conforms` which doesn't clone `source`.
2360      *
2361      * @private
2362      * @param {Object} source The object of property predicates to conform to.
2363      * @returns {Function} Returns the new spec function.
2364      */
2365     function baseConforms(source) {
2366       var props = keys(source),
2367           length = props.length;
2368
2369       return function(object) {
2370         if (object == null) {
2371           return !length;
2372         }
2373         var index = length;
2374         while (index--) {
2375           var key = props[index],
2376               predicate = source[key],
2377               value = object[key];
2378
2379           if ((value === undefined &&
2380               !(key in Object(object))) || !predicate(value)) {
2381             return false;
2382           }
2383         }
2384         return true;
2385       };
2386     }
2387
2388     /**
2389      * The base implementation of `_.create` without support for assigning
2390      * properties to the created object.
2391      *
2392      * @private
2393      * @param {Object} prototype The object to inherit from.
2394      * @returns {Object} Returns the new object.
2395      */
2396     function baseCreate(proto) {
2397       return isObject(proto) ? objectCreate(proto) : {};
2398     }
2399
2400     /**
2401      * The base implementation of `_.delay` and `_.defer` which accepts an array
2402      * of `func` arguments.
2403      *
2404      * @private
2405      * @param {Function} func The function to delay.
2406      * @param {number} wait The number of milliseconds to delay invocation.
2407      * @param {Object} args The arguments to provide to `func`.
2408      * @returns {number} Returns the timer id.
2409      */
2410     function baseDelay(func, wait, args) {
2411       if (typeof func != 'function') {
2412         throw new TypeError(FUNC_ERROR_TEXT);
2413       }
2414       return setTimeout(function() { func.apply(undefined, args); }, wait);
2415     }
2416
2417     /**
2418      * The base implementation of methods like `_.difference` without support
2419      * for excluding multiple arrays or iteratee shorthands.
2420      *
2421      * @private
2422      * @param {Array} array The array to inspect.
2423      * @param {Array} values The values to exclude.
2424      * @param {Function} [iteratee] The iteratee invoked per element.
2425      * @param {Function} [comparator] The comparator invoked per element.
2426      * @returns {Array} Returns the new array of filtered values.
2427      */
2428     function baseDifference(array, values, iteratee, comparator) {
2429       var index = -1,
2430           includes = arrayIncludes,
2431           isCommon = true,
2432           length = array.length,
2433           result = [],
2434           valuesLength = values.length;
2435
2436       if (!length) {
2437         return result;
2438       }
2439       if (iteratee) {
2440         values = arrayMap(values, baseUnary(iteratee));
2441       }
2442       if (comparator) {
2443         includes = arrayIncludesWith;
2444         isCommon = false;
2445       }
2446       else if (values.length >= LARGE_ARRAY_SIZE) {
2447         includes = cacheHas;
2448         isCommon = false;
2449         values = new SetCache(values);
2450       }
2451       outer:
2452       while (++index < length) {
2453         var value = array[index],
2454             computed = iteratee ? iteratee(value) : value;
2455
2456         value = (comparator || value !== 0) ? value : 0;
2457         if (isCommon && computed === computed) {
2458           var valuesIndex = valuesLength;
2459           while (valuesIndex--) {
2460             if (values[valuesIndex] === computed) {
2461               continue outer;
2462             }
2463           }
2464           result.push(value);
2465         }
2466         else if (!includes(values, computed, comparator)) {
2467           result.push(value);
2468         }
2469       }
2470       return result;
2471     }
2472
2473     /**
2474      * The base implementation of `_.forEach` without support for iteratee shorthands.
2475      *
2476      * @private
2477      * @param {Array|Object} collection The collection to iterate over.
2478      * @param {Function} iteratee The function invoked per iteration.
2479      * @returns {Array|Object} Returns `collection`.
2480      */
2481     var baseEach = createBaseEach(baseForOwn);
2482
2483     /**
2484      * The base implementation of `_.forEachRight` without support for iteratee shorthands.
2485      *
2486      * @private
2487      * @param {Array|Object} collection The collection to iterate over.
2488      * @param {Function} iteratee The function invoked per iteration.
2489      * @returns {Array|Object} Returns `collection`.
2490      */
2491     var baseEachRight = createBaseEach(baseForOwnRight, true);
2492
2493     /**
2494      * The base implementation of `_.every` without support for iteratee shorthands.
2495      *
2496      * @private
2497      * @param {Array|Object} collection The collection to iterate over.
2498      * @param {Function} predicate The function invoked per iteration.
2499      * @returns {boolean} Returns `true` if all elements pass the predicate check,
2500      *  else `false`
2501      */
2502     function baseEvery(collection, predicate) {
2503       var result = true;
2504       baseEach(collection, function(value, index, collection) {
2505         result = !!predicate(value, index, collection);
2506         return result;
2507       });
2508       return result;
2509     }
2510
2511     /**
2512      * The base implementation of methods like `_.max` and `_.min` which accepts a
2513      * `comparator` to determine the extremum value.
2514      *
2515      * @private
2516      * @param {Array} array The array to iterate over.
2517      * @param {Function} iteratee The iteratee invoked per iteration.
2518      * @param {Function} comparator The comparator used to compare values.
2519      * @returns {*} Returns the extremum value.
2520      */
2521     function baseExtremum(array, iteratee, comparator) {
2522       var index = -1,
2523           length = array.length;
2524
2525       while (++index < length) {
2526         var value = array[index],
2527             current = iteratee(value);
2528
2529         if (current != null && (computed === undefined
2530               ? (current === current && !isSymbol(current))
2531               : comparator(current, computed)
2532             )) {
2533           var computed = current,
2534               result = value;
2535         }
2536       }
2537       return result;
2538     }
2539
2540     /**
2541      * The base implementation of `_.fill` without an iteratee call guard.
2542      *
2543      * @private
2544      * @param {Array} array The array to fill.
2545      * @param {*} value The value to fill `array` with.
2546      * @param {number} [start=0] The start position.
2547      * @param {number} [end=array.length] The end position.
2548      * @returns {Array} Returns `array`.
2549      */
2550     function baseFill(array, value, start, end) {
2551       var length = array.length;
2552
2553       start = toInteger(start);
2554       if (start < 0) {
2555         start = -start > length ? 0 : (length + start);
2556       }
2557       end = (end === undefined || end > length) ? length : toInteger(end);
2558       if (end < 0) {
2559         end += length;
2560       }
2561       end = start > end ? 0 : toLength(end);
2562       while (start < end) {
2563         array[start++] = value;
2564       }
2565       return array;
2566     }
2567
2568     /**
2569      * The base implementation of `_.filter` without support for iteratee shorthands.
2570      *
2571      * @private
2572      * @param {Array|Object} collection The collection to iterate over.
2573      * @param {Function} predicate The function invoked per iteration.
2574      * @returns {Array} Returns the new filtered array.
2575      */
2576     function baseFilter(collection, predicate) {
2577       var result = [];
2578       baseEach(collection, function(value, index, collection) {
2579         if (predicate(value, index, collection)) {
2580           result.push(value);
2581         }
2582       });
2583       return result;
2584     }
2585
2586     /**
2587      * The base implementation of `_.flatten` with support for restricting flattening.
2588      *
2589      * @private
2590      * @param {Array} array The array to flatten.
2591      * @param {number} depth The maximum recursion depth.
2592      * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
2593      * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
2594      * @param {Array} [result=[]] The initial result value.
2595      * @returns {Array} Returns the new flattened array.
2596      */
2597     function baseFlatten(array, depth, predicate, isStrict, result) {
2598       var index = -1,
2599           length = array.length;
2600
2601       predicate || (predicate = isFlattenable);
2602       result || (result = []);
2603
2604       while (++index < length) {
2605         var value = array[index];
2606         if (depth > 0 && predicate(value)) {
2607           if (depth > 1) {
2608             // Recursively flatten arrays (susceptible to call stack limits).
2609             baseFlatten(value, depth - 1, predicate, isStrict, result);
2610           } else {
2611             arrayPush(result, value);
2612           }
2613         } else if (!isStrict) {
2614           result[result.length] = value;
2615         }
2616       }
2617       return result;
2618     }
2619
2620     /**
2621      * The base implementation of `baseForOwn` which iterates over `object`
2622      * properties returned by `keysFunc` and invokes `iteratee` for each property.
2623      * Iteratee functions may exit iteration early by explicitly returning `false`.
2624      *
2625      * @private
2626      * @param {Object} object The object to iterate over.
2627      * @param {Function} iteratee The function invoked per iteration.
2628      * @param {Function} keysFunc The function to get the keys of `object`.
2629      * @returns {Object} Returns `object`.
2630      */
2631     var baseFor = createBaseFor();
2632
2633     /**
2634      * This function is like `baseFor` except that it iterates over properties
2635      * in the opposite order.
2636      *
2637      * @private
2638      * @param {Object} object The object to iterate over.
2639      * @param {Function} iteratee The function invoked per iteration.
2640      * @param {Function} keysFunc The function to get the keys of `object`.
2641      * @returns {Object} Returns `object`.
2642      */
2643     var baseForRight = createBaseFor(true);
2644
2645     /**
2646      * The base implementation of `_.forOwn` without support for iteratee shorthands.
2647      *
2648      * @private
2649      * @param {Object} object The object to iterate over.
2650      * @param {Function} iteratee The function invoked per iteration.
2651      * @returns {Object} Returns `object`.
2652      */
2653     function baseForOwn(object, iteratee) {
2654       return object && baseFor(object, iteratee, keys);
2655     }
2656
2657     /**
2658      * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
2659      *
2660      * @private
2661      * @param {Object} object The object to iterate over.
2662      * @param {Function} iteratee The function invoked per iteration.
2663      * @returns {Object} Returns `object`.
2664      */
2665     function baseForOwnRight(object, iteratee) {
2666       return object && baseForRight(object, iteratee, keys);
2667     }
2668
2669     /**
2670      * The base implementation of `_.functions` which creates an array of
2671      * `object` function property names filtered from `props`.
2672      *
2673      * @private
2674      * @param {Object} object The object to inspect.
2675      * @param {Array} props The property names to filter.
2676      * @returns {Array} Returns the function names.
2677      */
2678     function baseFunctions(object, props) {
2679       return arrayFilter(props, function(key) {
2680         return isFunction(object[key]);
2681       });
2682     }
2683
2684     /**
2685      * The base implementation of `_.get` without support for default values.
2686      *
2687      * @private
2688      * @param {Object} object The object to query.
2689      * @param {Array|string} path The path of the property to get.
2690      * @returns {*} Returns the resolved value.
2691      */
2692     function baseGet(object, path) {
2693       path = isKey(path, object) ? [path] : castPath(path);
2694
2695       var index = 0,
2696           length = path.length;
2697
2698       while (object != null && index < length) {
2699         object = object[toKey(path[index++])];
2700       }
2701       return (index && index == length) ? object : undefined;
2702     }
2703
2704     /**
2705      * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
2706      * `keysFunc` and `symbolsFunc` to get the enumerable property names and
2707      * symbols of `object`.
2708      *
2709      * @private
2710      * @param {Object} object The object to query.
2711      * @param {Function} keysFunc The function to get the keys of `object`.
2712      * @param {Function} symbolsFunc The function to get the symbols of `object`.
2713      * @returns {Array} Returns the array of property names and symbols.
2714      */
2715     function baseGetAllKeys(object, keysFunc, symbolsFunc) {
2716       var result = keysFunc(object);
2717       return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
2718     }
2719
2720     /**
2721      * The base implementation of `_.gt` which doesn't coerce arguments to numbers.
2722      *
2723      * @private
2724      * @param {*} value The value to compare.
2725      * @param {*} other The other value to compare.
2726      * @returns {boolean} Returns `true` if `value` is greater than `other`,
2727      *  else `false`.
2728      */
2729     function baseGt(value, other) {
2730       return value > other;
2731     }
2732
2733     /**
2734      * The base implementation of `_.has` without support for deep paths.
2735      *
2736      * @private
2737      * @param {Object} [object] The object to query.
2738      * @param {Array|string} key The key to check.
2739      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2740      */
2741     function baseHas(object, key) {
2742       // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
2743       // that are composed entirely of index properties, return `false` for
2744       // `hasOwnProperty` checks of them.
2745       return object != null &&
2746         (hasOwnProperty.call(object, key) ||
2747           (typeof object == 'object' && key in object && getPrototype(object) === null));
2748     }
2749
2750     /**
2751      * The base implementation of `_.hasIn` without support for deep paths.
2752      *
2753      * @private
2754      * @param {Object} [object] The object to query.
2755      * @param {Array|string} key The key to check.
2756      * @returns {boolean} Returns `true` if `key` exists, else `false`.
2757      */
2758     function baseHasIn(object, key) {
2759       return object != null && key in Object(object);
2760     }
2761
2762     /**
2763      * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
2764      *
2765      * @private
2766      * @param {number} number The number to check.
2767      * @param {number} start The start of the range.
2768      * @param {number} end The end of the range.
2769      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
2770      */
2771     function baseInRange(number, start, end) {
2772       return number >= nativeMin(start, end) && number < nativeMax(start, end);
2773     }
2774
2775     /**
2776      * The base implementation of methods like `_.intersection`, without support
2777      * for iteratee shorthands, that accepts an array of arrays to inspect.
2778      *
2779      * @private
2780      * @param {Array} arrays The arrays to inspect.
2781      * @param {Function} [iteratee] The iteratee invoked per element.
2782      * @param {Function} [comparator] The comparator invoked per element.
2783      * @returns {Array} Returns the new array of shared values.
2784      */
2785     function baseIntersection(arrays, iteratee, comparator) {
2786       var includes = comparator ? arrayIncludesWith : arrayIncludes,
2787           length = arrays[0].length,
2788           othLength = arrays.length,
2789           othIndex = othLength,
2790           caches = Array(othLength),
2791           maxLength = Infinity,
2792           result = [];
2793
2794       while (othIndex--) {
2795         var array = arrays[othIndex];
2796         if (othIndex && iteratee) {
2797           array = arrayMap(array, baseUnary(iteratee));
2798         }
2799         maxLength = nativeMin(array.length, maxLength);
2800         caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
2801           ? new SetCache(othIndex && array)
2802           : undefined;
2803       }
2804       array = arrays[0];
2805
2806       var index = -1,
2807           seen = caches[0];
2808
2809       outer:
2810       while (++index < length && result.length < maxLength) {
2811         var value = array[index],
2812             computed = iteratee ? iteratee(value) : value;
2813
2814         value = (comparator || value !== 0) ? value : 0;
2815         if (!(seen
2816               ? cacheHas(seen, computed)
2817               : includes(result, computed, comparator)
2818             )) {
2819           othIndex = othLength;
2820           while (--othIndex) {
2821             var cache = caches[othIndex];
2822             if (!(cache
2823                   ? cacheHas(cache, computed)
2824                   : includes(arrays[othIndex], computed, comparator))
2825                 ) {
2826               continue outer;
2827             }
2828           }
2829           if (seen) {
2830             seen.push(computed);
2831           }
2832           result.push(value);
2833         }
2834       }
2835       return result;
2836     }
2837
2838     /**
2839      * The base implementation of `_.invert` and `_.invertBy` which inverts
2840      * `object` with values transformed by `iteratee` and set by `setter`.
2841      *
2842      * @private
2843      * @param {Object} object The object to iterate over.
2844      * @param {Function} setter The function to set `accumulator` values.
2845      * @param {Function} iteratee The iteratee to transform values.
2846      * @param {Object} accumulator The initial inverted object.
2847      * @returns {Function} Returns `accumulator`.
2848      */
2849     function baseInverter(object, setter, iteratee, accumulator) {
2850       baseForOwn(object, function(value, key, object) {
2851         setter(accumulator, iteratee(value), key, object);
2852       });
2853       return accumulator;
2854     }
2855
2856     /**
2857      * The base implementation of `_.invoke` without support for individual
2858      * method arguments.
2859      *
2860      * @private
2861      * @param {Object} object The object to query.
2862      * @param {Array|string} path The path of the method to invoke.
2863      * @param {Array} args The arguments to invoke the method with.
2864      * @returns {*} Returns the result of the invoked method.
2865      */
2866     function baseInvoke(object, path, args) {
2867       if (!isKey(path, object)) {
2868         path = castPath(path);
2869         object = parent(object, path);
2870         path = last(path);
2871       }
2872       var func = object == null ? object : object[toKey(path)];
2873       return func == null ? undefined : apply(func, object, args);
2874     }
2875
2876     /**
2877      * The base implementation of `_.isEqual` which supports partial comparisons
2878      * and tracks traversed objects.
2879      *
2880      * @private
2881      * @param {*} value The value to compare.
2882      * @param {*} other The other value to compare.
2883      * @param {Function} [customizer] The function to customize comparisons.
2884      * @param {boolean} [bitmask] The bitmask of comparison flags.
2885      *  The bitmask may be composed of the following flags:
2886      *     1 - Unordered comparison
2887      *     2 - Partial comparison
2888      * @param {Object} [stack] Tracks traversed `value` and `other` objects.
2889      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2890      */
2891     function baseIsEqual(value, other, customizer, bitmask, stack) {
2892       if (value === other) {
2893         return true;
2894       }
2895       if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
2896         return value !== value && other !== other;
2897       }
2898       return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
2899     }
2900
2901     /**
2902      * A specialized version of `baseIsEqual` for arrays and objects which performs
2903      * deep comparisons and tracks traversed objects enabling objects with circular
2904      * references to be compared.
2905      *
2906      * @private
2907      * @param {Object} object The object to compare.
2908      * @param {Object} other The other object to compare.
2909      * @param {Function} equalFunc The function to determine equivalents of values.
2910      * @param {Function} [customizer] The function to customize comparisons.
2911      * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual`
2912      *  for more details.
2913      * @param {Object} [stack] Tracks traversed `object` and `other` objects.
2914      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2915      */
2916     function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
2917       var objIsArr = isArray(object),
2918           othIsArr = isArray(other),
2919           objTag = arrayTag,
2920           othTag = arrayTag;
2921
2922       if (!objIsArr) {
2923         objTag = getTag(object);
2924         objTag = objTag == argsTag ? objectTag : objTag;
2925       }
2926       if (!othIsArr) {
2927         othTag = getTag(other);
2928         othTag = othTag == argsTag ? objectTag : othTag;
2929       }
2930       var objIsObj = objTag == objectTag && !isHostObject(object),
2931           othIsObj = othTag == objectTag && !isHostObject(other),
2932           isSameTag = objTag == othTag;
2933
2934       if (isSameTag && !objIsObj) {
2935         stack || (stack = new Stack);
2936         return (objIsArr || isTypedArray(object))
2937           ? equalArrays(object, other, equalFunc, customizer, bitmask, stack)
2938           : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack);
2939       }
2940       if (!(bitmask & PARTIAL_COMPARE_FLAG)) {
2941         var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2942             othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2943
2944         if (objIsWrapped || othIsWrapped) {
2945           var objUnwrapped = objIsWrapped ? object.value() : object,
2946               othUnwrapped = othIsWrapped ? other.value() : other;
2947
2948           stack || (stack = new Stack);
2949           return equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack);
2950         }
2951       }
2952       if (!isSameTag) {
2953         return false;
2954       }
2955       stack || (stack = new Stack);
2956       return equalObjects(object, other, equalFunc, customizer, bitmask, stack);
2957     }
2958
2959     /**
2960      * The base implementation of `_.isMatch` without support for iteratee shorthands.
2961      *
2962      * @private
2963      * @param {Object} object The object to inspect.
2964      * @param {Object} source The object of property values to match.
2965      * @param {Array} matchData The property names, values, and compare flags to match.
2966      * @param {Function} [customizer] The function to customize comparisons.
2967      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
2968      */
2969     function baseIsMatch(object, source, matchData, customizer) {
2970       var index = matchData.length,
2971           length = index,
2972           noCustomizer = !customizer;
2973
2974       if (object == null) {
2975         return !length;
2976       }
2977       object = Object(object);
2978       while (index--) {
2979         var data = matchData[index];
2980         if ((noCustomizer && data[2])
2981               ? data[1] !== object[data[0]]
2982               : !(data[0] in object)
2983             ) {
2984           return false;
2985         }
2986       }
2987       while (++index < length) {
2988         data = matchData[index];
2989         var key = data[0],
2990             objValue = object[key],
2991             srcValue = data[1];
2992
2993         if (noCustomizer && data[2]) {
2994           if (objValue === undefined && !(key in object)) {
2995             return false;
2996           }
2997         } else {
2998           var stack = new Stack;
2999           if (customizer) {
3000             var result = customizer(objValue, srcValue, key, object, source, stack);
3001           }
3002           if (!(result === undefined
3003                 ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
3004                 : result
3005               )) {
3006             return false;
3007           }
3008         }
3009       }
3010       return true;
3011     }
3012
3013     /**
3014      * The base implementation of `_.isNative` without bad shim checks.
3015      *
3016      * @private
3017      * @param {*} value The value to check.
3018      * @returns {boolean} Returns `true` if `value` is a native function,
3019      *  else `false`.
3020      */
3021     function baseIsNative(value) {
3022       if (!isObject(value) || isMasked(value)) {
3023         return false;
3024       }
3025       var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
3026       return pattern.test(toSource(value));
3027     }
3028
3029     /**
3030      * The base implementation of `_.iteratee`.
3031      *
3032      * @private
3033      * @param {*} [value=_.identity] The value to convert to an iteratee.
3034      * @returns {Function} Returns the iteratee.
3035      */
3036     function baseIteratee(value) {
3037       // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
3038       // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
3039       if (typeof value == 'function') {
3040         return value;
3041       }
3042       if (value == null) {
3043         return identity;
3044       }
3045       if (typeof value == 'object') {
3046         return isArray(value)
3047           ? baseMatchesProperty(value[0], value[1])
3048           : baseMatches(value);
3049       }
3050       return property(value);
3051     }
3052
3053     /**
3054      * The base implementation of `_.keys` which doesn't skip the constructor
3055      * property of prototypes or treat sparse arrays as dense.
3056      *
3057      * @private
3058      * @param {Object} object The object to query.
3059      * @returns {Array} Returns the array of property names.
3060      */
3061     function baseKeys(object) {
3062       return nativeKeys(Object(object));
3063     }
3064
3065     /**
3066      * The base implementation of `_.keysIn` which doesn't skip the constructor
3067      * property of prototypes or treat sparse arrays as dense.
3068      *
3069      * @private
3070      * @param {Object} object The object to query.
3071      * @returns {Array} Returns the array of property names.
3072      */
3073     function baseKeysIn(object) {
3074       object = object == null ? object : Object(object);
3075
3076       var result = [];
3077       for (var key in object) {
3078         result.push(key);
3079       }
3080       return result;
3081     }
3082
3083     // Fallback for IE < 9 with es6-shim.
3084     if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
3085       baseKeysIn = function(object) {
3086         return iteratorToArray(enumerate(object));
3087       };
3088     }
3089
3090     /**
3091      * The base implementation of `_.lt` which doesn't coerce arguments to numbers.
3092      *
3093      * @private
3094      * @param {*} value The value to compare.
3095      * @param {*} other The other value to compare.
3096      * @returns {boolean} Returns `true` if `value` is less than `other`,
3097      *  else `false`.
3098      */
3099     function baseLt(value, other) {
3100       return value < other;
3101     }
3102
3103     /**
3104      * The base implementation of `_.map` without support for iteratee shorthands.
3105      *
3106      * @private
3107      * @param {Array|Object} collection The collection to iterate over.
3108      * @param {Function} iteratee The function invoked per iteration.
3109      * @returns {Array} Returns the new mapped array.
3110      */
3111     function baseMap(collection, iteratee) {
3112       var index = -1,
3113           result = isArrayLike(collection) ? Array(collection.length) : [];
3114
3115       baseEach(collection, function(value, key, collection) {
3116         result[++index] = iteratee(value, key, collection);
3117       });
3118       return result;
3119     }
3120
3121     /**
3122      * The base implementation of `_.matches` which doesn't clone `source`.
3123      *
3124      * @private
3125      * @param {Object} source The object of property values to match.
3126      * @returns {Function} Returns the new spec function.
3127      */
3128     function baseMatches(source) {
3129       var matchData = getMatchData(source);
3130       if (matchData.length == 1 && matchData[0][2]) {
3131         return matchesStrictComparable(matchData[0][0], matchData[0][1]);
3132       }
3133       return function(object) {
3134         return object === source || baseIsMatch(object, source, matchData);
3135       };
3136     }
3137
3138     /**
3139      * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
3140      *
3141      * @private
3142      * @param {string} path The path of the property to get.
3143      * @param {*} srcValue The value to match.
3144      * @returns {Function} Returns the new spec function.
3145      */
3146     function baseMatchesProperty(path, srcValue) {
3147       if (isKey(path) && isStrictComparable(srcValue)) {
3148         return matchesStrictComparable(toKey(path), srcValue);
3149       }
3150       return function(object) {
3151         var objValue = get(object, path);
3152         return (objValue === undefined && objValue === srcValue)
3153           ? hasIn(object, path)
3154           : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
3155       };
3156     }
3157
3158     /**
3159      * The base implementation of `_.merge` without support for multiple sources.
3160      *
3161      * @private
3162      * @param {Object} object The destination object.
3163      * @param {Object} source The source object.
3164      * @param {number} srcIndex The index of `source`.
3165      * @param {Function} [customizer] The function to customize merged values.
3166      * @param {Object} [stack] Tracks traversed source values and their merged
3167      *  counterparts.
3168      */
3169     function baseMerge(object, source, srcIndex, customizer, stack) {
3170       if (object === source) {
3171         return;
3172       }
3173       if (!(isArray(source) || isTypedArray(source))) {
3174         var props = keysIn(source);
3175       }
3176       arrayEach(props || source, function(srcValue, key) {
3177         if (props) {
3178           key = srcValue;
3179           srcValue = source[key];
3180         }
3181         if (isObject(srcValue)) {
3182           stack || (stack = new Stack);
3183           baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
3184         }
3185         else {
3186           var newValue = customizer
3187             ? customizer(object[key], srcValue, (key + ''), object, source, stack)
3188             : undefined;
3189
3190           if (newValue === undefined) {
3191             newValue = srcValue;
3192           }
3193           assignMergeValue(object, key, newValue);
3194         }
3195       });
3196     }
3197
3198     /**
3199      * A specialized version of `baseMerge` for arrays and objects which performs
3200      * deep merges and tracks traversed objects enabling objects with circular
3201      * references to be merged.
3202      *
3203      * @private
3204      * @param {Object} object The destination object.
3205      * @param {Object} source The source object.
3206      * @param {string} key The key of the value to merge.
3207      * @param {number} srcIndex The index of `source`.
3208      * @param {Function} mergeFunc The function to merge values.
3209      * @param {Function} [customizer] The function to customize assigned values.
3210      * @param {Object} [stack] Tracks traversed source values and their merged
3211      *  counterparts.
3212      */
3213     function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
3214       var objValue = object[key],
3215           srcValue = source[key],
3216           stacked = stack.get(srcValue);
3217
3218       if (stacked) {
3219         assignMergeValue(object, key, stacked);
3220         return;
3221       }
3222       var newValue = customizer
3223         ? customizer(objValue, srcValue, (key + ''), object, source, stack)
3224         : undefined;
3225
3226       var isCommon = newValue === undefined;
3227
3228       if (isCommon) {
3229         newValue = srcValue;
3230         if (isArray(srcValue) || isTypedArray(srcValue)) {
3231           if (isArray(objValue)) {
3232             newValue = objValue;
3233           }
3234           else if (isArrayLikeObject(objValue)) {
3235             newValue = copyArray(objValue);
3236           }
3237           else {
3238             isCommon = false;
3239             newValue = baseClone(srcValue, true);
3240           }
3241         }
3242         else if (isPlainObject(srcValue) || isArguments(srcValue)) {
3243           if (isArguments(objValue)) {
3244             newValue = toPlainObject(objValue);
3245           }
3246           else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
3247             isCommon = false;
3248             newValue = baseClone(srcValue, true);
3249           }
3250           else {
3251             newValue = objValue;
3252           }
3253         }
3254         else {
3255           isCommon = false;
3256         }
3257       }
3258       stack.set(srcValue, newValue);
3259
3260       if (isCommon) {
3261         // Recursively merge objects and arrays (susceptible to call stack limits).
3262         mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
3263       }
3264       stack['delete'](srcValue);
3265       assignMergeValue(object, key, newValue);
3266     }
3267
3268     /**
3269      * The base implementation of `_.nth` which doesn't coerce `n` to an integer.
3270      *
3271      * @private
3272      * @param {Array} array The array to query.
3273      * @param {number} n The index of the element to return.
3274      * @returns {*} Returns the nth element of `array`.
3275      */
3276     function baseNth(array, n) {
3277       var length = array.length;
3278       if (!length) {
3279         return;
3280       }
3281       n += n < 0 ? length : 0;
3282       return isIndex(n, length) ? array[n] : undefined;
3283     }
3284
3285     /**
3286      * The base implementation of `_.orderBy` without param guards.
3287      *
3288      * @private
3289      * @param {Array|Object} collection The collection to iterate over.
3290      * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
3291      * @param {string[]} orders The sort orders of `iteratees`.
3292      * @returns {Array} Returns the new sorted array.
3293      */
3294     function baseOrderBy(collection, iteratees, orders) {
3295       var index = -1;
3296       iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
3297
3298       var result = baseMap(collection, function(value, key, collection) {
3299         var criteria = arrayMap(iteratees, function(iteratee) {
3300           return iteratee(value);
3301         });
3302         return { 'criteria': criteria, 'index': ++index, 'value': value };
3303       });
3304
3305       return baseSortBy(result, function(object, other) {
3306         return compareMultiple(object, other, orders);
3307       });
3308     }
3309
3310     /**
3311      * The base implementation of `_.pick` without support for individual
3312      * property identifiers.
3313      *
3314      * @private
3315      * @param {Object} object The source object.
3316      * @param {string[]} props The property identifiers to pick.
3317      * @returns {Object} Returns the new object.
3318      */
3319     function basePick(object, props) {
3320       object = Object(object);
3321       return arrayReduce(props, function(result, key) {
3322         if (key in object) {
3323           result[key] = object[key];
3324         }
3325         return result;
3326       }, {});
3327     }
3328
3329     /**
3330      * The base implementation of  `_.pickBy` without support for iteratee shorthands.
3331      *
3332      * @private
3333      * @param {Object} object The source object.
3334      * @param {Function} predicate The function invoked per property.
3335      * @returns {Object} Returns the new object.
3336      */
3337     function basePickBy(object, predicate) {
3338       var index = -1,
3339           props = getAllKeysIn(object),
3340           length = props.length,
3341           result = {};
3342
3343       while (++index < length) {
3344         var key = props[index],
3345             value = object[key];
3346
3347         if (predicate(value, key)) {
3348           result[key] = value;
3349         }
3350       }
3351       return result;
3352     }
3353
3354     /**
3355      * The base implementation of `_.property` without support for deep paths.
3356      *
3357      * @private
3358      * @param {string} key The key of the property to get.
3359      * @returns {Function} Returns the new accessor function.
3360      */
3361     function baseProperty(key) {
3362       return function(object) {
3363         return object == null ? undefined : object[key];
3364       };
3365     }
3366
3367     /**
3368      * A specialized version of `baseProperty` which supports deep paths.
3369      *
3370      * @private
3371      * @param {Array|string} path The path of the property to get.
3372      * @returns {Function} Returns the new accessor function.
3373      */
3374     function basePropertyDeep(path) {
3375       return function(object) {
3376         return baseGet(object, path);
3377       };
3378     }
3379
3380     /**
3381      * The base implementation of `_.pullAllBy` without support for iteratee
3382      * shorthands.
3383      *
3384      * @private
3385      * @param {Array} array The array to modify.
3386      * @param {Array} values The values to remove.
3387      * @param {Function} [iteratee] The iteratee invoked per element.
3388      * @param {Function} [comparator] The comparator invoked per element.
3389      * @returns {Array} Returns `array`.
3390      */
3391     function basePullAll(array, values, iteratee, comparator) {
3392       var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
3393           index = -1,
3394           length = values.length,
3395           seen = array;
3396
3397       if (array === values) {
3398         values = copyArray(values);
3399       }
3400       if (iteratee) {
3401         seen = arrayMap(array, baseUnary(iteratee));
3402       }
3403       while (++index < length) {
3404         var fromIndex = 0,
3405             value = values[index],
3406             computed = iteratee ? iteratee(value) : value;
3407
3408         while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
3409           if (seen !== array) {
3410             splice.call(seen, fromIndex, 1);
3411           }
3412           splice.call(array, fromIndex, 1);
3413         }
3414       }
3415       return array;
3416     }
3417
3418     /**
3419      * The base implementation of `_.pullAt` without support for individual
3420      * indexes or capturing the removed elements.
3421      *
3422      * @private
3423      * @param {Array} array The array to modify.
3424      * @param {number[]} indexes The indexes of elements to remove.
3425      * @returns {Array} Returns `array`.
3426      */
3427     function basePullAt(array, indexes) {
3428       var length = array ? indexes.length : 0,
3429           lastIndex = length - 1;
3430
3431       while (length--) {
3432         var index = indexes[length];
3433         if (length == lastIndex || index !== previous) {
3434           var previous = index;
3435           if (isIndex(index)) {
3436             splice.call(array, index, 1);
3437           }
3438           else if (!isKey(index, array)) {
3439             var path = castPath(index),
3440                 object = parent(array, path);
3441
3442             if (object != null) {
3443               delete object[toKey(last(path))];
3444             }
3445           }
3446           else {
3447             delete array[toKey(index)];
3448           }
3449         }
3450       }
3451       return array;
3452     }
3453
3454     /**
3455      * The base implementation of `_.random` without support for returning
3456      * floating-point numbers.
3457      *
3458      * @private
3459      * @param {number} lower The lower bound.
3460      * @param {number} upper The upper bound.
3461      * @returns {number} Returns the random number.
3462      */
3463     function baseRandom(lower, upper) {
3464       return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
3465     }
3466
3467     /**
3468      * The base implementation of `_.range` and `_.rangeRight` which doesn't
3469      * coerce arguments to numbers.
3470      *
3471      * @private
3472      * @param {number} start The start of the range.
3473      * @param {number} end The end of the range.
3474      * @param {number} step The value to increment or decrement by.
3475      * @param {boolean} [fromRight] Specify iterating from right to left.
3476      * @returns {Array} Returns the range of numbers.
3477      */
3478     function baseRange(start, end, step, fromRight) {
3479       var index = -1,
3480           length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
3481           result = Array(length);
3482
3483       while (length--) {
3484         result[fromRight ? length : ++index] = start;
3485         start += step;
3486       }
3487       return result;
3488     }
3489
3490     /**
3491      * The base implementation of `_.repeat` which doesn't coerce arguments.
3492      *
3493      * @private
3494      * @param {string} string The string to repeat.
3495      * @param {number} n The number of times to repeat the string.
3496      * @returns {string} Returns the repeated string.
3497      */
3498     function baseRepeat(string, n) {
3499       var result = '';
3500       if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
3501         return result;
3502       }
3503       // Leverage the exponentiation by squaring algorithm for a faster repeat.
3504       // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
3505       do {
3506         if (n % 2) {
3507           result += string;
3508         }
3509         n = nativeFloor(n / 2);
3510         if (n) {
3511           string += string;
3512         }
3513       } while (n);
3514
3515       return result;
3516     }
3517
3518     /**
3519      * The base implementation of `_.set`.
3520      *
3521      * @private
3522      * @param {Object} object The object to query.
3523      * @param {Array|string} path The path of the property to set.
3524      * @param {*} value The value to set.
3525      * @param {Function} [customizer] The function to customize path creation.
3526      * @returns {Object} Returns `object`.
3527      */
3528     function baseSet(object, path, value, customizer) {
3529       path = isKey(path, object) ? [path] : castPath(path);
3530
3531       var index = -1,
3532           length = path.length,
3533           lastIndex = length - 1,
3534           nested = object;
3535
3536       while (nested != null && ++index < length) {
3537         var key = toKey(path[index]);
3538         if (isObject(nested)) {
3539           var newValue = value;
3540           if (index != lastIndex) {
3541             var objValue = nested[key];
3542             newValue = customizer ? customizer(objValue, key, nested) : undefined;
3543             if (newValue === undefined) {
3544               newValue = objValue == null
3545                 ? (isIndex(path[index + 1]) ? [] : {})
3546                 : objValue;
3547             }
3548           }
3549           assignValue(nested, key, newValue);
3550         }
3551         nested = nested[key];
3552       }
3553       return object;
3554     }
3555
3556     /**
3557      * The base implementation of `setData` without support for hot loop detection.
3558      *
3559      * @private
3560      * @param {Function} func The function to associate metadata with.
3561      * @param {*} data The metadata.
3562      * @returns {Function} Returns `func`.
3563      */
3564     var baseSetData = !metaMap ? identity : function(func, data) {
3565       metaMap.set(func, data);
3566       return func;
3567     };
3568
3569     /**
3570      * The base implementation of `_.slice` without an iteratee call guard.
3571      *
3572      * @private
3573      * @param {Array} array The array to slice.
3574      * @param {number} [start=0] The start position.
3575      * @param {number} [end=array.length] The end position.
3576      * @returns {Array} Returns the slice of `array`.
3577      */
3578     function baseSlice(array, start, end) {
3579       var index = -1,
3580           length = array.length;
3581
3582       if (start < 0) {
3583         start = -start > length ? 0 : (length + start);
3584       }
3585       end = end > length ? length : end;
3586       if (end < 0) {
3587         end += length;
3588       }
3589       length = start > end ? 0 : ((end - start) >>> 0);
3590       start >>>= 0;
3591
3592       var result = Array(length);
3593       while (++index < length) {
3594         result[index] = array[index + start];
3595       }
3596       return result;
3597     }
3598
3599     /**
3600      * The base implementation of `_.some` without support for iteratee shorthands.
3601      *
3602      * @private
3603      * @param {Array|Object} collection The collection to iterate over.
3604      * @param {Function} predicate The function invoked per iteration.
3605      * @returns {boolean} Returns `true` if any element passes the predicate check,
3606      *  else `false`.
3607      */
3608     function baseSome(collection, predicate) {
3609       var result;
3610
3611       baseEach(collection, function(value, index, collection) {
3612         result = predicate(value, index, collection);
3613         return !result;
3614       });
3615       return !!result;
3616     }
3617
3618     /**
3619      * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
3620      * performs a binary search of `array` to determine the index at which `value`
3621      * should be inserted into `array` in order to maintain its sort order.
3622      *
3623      * @private
3624      * @param {Array} array The sorted array to inspect.
3625      * @param {*} value The value to evaluate.
3626      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3627      * @returns {number} Returns the index at which `value` should be inserted
3628      *  into `array`.
3629      */
3630     function baseSortedIndex(array, value, retHighest) {
3631       var low = 0,
3632           high = array ? array.length : low;
3633
3634       if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
3635         while (low < high) {
3636           var mid = (low + high) >>> 1,
3637               computed = array[mid];
3638
3639           if (computed !== null && !isSymbol(computed) &&
3640               (retHighest ? (computed <= value) : (computed < value))) {
3641             low = mid + 1;
3642           } else {
3643             high = mid;
3644           }
3645         }
3646         return high;
3647       }
3648       return baseSortedIndexBy(array, value, identity, retHighest);
3649     }
3650
3651     /**
3652      * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
3653      * which invokes `iteratee` for `value` and each element of `array` to compute
3654      * their sort ranking. The iteratee is invoked with one argument; (value).
3655      *
3656      * @private
3657      * @param {Array} array The sorted array to inspect.
3658      * @param {*} value The value to evaluate.
3659      * @param {Function} iteratee The iteratee invoked per element.
3660      * @param {boolean} [retHighest] Specify returning the highest qualified index.
3661      * @returns {number} Returns the index at which `value` should be inserted
3662      *  into `array`.
3663      */
3664     function baseSortedIndexBy(array, value, iteratee, retHighest) {
3665       value = iteratee(value);
3666
3667       var low = 0,
3668           high = array ? array.length : 0,
3669           valIsNaN = value !== value,
3670           valIsNull = value === null,
3671           valIsSymbol = isSymbol(value),
3672           valIsUndefined = value === undefined;
3673
3674       while (low < high) {
3675         var mid = nativeFloor((low + high) / 2),
3676             computed = iteratee(array[mid]),
3677             othIsDefined = computed !== undefined,
3678             othIsNull = computed === null,
3679             othIsReflexive = computed === computed,
3680             othIsSymbol = isSymbol(computed);
3681
3682         if (valIsNaN) {
3683           var setLow = retHighest || othIsReflexive;
3684         } else if (valIsUndefined) {
3685           setLow = othIsReflexive && (retHighest || othIsDefined);
3686         } else if (valIsNull) {
3687           setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
3688         } else if (valIsSymbol) {
3689           setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
3690         } else if (othIsNull || othIsSymbol) {
3691           setLow = false;
3692         } else {
3693           setLow = retHighest ? (computed <= value) : (computed < value);
3694         }
3695         if (setLow) {
3696           low = mid + 1;
3697         } else {
3698           high = mid;
3699         }
3700       }
3701       return nativeMin(high, MAX_ARRAY_INDEX);
3702     }
3703
3704     /**
3705      * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
3706      * support for iteratee shorthands.
3707      *
3708      * @private
3709      * @param {Array} array The array to inspect.
3710      * @param {Function} [iteratee] The iteratee invoked per element.
3711      * @returns {Array} Returns the new duplicate free array.
3712      */
3713     function baseSortedUniq(array, iteratee) {
3714       var index = -1,
3715           length = array.length,
3716           resIndex = 0,
3717           result = [];
3718
3719       while (++index < length) {
3720         var value = array[index],
3721             computed = iteratee ? iteratee(value) : value;
3722
3723         if (!index || !eq(computed, seen)) {
3724           var seen = computed;
3725           result[resIndex++] = value === 0 ? 0 : value;
3726         }
3727       }
3728       return result;
3729     }
3730
3731     /**
3732      * The base implementation of `_.toNumber` which doesn't ensure correct
3733      * conversions of binary, hexadecimal, or octal string values.
3734      *
3735      * @private
3736      * @param {*} value The value to process.
3737      * @returns {number} Returns the number.
3738      */
3739     function baseToNumber(value) {
3740       if (typeof value == 'number') {
3741         return value;
3742       }
3743       if (isSymbol(value)) {
3744         return NAN;
3745       }
3746       return +value;
3747     }
3748
3749     /**
3750      * The base implementation of `_.toString` which doesn't convert nullish
3751      * values to empty strings.
3752      *
3753      * @private
3754      * @param {*} value The value to process.
3755      * @returns {string} Returns the string.
3756      */
3757     function baseToString(value) {
3758       // Exit early for strings to avoid a performance hit in some environments.
3759       if (typeof value == 'string') {
3760         return value;
3761       }
3762       if (isSymbol(value)) {
3763         return symbolToString ? symbolToString.call(value) : '';
3764       }
3765       var result = (value + '');
3766       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
3767     }
3768
3769     /**
3770      * The base implementation of `_.uniqBy` without support for iteratee shorthands.
3771      *
3772      * @private
3773      * @param {Array} array The array to inspect.
3774      * @param {Function} [iteratee] The iteratee invoked per element.
3775      * @param {Function} [comparator] The comparator invoked per element.
3776      * @returns {Array} Returns the new duplicate free array.
3777      */
3778     function baseUniq(array, iteratee, comparator) {
3779       var index = -1,
3780           includes = arrayIncludes,
3781           length = array.length,
3782           isCommon = true,
3783           result = [],
3784           seen = result;
3785
3786       if (comparator) {
3787         isCommon = false;
3788         includes = arrayIncludesWith;
3789       }
3790       else if (length >= LARGE_ARRAY_SIZE) {
3791         var set = iteratee ? null : createSet(array);
3792         if (set) {
3793           return setToArray(set);
3794         }
3795         isCommon = false;
3796         includes = cacheHas;
3797         seen = new SetCache;
3798       }
3799       else {
3800         seen = iteratee ? [] : result;
3801       }
3802       outer:
3803       while (++index < length) {
3804         var value = array[index],
3805             computed = iteratee ? iteratee(value) : value;
3806
3807         value = (comparator || value !== 0) ? value : 0;
3808         if (isCommon && computed === computed) {
3809           var seenIndex = seen.length;
3810           while (seenIndex--) {
3811             if (seen[seenIndex] === computed) {
3812               continue outer;
3813             }
3814           }
3815           if (iteratee) {
3816             seen.push(computed);
3817           }
3818           result.push(value);
3819         }
3820         else if (!includes(seen, computed, comparator)) {
3821           if (seen !== result) {
3822             seen.push(computed);
3823           }
3824           result.push(value);
3825         }
3826       }
3827       return result;
3828     }
3829
3830     /**
3831      * The base implementation of `_.unset`.
3832      *
3833      * @private
3834      * @param {Object} object The object to modify.
3835      * @param {Array|string} path The path of the property to unset.
3836      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
3837      */
3838     function baseUnset(object, path) {
3839       path = isKey(path, object) ? [path] : castPath(path);
3840       object = parent(object, path);
3841
3842       var key = toKey(last(path));
3843       return !(object != null && baseHas(object, key)) || delete object[key];
3844     }
3845
3846     /**
3847      * The base implementation of `_.update`.
3848      *
3849      * @private
3850      * @param {Object} object The object to query.
3851      * @param {Array|string} path The path of the property to update.
3852      * @param {Function} updater The function to produce the updated value.
3853      * @param {Function} [customizer] The function to customize path creation.
3854      * @returns {Object} Returns `object`.
3855      */
3856     function baseUpdate(object, path, updater, customizer) {
3857       return baseSet(object, path, updater(baseGet(object, path)), customizer);
3858     }
3859
3860     /**
3861      * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
3862      * without support for iteratee shorthands.
3863      *
3864      * @private
3865      * @param {Array} array The array to query.
3866      * @param {Function} predicate The function invoked per iteration.
3867      * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
3868      * @param {boolean} [fromRight] Specify iterating from right to left.
3869      * @returns {Array} Returns the slice of `array`.
3870      */
3871     function baseWhile(array, predicate, isDrop, fromRight) {
3872       var length = array.length,
3873           index = fromRight ? length : -1;
3874
3875       while ((fromRight ? index-- : ++index < length) &&
3876         predicate(array[index], index, array)) {}
3877
3878       return isDrop
3879         ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
3880         : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
3881     }
3882
3883     /**
3884      * The base implementation of `wrapperValue` which returns the result of
3885      * performing a sequence of actions on the unwrapped `value`, where each
3886      * successive action is supplied the return value of the previous.
3887      *
3888      * @private
3889      * @param {*} value The unwrapped value.
3890      * @param {Array} actions Actions to perform to resolve the unwrapped value.
3891      * @returns {*} Returns the resolved value.
3892      */
3893     function baseWrapperValue(value, actions) {
3894       var result = value;
3895       if (result instanceof LazyWrapper) {
3896         result = result.value();
3897       }
3898       return arrayReduce(actions, function(result, action) {
3899         return action.func.apply(action.thisArg, arrayPush([result], action.args));
3900       }, result);
3901     }
3902
3903     /**
3904      * The base implementation of methods like `_.xor`, without support for
3905      * iteratee shorthands, that accepts an array of arrays to inspect.
3906      *
3907      * @private
3908      * @param {Array} arrays The arrays to inspect.
3909      * @param {Function} [iteratee] The iteratee invoked per element.
3910      * @param {Function} [comparator] The comparator invoked per element.
3911      * @returns {Array} Returns the new array of values.
3912      */
3913     function baseXor(arrays, iteratee, comparator) {
3914       var index = -1,
3915           length = arrays.length;
3916
3917       while (++index < length) {
3918         var result = result
3919           ? arrayPush(
3920               baseDifference(result, arrays[index], iteratee, comparator),
3921               baseDifference(arrays[index], result, iteratee, comparator)
3922             )
3923           : arrays[index];
3924       }
3925       return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
3926     }
3927
3928     /**
3929      * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
3930      *
3931      * @private
3932      * @param {Array} props The property identifiers.
3933      * @param {Array} values The property values.
3934      * @param {Function} assignFunc The function to assign values.
3935      * @returns {Object} Returns the new object.
3936      */
3937     function baseZipObject(props, values, assignFunc) {
3938       var index = -1,
3939           length = props.length,
3940           valsLength = values.length,
3941           result = {};
3942
3943       while (++index < length) {
3944         var value = index < valsLength ? values[index] : undefined;
3945         assignFunc(result, props[index], value);
3946       }
3947       return result;
3948     }
3949
3950     /**
3951      * Casts `value` to an empty array if it's not an array like object.
3952      *
3953      * @private
3954      * @param {*} value The value to inspect.
3955      * @returns {Array|Object} Returns the cast array-like object.
3956      */
3957     function castArrayLikeObject(value) {
3958       return isArrayLikeObject(value) ? value : [];
3959     }
3960
3961     /**
3962      * Casts `value` to `identity` if it's not a function.
3963      *
3964      * @private
3965      * @param {*} value The value to inspect.
3966      * @returns {Function} Returns cast function.
3967      */
3968     function castFunction(value) {
3969       return typeof value == 'function' ? value : identity;
3970     }
3971
3972     /**
3973      * Casts `value` to a path array if it's not one.
3974      *
3975      * @private
3976      * @param {*} value The value to inspect.
3977      * @returns {Array} Returns the cast property path array.
3978      */
3979     function castPath(value) {
3980       return isArray(value) ? value : stringToPath(value);
3981     }
3982
3983     /**
3984      * Casts `array` to a slice if it's needed.
3985      *
3986      * @private
3987      * @param {Array} array The array to inspect.
3988      * @param {number} start The start position.
3989      * @param {number} [end=array.length] The end position.
3990      * @returns {Array} Returns the cast slice.
3991      */
3992     function castSlice(array, start, end) {
3993       var length = array.length;
3994       end = end === undefined ? length : end;
3995       return (!start && end >= length) ? array : baseSlice(array, start, end);
3996     }
3997
3998     /**
3999      * Creates a clone of  `buffer`.
4000      *
4001      * @private
4002      * @param {Buffer} buffer The buffer to clone.
4003      * @param {boolean} [isDeep] Specify a deep clone.
4004      * @returns {Buffer} Returns the cloned buffer.
4005      */
4006     function cloneBuffer(buffer, isDeep) {
4007       if (isDeep) {
4008         return buffer.slice();
4009       }
4010       var result = new buffer.constructor(buffer.length);
4011       buffer.copy(result);
4012       return result;
4013     }
4014
4015     /**
4016      * Creates a clone of `arrayBuffer`.
4017      *
4018      * @private
4019      * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
4020      * @returns {ArrayBuffer} Returns the cloned array buffer.
4021      */
4022     function cloneArrayBuffer(arrayBuffer) {
4023       var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
4024       new Uint8Array(result).set(new Uint8Array(arrayBuffer));
4025       return result;
4026     }
4027
4028     /**
4029      * Creates a clone of `dataView`.
4030      *
4031      * @private
4032      * @param {Object} dataView The data view to clone.
4033      * @param {boolean} [isDeep] Specify a deep clone.
4034      * @returns {Object} Returns the cloned data view.
4035      */
4036     function cloneDataView(dataView, isDeep) {
4037       var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
4038       return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
4039     }
4040
4041     /**
4042      * Creates a clone of `map`.
4043      *
4044      * @private
4045      * @param {Object} map The map to clone.
4046      * @param {Function} cloneFunc The function to clone values.
4047      * @param {boolean} [isDeep] Specify a deep clone.
4048      * @returns {Object} Returns the cloned map.
4049      */
4050     function cloneMap(map, isDeep, cloneFunc) {
4051       var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);
4052       return arrayReduce(array, addMapEntry, new map.constructor);
4053     }
4054
4055     /**
4056      * Creates a clone of `regexp`.
4057      *
4058      * @private
4059      * @param {Object} regexp The regexp to clone.
4060      * @returns {Object} Returns the cloned regexp.
4061      */
4062     function cloneRegExp(regexp) {
4063       var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
4064       result.lastIndex = regexp.lastIndex;
4065       return result;
4066     }
4067
4068     /**
4069      * Creates a clone of `set`.
4070      *
4071      * @private
4072      * @param {Object} set The set to clone.
4073      * @param {Function} cloneFunc The function to clone values.
4074      * @param {boolean} [isDeep] Specify a deep clone.
4075      * @returns {Object} Returns the cloned set.
4076      */
4077     function cloneSet(set, isDeep, cloneFunc) {
4078       var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);
4079       return arrayReduce(array, addSetEntry, new set.constructor);
4080     }
4081
4082     /**
4083      * Creates a clone of the `symbol` object.
4084      *
4085      * @private
4086      * @param {Object} symbol The symbol object to clone.
4087      * @returns {Object} Returns the cloned symbol object.
4088      */
4089     function cloneSymbol(symbol) {
4090       return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
4091     }
4092
4093     /**
4094      * Creates a clone of `typedArray`.
4095      *
4096      * @private
4097      * @param {Object} typedArray The typed array to clone.
4098      * @param {boolean} [isDeep] Specify a deep clone.
4099      * @returns {Object} Returns the cloned typed array.
4100      */
4101     function cloneTypedArray(typedArray, isDeep) {
4102       var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
4103       return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
4104     }
4105
4106     /**
4107      * Compares values to sort them in ascending order.
4108      *
4109      * @private
4110      * @param {*} value The value to compare.
4111      * @param {*} other The other value to compare.
4112      * @returns {number} Returns the sort order indicator for `value`.
4113      */
4114     function compareAscending(value, other) {
4115       if (value !== other) {
4116         var valIsDefined = value !== undefined,
4117             valIsNull = value === null,
4118             valIsReflexive = value === value,
4119             valIsSymbol = isSymbol(value);
4120
4121         var othIsDefined = other !== undefined,
4122             othIsNull = other === null,
4123             othIsReflexive = other === other,
4124             othIsSymbol = isSymbol(other);
4125
4126         if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
4127             (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
4128             (valIsNull && othIsDefined && othIsReflexive) ||
4129             (!valIsDefined && othIsReflexive) ||
4130             !valIsReflexive) {
4131           return 1;
4132         }
4133         if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
4134             (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
4135             (othIsNull && valIsDefined && valIsReflexive) ||
4136             (!othIsDefined && valIsReflexive) ||
4137             !othIsReflexive) {
4138           return -1;
4139         }
4140       }
4141       return 0;
4142     }
4143
4144     /**
4145      * Used by `_.orderBy` to compare multiple properties of a value to another
4146      * and stable sort them.
4147      *
4148      * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
4149      * specify an order of "desc" for descending or "asc" for ascending sort order
4150      * of corresponding values.
4151      *
4152      * @private
4153      * @param {Object} object The object to compare.
4154      * @param {Object} other The other object to compare.
4155      * @param {boolean[]|string[]} orders The order to sort by for each property.
4156      * @returns {number} Returns the sort order indicator for `object`.
4157      */
4158     function compareMultiple(object, other, orders) {
4159       var index = -1,
4160           objCriteria = object.criteria,
4161           othCriteria = other.criteria,
4162           length = objCriteria.length,
4163           ordersLength = orders.length;
4164
4165       while (++index < length) {
4166         var result = compareAscending(objCriteria[index], othCriteria[index]);
4167         if (result) {
4168           if (index >= ordersLength) {
4169             return result;
4170           }
4171           var order = orders[index];
4172           return result * (order == 'desc' ? -1 : 1);
4173         }
4174       }
4175       // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
4176       // that causes it, under certain circumstances, to provide the same value for
4177       // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
4178       // for more details.
4179       //
4180       // This also ensures a stable sort in V8 and other engines.
4181       // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
4182       return object.index - other.index;
4183     }
4184
4185     /**
4186      * Creates an array that is the composition of partially applied arguments,
4187      * placeholders, and provided arguments into a single array of arguments.
4188      *
4189      * @private
4190      * @param {Array} args The provided arguments.
4191      * @param {Array} partials The arguments to prepend to those provided.
4192      * @param {Array} holders The `partials` placeholder indexes.
4193      * @params {boolean} [isCurried] Specify composing for a curried function.
4194      * @returns {Array} Returns the new array of composed arguments.
4195      */
4196     function composeArgs(args, partials, holders, isCurried) {
4197       var argsIndex = -1,
4198           argsLength = args.length,
4199           holdersLength = holders.length,
4200           leftIndex = -1,
4201           leftLength = partials.length,
4202           rangeLength = nativeMax(argsLength - holdersLength, 0),
4203           result = Array(leftLength + rangeLength),
4204           isUncurried = !isCurried;
4205
4206       while (++leftIndex < leftLength) {
4207         result[leftIndex] = partials[leftIndex];
4208       }
4209       while (++argsIndex < holdersLength) {
4210         if (isUncurried || argsIndex < argsLength) {
4211           result[holders[argsIndex]] = args[argsIndex];
4212         }
4213       }
4214       while (rangeLength--) {
4215         result[leftIndex++] = args[argsIndex++];
4216       }
4217       return result;
4218     }
4219
4220     /**
4221      * This function is like `composeArgs` except that the arguments composition
4222      * is tailored for `_.partialRight`.
4223      *
4224      * @private
4225      * @param {Array} args The provided arguments.
4226      * @param {Array} partials The arguments to append to those provided.
4227      * @param {Array} holders The `partials` placeholder indexes.
4228      * @params {boolean} [isCurried] Specify composing for a curried function.
4229      * @returns {Array} Returns the new array of composed arguments.
4230      */
4231     function composeArgsRight(args, partials, holders, isCurried) {
4232       var argsIndex = -1,
4233           argsLength = args.length,
4234           holdersIndex = -1,
4235           holdersLength = holders.length,
4236           rightIndex = -1,
4237           rightLength = partials.length,
4238           rangeLength = nativeMax(argsLength - holdersLength, 0),
4239           result = Array(rangeLength + rightLength),
4240           isUncurried = !isCurried;
4241
4242       while (++argsIndex < rangeLength) {
4243         result[argsIndex] = args[argsIndex];
4244       }
4245       var offset = argsIndex;
4246       while (++rightIndex < rightLength) {
4247         result[offset + rightIndex] = partials[rightIndex];
4248       }
4249       while (++holdersIndex < holdersLength) {
4250         if (isUncurried || argsIndex < argsLength) {
4251           result[offset + holders[holdersIndex]] = args[argsIndex++];
4252         }
4253       }
4254       return result;
4255     }
4256
4257     /**
4258      * Copies the values of `source` to `array`.
4259      *
4260      * @private
4261      * @param {Array} source The array to copy values from.
4262      * @param {Array} [array=[]] The array to copy values to.
4263      * @returns {Array} Returns `array`.
4264      */
4265     function copyArray(source, array) {
4266       var index = -1,
4267           length = source.length;
4268
4269       array || (array = Array(length));
4270       while (++index < length) {
4271         array[index] = source[index];
4272       }
4273       return array;
4274     }
4275
4276     /**
4277      * Copies properties of `source` to `object`.
4278      *
4279      * @private
4280      * @param {Object} source The object to copy properties from.
4281      * @param {Array} props The property identifiers to copy.
4282      * @param {Object} [object={}] The object to copy properties to.
4283      * @param {Function} [customizer] The function to customize copied values.
4284      * @returns {Object} Returns `object`.
4285      */
4286     function copyObject(source, props, object, customizer) {
4287       object || (object = {});
4288
4289       var index = -1,
4290           length = props.length;
4291
4292       while (++index < length) {
4293         var key = props[index];
4294
4295         var newValue = customizer
4296           ? customizer(object[key], source[key], key, object, source)
4297           : source[key];
4298
4299         assignValue(object, key, newValue);
4300       }
4301       return object;
4302     }
4303
4304     /**
4305      * Copies own symbol properties of `source` to `object`.
4306      *
4307      * @private
4308      * @param {Object} source The object to copy symbols from.
4309      * @param {Object} [object={}] The object to copy symbols to.
4310      * @returns {Object} Returns `object`.
4311      */
4312     function copySymbols(source, object) {
4313       return copyObject(source, getSymbols(source), object);
4314     }
4315
4316     /**
4317      * Creates a function like `_.groupBy`.
4318      *
4319      * @private
4320      * @param {Function} setter The function to set accumulator values.
4321      * @param {Function} [initializer] The accumulator object initializer.
4322      * @returns {Function} Returns the new aggregator function.
4323      */
4324     function createAggregator(setter, initializer) {
4325       return function(collection, iteratee) {
4326         var func = isArray(collection) ? arrayAggregator : baseAggregator,
4327             accumulator = initializer ? initializer() : {};
4328
4329         return func(collection, setter, getIteratee(iteratee), accumulator);
4330       };
4331     }
4332
4333     /**
4334      * Creates a function like `_.assign`.
4335      *
4336      * @private
4337      * @param {Function} assigner The function to assign values.
4338      * @returns {Function} Returns the new assigner function.
4339      */
4340     function createAssigner(assigner) {
4341       return rest(function(object, sources) {
4342         var index = -1,
4343             length = sources.length,
4344             customizer = length > 1 ? sources[length - 1] : undefined,
4345             guard = length > 2 ? sources[2] : undefined;
4346
4347         customizer = (assigner.length > 3 && typeof customizer == 'function')
4348           ? (length--, customizer)
4349           : undefined;
4350
4351         if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4352           customizer = length < 3 ? undefined : customizer;
4353           length = 1;
4354         }
4355         object = Object(object);
4356         while (++index < length) {
4357           var source = sources[index];
4358           if (source) {
4359             assigner(object, source, index, customizer);
4360           }
4361         }
4362         return object;
4363       });
4364     }
4365
4366     /**
4367      * Creates a `baseEach` or `baseEachRight` function.
4368      *
4369      * @private
4370      * @param {Function} eachFunc The function to iterate over a collection.
4371      * @param {boolean} [fromRight] Specify iterating from right to left.
4372      * @returns {Function} Returns the new base function.
4373      */
4374     function createBaseEach(eachFunc, fromRight) {
4375       return function(collection, iteratee) {
4376         if (collection == null) {
4377           return collection;
4378         }
4379         if (!isArrayLike(collection)) {
4380           return eachFunc(collection, iteratee);
4381         }
4382         var length = collection.length,
4383             index = fromRight ? length : -1,
4384             iterable = Object(collection);
4385
4386         while ((fromRight ? index-- : ++index < length)) {
4387           if (iteratee(iterable[index], index, iterable) === false) {
4388             break;
4389           }
4390         }
4391         return collection;
4392       };
4393     }
4394
4395     /**
4396      * Creates a base function for methods like `_.forIn` and `_.forOwn`.
4397      *
4398      * @private
4399      * @param {boolean} [fromRight] Specify iterating from right to left.
4400      * @returns {Function} Returns the new base function.
4401      */
4402     function createBaseFor(fromRight) {
4403       return function(object, iteratee, keysFunc) {
4404         var index = -1,
4405             iterable = Object(object),
4406             props = keysFunc(object),
4407             length = props.length;
4408
4409         while (length--) {
4410           var key = props[fromRight ? length : ++index];
4411           if (iteratee(iterable[key], key, iterable) === false) {
4412             break;
4413           }
4414         }
4415         return object;
4416       };
4417     }
4418
4419     /**
4420      * Creates a function that wraps `func` to invoke it with the optional `this`
4421      * binding of `thisArg`.
4422      *
4423      * @private
4424      * @param {Function} func The function to wrap.
4425      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
4426      *  for more details.
4427      * @param {*} [thisArg] The `this` binding of `func`.
4428      * @returns {Function} Returns the new wrapped function.
4429      */
4430     function createBaseWrapper(func, bitmask, thisArg) {
4431       var isBind = bitmask & BIND_FLAG,
4432           Ctor = createCtorWrapper(func);
4433
4434       function wrapper() {
4435         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4436         return fn.apply(isBind ? thisArg : this, arguments);
4437       }
4438       return wrapper;
4439     }
4440
4441     /**
4442      * Creates a function like `_.lowerFirst`.
4443      *
4444      * @private
4445      * @param {string} methodName The name of the `String` case method to use.
4446      * @returns {Function} Returns the new case function.
4447      */
4448     function createCaseFirst(methodName) {
4449       return function(string) {
4450         string = toString(string);
4451
4452         var strSymbols = reHasComplexSymbol.test(string)
4453           ? stringToArray(string)
4454           : undefined;
4455
4456         var chr = strSymbols
4457           ? strSymbols[0]
4458           : string.charAt(0);
4459
4460         var trailing = strSymbols
4461           ? castSlice(strSymbols, 1).join('')
4462           : string.slice(1);
4463
4464         return chr[methodName]() + trailing;
4465       };
4466     }
4467
4468     /**
4469      * Creates a function like `_.camelCase`.
4470      *
4471      * @private
4472      * @param {Function} callback The function to combine each word.
4473      * @returns {Function} Returns the new compounder function.
4474      */
4475     function createCompounder(callback) {
4476       return function(string) {
4477         return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
4478       };
4479     }
4480
4481     /**
4482      * Creates a function that produces an instance of `Ctor` regardless of
4483      * whether it was invoked as part of a `new` expression or by `call` or `apply`.
4484      *
4485      * @private
4486      * @param {Function} Ctor The constructor to wrap.
4487      * @returns {Function} Returns the new wrapped function.
4488      */
4489     function createCtorWrapper(Ctor) {
4490       return function() {
4491         // Use a `switch` statement to work with class constructors. See
4492         // http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
4493         // for more details.
4494         var args = arguments;
4495         switch (args.length) {
4496           case 0: return new Ctor;
4497           case 1: return new Ctor(args[0]);
4498           case 2: return new Ctor(args[0], args[1]);
4499           case 3: return new Ctor(args[0], args[1], args[2]);
4500           case 4: return new Ctor(args[0], args[1], args[2], args[3]);
4501           case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
4502           case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
4503           case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
4504         }
4505         var thisBinding = baseCreate(Ctor.prototype),
4506             result = Ctor.apply(thisBinding, args);
4507
4508         // Mimic the constructor's `return` behavior.
4509         // See https://es5.github.io/#x13.2.2 for more details.
4510         return isObject(result) ? result : thisBinding;
4511       };
4512     }
4513
4514     /**
4515      * Creates a function that wraps `func` to enable currying.
4516      *
4517      * @private
4518      * @param {Function} func The function to wrap.
4519      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
4520      *  for more details.
4521      * @param {number} arity The arity of `func`.
4522      * @returns {Function} Returns the new wrapped function.
4523      */
4524     function createCurryWrapper(func, bitmask, arity) {
4525       var Ctor = createCtorWrapper(func);
4526
4527       function wrapper() {
4528         var length = arguments.length,
4529             args = Array(length),
4530             index = length,
4531             placeholder = getHolder(wrapper);
4532
4533         while (index--) {
4534           args[index] = arguments[index];
4535         }
4536         var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
4537           ? []
4538           : replaceHolders(args, placeholder);
4539
4540         length -= holders.length;
4541         if (length < arity) {
4542           return createRecurryWrapper(
4543             func, bitmask, createHybridWrapper, wrapper.placeholder, undefined,
4544             args, holders, undefined, undefined, arity - length);
4545         }
4546         var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4547         return apply(fn, this, args);
4548       }
4549       return wrapper;
4550     }
4551
4552     /**
4553      * Creates a `_.find` or `_.findLast` function.
4554      *
4555      * @private
4556      * @param {Function} findIndexFunc The function to find the collection index.
4557      * @returns {Function} Returns the new find function.
4558      */
4559     function createFind(findIndexFunc) {
4560       return function(collection, predicate, fromIndex) {
4561         var iterable = Object(collection);
4562         predicate = getIteratee(predicate, 3);
4563         if (!isArrayLike(collection)) {
4564           var props = keys(collection);
4565         }
4566         var index = findIndexFunc(props || collection, function(value, key) {
4567           if (props) {
4568             key = value;
4569             value = iterable[key];
4570           }
4571           return predicate(value, key, iterable);
4572         }, fromIndex);
4573         return index > -1 ? collection[props ? props[index] : index] : undefined;
4574       };
4575     }
4576
4577     /**
4578      * Creates a `_.flow` or `_.flowRight` function.
4579      *
4580      * @private
4581      * @param {boolean} [fromRight] Specify iterating from right to left.
4582      * @returns {Function} Returns the new flow function.
4583      */
4584     function createFlow(fromRight) {
4585       return rest(function(funcs) {
4586         funcs = baseFlatten(funcs, 1);
4587
4588         var length = funcs.length,
4589             index = length,
4590             prereq = LodashWrapper.prototype.thru;
4591
4592         if (fromRight) {
4593           funcs.reverse();
4594         }
4595         while (index--) {
4596           var func = funcs[index];
4597           if (typeof func != 'function') {
4598             throw new TypeError(FUNC_ERROR_TEXT);
4599           }
4600           if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
4601             var wrapper = new LodashWrapper([], true);
4602           }
4603         }
4604         index = wrapper ? index : length;
4605         while (++index < length) {
4606           func = funcs[index];
4607
4608           var funcName = getFuncName(func),
4609               data = funcName == 'wrapper' ? getData(func) : undefined;
4610
4611           if (data && isLaziable(data[0]) &&
4612                 data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) &&
4613                 !data[4].length && data[9] == 1
4614               ) {
4615             wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
4616           } else {
4617             wrapper = (func.length == 1 && isLaziable(func))
4618               ? wrapper[funcName]()
4619               : wrapper.thru(func);
4620           }
4621         }
4622         return function() {
4623           var args = arguments,
4624               value = args[0];
4625
4626           if (wrapper && args.length == 1 &&
4627               isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
4628             return wrapper.plant(value).value();
4629           }
4630           var index = 0,
4631               result = length ? funcs[index].apply(this, args) : value;
4632
4633           while (++index < length) {
4634             result = funcs[index].call(this, result);
4635           }
4636           return result;
4637         };
4638       });
4639     }
4640
4641     /**
4642      * Creates a function that wraps `func` to invoke it with optional `this`
4643      * binding of `thisArg`, partial application, and currying.
4644      *
4645      * @private
4646      * @param {Function|string} func The function or method name to wrap.
4647      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
4648      *  for more details.
4649      * @param {*} [thisArg] The `this` binding of `func`.
4650      * @param {Array} [partials] The arguments to prepend to those provided to
4651      *  the new function.
4652      * @param {Array} [holders] The `partials` placeholder indexes.
4653      * @param {Array} [partialsRight] The arguments to append to those provided
4654      *  to the new function.
4655      * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
4656      * @param {Array} [argPos] The argument positions of the new function.
4657      * @param {number} [ary] The arity cap of `func`.
4658      * @param {number} [arity] The arity of `func`.
4659      * @returns {Function} Returns the new wrapped function.
4660      */
4661     function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
4662       var isAry = bitmask & ARY_FLAG,
4663           isBind = bitmask & BIND_FLAG,
4664           isBindKey = bitmask & BIND_KEY_FLAG,
4665           isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG),
4666           isFlip = bitmask & FLIP_FLAG,
4667           Ctor = isBindKey ? undefined : createCtorWrapper(func);
4668
4669       function wrapper() {
4670         var length = arguments.length,
4671             args = Array(length),
4672             index = length;
4673
4674         while (index--) {
4675           args[index] = arguments[index];
4676         }
4677         if (isCurried) {
4678           var placeholder = getHolder(wrapper),
4679               holdersCount = countHolders(args, placeholder);
4680         }
4681         if (partials) {
4682           args = composeArgs(args, partials, holders, isCurried);
4683         }
4684         if (partialsRight) {
4685           args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
4686         }
4687         length -= holdersCount;
4688         if (isCurried && length < arity) {
4689           var newHolders = replaceHolders(args, placeholder);
4690           return createRecurryWrapper(
4691             func, bitmask, createHybridWrapper, wrapper.placeholder, thisArg,
4692             args, newHolders, argPos, ary, arity - length
4693           );
4694         }
4695         var thisBinding = isBind ? thisArg : this,
4696             fn = isBindKey ? thisBinding[func] : func;
4697
4698         length = args.length;
4699         if (argPos) {
4700           args = reorder(args, argPos);
4701         } else if (isFlip && length > 1) {
4702           args.reverse();
4703         }
4704         if (isAry && ary < length) {
4705           args.length = ary;
4706         }
4707         if (this && this !== root && this instanceof wrapper) {
4708           fn = Ctor || createCtorWrapper(fn);
4709         }
4710         return fn.apply(thisBinding, args);
4711       }
4712       return wrapper;
4713     }
4714
4715     /**
4716      * Creates a function like `_.invertBy`.
4717      *
4718      * @private
4719      * @param {Function} setter The function to set accumulator values.
4720      * @param {Function} toIteratee The function to resolve iteratees.
4721      * @returns {Function} Returns the new inverter function.
4722      */
4723     function createInverter(setter, toIteratee) {
4724       return function(object, iteratee) {
4725         return baseInverter(object, setter, toIteratee(iteratee), {});
4726       };
4727     }
4728
4729     /**
4730      * Creates a function that performs a mathematical operation on two values.
4731      *
4732      * @private
4733      * @param {Function} operator The function to perform the operation.
4734      * @returns {Function} Returns the new mathematical operation function.
4735      */
4736     function createMathOperation(operator) {
4737       return function(value, other) {
4738         var result;
4739         if (value === undefined && other === undefined) {
4740           return 0;
4741         }
4742         if (value !== undefined) {
4743           result = value;
4744         }
4745         if (other !== undefined) {
4746           if (result === undefined) {
4747             return other;
4748           }
4749           if (typeof value == 'string' || typeof other == 'string') {
4750             value = baseToString(value);
4751             other = baseToString(other);
4752           } else {
4753             value = baseToNumber(value);
4754             other = baseToNumber(other);
4755           }
4756           result = operator(value, other);
4757         }
4758         return result;
4759       };
4760     }
4761
4762     /**
4763      * Creates a function like `_.over`.
4764      *
4765      * @private
4766      * @param {Function} arrayFunc The function to iterate over iteratees.
4767      * @returns {Function} Returns the new over function.
4768      */
4769     function createOver(arrayFunc) {
4770       return rest(function(iteratees) {
4771         iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
4772           ? arrayMap(iteratees[0], baseUnary(getIteratee()))
4773           : arrayMap(baseFlatten(iteratees, 1, isFlattenableIteratee), baseUnary(getIteratee()));
4774
4775         return rest(function(args) {
4776           var thisArg = this;
4777           return arrayFunc(iteratees, function(iteratee) {
4778             return apply(iteratee, thisArg, args);
4779           });
4780         });
4781       });
4782     }
4783
4784     /**
4785      * Creates the padding for `string` based on `length`. The `chars` string
4786      * is truncated if the number of characters exceeds `length`.
4787      *
4788      * @private
4789      * @param {number} length The padding length.
4790      * @param {string} [chars=' '] The string used as padding.
4791      * @returns {string} Returns the padding for `string`.
4792      */
4793     function createPadding(length, chars) {
4794       chars = chars === undefined ? ' ' : baseToString(chars);
4795
4796       var charsLength = chars.length;
4797       if (charsLength < 2) {
4798         return charsLength ? baseRepeat(chars, length) : chars;
4799       }
4800       var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
4801       return reHasComplexSymbol.test(chars)
4802         ? castSlice(stringToArray(result), 0, length).join('')
4803         : result.slice(0, length);
4804     }
4805
4806     /**
4807      * Creates a function that wraps `func` to invoke it with the `this` binding
4808      * of `thisArg` and `partials` prepended to the arguments it receives.
4809      *
4810      * @private
4811      * @param {Function} func The function to wrap.
4812      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
4813      *  for more details.
4814      * @param {*} thisArg The `this` binding of `func`.
4815      * @param {Array} partials The arguments to prepend to those provided to
4816      *  the new function.
4817      * @returns {Function} Returns the new wrapped function.
4818      */
4819     function createPartialWrapper(func, bitmask, thisArg, partials) {
4820       var isBind = bitmask & BIND_FLAG,
4821           Ctor = createCtorWrapper(func);
4822
4823       function wrapper() {
4824         var argsIndex = -1,
4825             argsLength = arguments.length,
4826             leftIndex = -1,
4827             leftLength = partials.length,
4828             args = Array(leftLength + argsLength),
4829             fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
4830
4831         while (++leftIndex < leftLength) {
4832           args[leftIndex] = partials[leftIndex];
4833         }
4834         while (argsLength--) {
4835           args[leftIndex++] = arguments[++argsIndex];
4836         }
4837         return apply(fn, isBind ? thisArg : this, args);
4838       }
4839       return wrapper;
4840     }
4841
4842     /**
4843      * Creates a `_.range` or `_.rangeRight` function.
4844      *
4845      * @private
4846      * @param {boolean} [fromRight] Specify iterating from right to left.
4847      * @returns {Function} Returns the new range function.
4848      */
4849     function createRange(fromRight) {
4850       return function(start, end, step) {
4851         if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
4852           end = step = undefined;
4853         }
4854         // Ensure the sign of `-0` is preserved.
4855         start = toNumber(start);
4856         start = start === start ? start : 0;
4857         if (end === undefined) {
4858           end = start;
4859           start = 0;
4860         } else {
4861           end = toNumber(end) || 0;
4862         }
4863         step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
4864         return baseRange(start, end, step, fromRight);
4865       };
4866     }
4867
4868     /**
4869      * Creates a function that performs a relational operation on two values.
4870      *
4871      * @private
4872      * @param {Function} operator The function to perform the operation.
4873      * @returns {Function} Returns the new relational operation function.
4874      */
4875     function createRelationalOperation(operator) {
4876       return function(value, other) {
4877         if (!(typeof value == 'string' && typeof other == 'string')) {
4878           value = toNumber(value);
4879           other = toNumber(other);
4880         }
4881         return operator(value, other);
4882       };
4883     }
4884
4885     /**
4886      * Creates a function that wraps `func` to continue currying.
4887      *
4888      * @private
4889      * @param {Function} func The function to wrap.
4890      * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper`
4891      *  for more details.
4892      * @param {Function} wrapFunc The function to create the `func` wrapper.
4893      * @param {*} placeholder The placeholder value.
4894      * @param {*} [thisArg] The `this` binding of `func`.
4895      * @param {Array} [partials] The arguments to prepend to those provided to
4896      *  the new function.
4897      * @param {Array} [holders] The `partials` placeholder indexes.
4898      * @param {Array} [argPos] The argument positions of the new function.
4899      * @param {number} [ary] The arity cap of `func`.
4900      * @param {number} [arity] The arity of `func`.
4901      * @returns {Function} Returns the new wrapped function.
4902      */
4903     function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
4904       var isCurry = bitmask & CURRY_FLAG,
4905           newHolders = isCurry ? holders : undefined,
4906           newHoldersRight = isCurry ? undefined : holders,
4907           newPartials = isCurry ? partials : undefined,
4908           newPartialsRight = isCurry ? undefined : partials;
4909
4910       bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
4911       bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
4912
4913       if (!(bitmask & CURRY_BOUND_FLAG)) {
4914         bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
4915       }
4916       var newData = [
4917         func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
4918         newHoldersRight, argPos, ary, arity
4919       ];
4920
4921       var result = wrapFunc.apply(undefined, newData);
4922       if (isLaziable(func)) {
4923         setData(result, newData);
4924       }
4925       result.placeholder = placeholder;
4926       return result;
4927     }
4928
4929     /**
4930      * Creates a function like `_.round`.
4931      *
4932      * @private
4933      * @param {string} methodName The name of the `Math` method to use when rounding.
4934      * @returns {Function} Returns the new round function.
4935      */
4936     function createRound(methodName) {
4937       var func = Math[methodName];
4938       return function(number, precision) {
4939         number = toNumber(number);
4940         precision = nativeMin(toInteger(precision), 292);
4941         if (precision) {
4942           // Shift with exponential notation to avoid floating-point issues.
4943           // See [MDN](https://mdn.io/round#Examples) for more details.
4944           var pair = (toString(number) + 'e').split('e'),
4945               value = func(pair[0] + 'e' + (+pair[1] + precision));
4946
4947           pair = (toString(value) + 'e').split('e');
4948           return +(pair[0] + 'e' + (+pair[1] - precision));
4949         }
4950         return func(number);
4951       };
4952     }
4953
4954     /**
4955      * Creates a set of `values`.
4956      *
4957      * @private
4958      * @param {Array} values The values to add to the set.
4959      * @returns {Object} Returns the new set.
4960      */
4961     var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
4962       return new Set(values);
4963     };
4964
4965     /**
4966      * Creates a `_.toPairs` or `_.toPairsIn` function.
4967      *
4968      * @private
4969      * @param {Function} keysFunc The function to get the keys of a given object.
4970      * @returns {Function} Returns the new pairs function.
4971      */
4972     function createToPairs(keysFunc) {
4973       return function(object) {
4974         var tag = getTag(object);
4975         if (tag == mapTag) {
4976           return mapToArray(object);
4977         }
4978         if (tag == setTag) {
4979           return setToPairs(object);
4980         }
4981         return baseToPairs(object, keysFunc(object));
4982       };
4983     }
4984
4985     /**
4986      * Creates a function that either curries or invokes `func` with optional
4987      * `this` binding and partially applied arguments.
4988      *
4989      * @private
4990      * @param {Function|string} func The function or method name to wrap.
4991      * @param {number} bitmask The bitmask of wrapper flags.
4992      *  The bitmask may be composed of the following flags:
4993      *     1 - `_.bind`
4994      *     2 - `_.bindKey`
4995      *     4 - `_.curry` or `_.curryRight` of a bound function
4996      *     8 - `_.curry`
4997      *    16 - `_.curryRight`
4998      *    32 - `_.partial`
4999      *    64 - `_.partialRight`
5000      *   128 - `_.rearg`
5001      *   256 - `_.ary`
5002      *   512 - `_.flip`
5003      * @param {*} [thisArg] The `this` binding of `func`.
5004      * @param {Array} [partials] The arguments to be partially applied.
5005      * @param {Array} [holders] The `partials` placeholder indexes.
5006      * @param {Array} [argPos] The argument positions of the new function.
5007      * @param {number} [ary] The arity cap of `func`.
5008      * @param {number} [arity] The arity of `func`.
5009      * @returns {Function} Returns the new wrapped function.
5010      */
5011     function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
5012       var isBindKey = bitmask & BIND_KEY_FLAG;
5013       if (!isBindKey && typeof func != 'function') {
5014         throw new TypeError(FUNC_ERROR_TEXT);
5015       }
5016       var length = partials ? partials.length : 0;
5017       if (!length) {
5018         bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
5019         partials = holders = undefined;
5020       }
5021       ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
5022       arity = arity === undefined ? arity : toInteger(arity);
5023       length -= holders ? holders.length : 0;
5024
5025       if (bitmask & PARTIAL_RIGHT_FLAG) {
5026         var partialsRight = partials,
5027             holdersRight = holders;
5028
5029         partials = holders = undefined;
5030       }
5031       var data = isBindKey ? undefined : getData(func);
5032
5033       var newData = [
5034         func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
5035         argPos, ary, arity
5036       ];
5037
5038       if (data) {
5039         mergeData(newData, data);
5040       }
5041       func = newData[0];
5042       bitmask = newData[1];
5043       thisArg = newData[2];
5044       partials = newData[3];
5045       holders = newData[4];
5046       arity = newData[9] = newData[9] == null
5047         ? (isBindKey ? 0 : func.length)
5048         : nativeMax(newData[9] - length, 0);
5049
5050       if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
5051         bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
5052       }
5053       if (!bitmask || bitmask == BIND_FLAG) {
5054         var result = createBaseWrapper(func, bitmask, thisArg);
5055       } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
5056         result = createCurryWrapper(func, bitmask, arity);
5057       } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
5058         result = createPartialWrapper(func, bitmask, thisArg, partials);
5059       } else {
5060         result = createHybridWrapper.apply(undefined, newData);
5061       }
5062       var setter = data ? baseSetData : setData;
5063       return setter(result, newData);
5064     }
5065
5066     /**
5067      * A specialized version of `baseIsEqualDeep` for arrays with support for
5068      * partial deep comparisons.
5069      *
5070      * @private
5071      * @param {Array} array The array to compare.
5072      * @param {Array} other The other array to compare.
5073      * @param {Function} equalFunc The function to determine equivalents of values.
5074      * @param {Function} customizer The function to customize comparisons.
5075      * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
5076      *  for more details.
5077      * @param {Object} stack Tracks traversed `array` and `other` objects.
5078      * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
5079      */
5080     function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
5081       var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
5082           arrLength = array.length,
5083           othLength = other.length;
5084
5085       if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
5086         return false;
5087       }
5088       // Assume cyclic values are equal.
5089       var stacked = stack.get(array);
5090       if (stacked) {
5091         return stacked == other;
5092       }
5093       var index = -1,
5094           result = true,
5095           seen = (bitmask & UNORDERED_COMPARE_FLAG) ? new SetCache : undefined;
5096
5097       stack.set(array, other);
5098
5099       // Ignore non-index properties.
5100       while (++index < arrLength) {
5101         var arrValue = array[index],
5102             othValue = other[index];
5103
5104         if (customizer) {
5105           var compared = isPartial
5106             ? customizer(othValue, arrValue, index, other, array, stack)
5107             : customizer(arrValue, othValue, index, array, other, stack);
5108         }
5109         if (compared !== undefined) {
5110           if (compared) {
5111             continue;
5112           }
5113           result = false;
5114           break;
5115         }
5116         // Recursively compare arrays (susceptible to call stack limits).
5117         if (seen) {
5118           if (!arraySome(other, function(othValue, othIndex) {
5119                 if (!seen.has(othIndex) &&
5120                     (arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
5121                   return seen.add(othIndex);
5122                 }
5123               })) {
5124             result = false;
5125             break;
5126           }
5127         } else if (!(
5128               arrValue === othValue ||
5129                 equalFunc(arrValue, othValue, customizer, bitmask, stack)
5130             )) {
5131           result = false;
5132           break;
5133         }
5134       }
5135       stack['delete'](array);
5136       return result;
5137     }
5138
5139     /**
5140      * A specialized version of `baseIsEqualDeep` for comparing objects of
5141      * the same `toStringTag`.
5142      *
5143      * **Note:** This function only supports comparing values with tags of
5144      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5145      *
5146      * @private
5147      * @param {Object} object The object to compare.
5148      * @param {Object} other The other object to compare.
5149      * @param {string} tag The `toStringTag` of the objects to compare.
5150      * @param {Function} equalFunc The function to determine equivalents of values.
5151      * @param {Function} customizer The function to customize comparisons.
5152      * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
5153      *  for more details.
5154      * @param {Object} stack Tracks traversed `object` and `other` objects.
5155      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5156      */
5157     function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) {
5158       switch (tag) {
5159         case dataViewTag:
5160           if ((object.byteLength != other.byteLength) ||
5161               (object.byteOffset != other.byteOffset)) {
5162             return false;
5163           }
5164           object = object.buffer;
5165           other = other.buffer;
5166
5167         case arrayBufferTag:
5168           if ((object.byteLength != other.byteLength) ||
5169               !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
5170             return false;
5171           }
5172           return true;
5173
5174         case boolTag:
5175         case dateTag:
5176           // Coerce dates and booleans to numbers, dates to milliseconds and
5177           // booleans to `1` or `0` treating invalid dates coerced to `NaN` as
5178           // not equal.
5179           return +object == +other;
5180
5181         case errorTag:
5182           return object.name == other.name && object.message == other.message;
5183
5184         case numberTag:
5185           // Treat `NaN` vs. `NaN` as equal.
5186           return (object != +object) ? other != +other : object == +other;
5187
5188         case regexpTag:
5189         case stringTag:
5190           // Coerce regexes to strings and treat strings, primitives and objects,
5191           // as equal. See http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.tostring
5192           // for more details.
5193           return object == (other + '');
5194
5195         case mapTag:
5196           var convert = mapToArray;
5197
5198         case setTag:
5199           var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
5200           convert || (convert = setToArray);
5201
5202           if (object.size != other.size && !isPartial) {
5203             return false;
5204           }
5205           // Assume cyclic values are equal.
5206           var stacked = stack.get(object);
5207           if (stacked) {
5208             return stacked == other;
5209           }
5210           bitmask |= UNORDERED_COMPARE_FLAG;
5211           stack.set(object, other);
5212
5213           // Recursively compare objects (susceptible to call stack limits).
5214           return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack);
5215
5216         case symbolTag:
5217           if (symbolValueOf) {
5218             return symbolValueOf.call(object) == symbolValueOf.call(other);
5219           }
5220       }
5221       return false;
5222     }
5223
5224     /**
5225      * A specialized version of `baseIsEqualDeep` for objects with support for
5226      * partial deep comparisons.
5227      *
5228      * @private
5229      * @param {Object} object The object to compare.
5230      * @param {Object} other The other object to compare.
5231      * @param {Function} equalFunc The function to determine equivalents of values.
5232      * @param {Function} customizer The function to customize comparisons.
5233      * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
5234      *  for more details.
5235      * @param {Object} stack Tracks traversed `object` and `other` objects.
5236      * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
5237      */
5238     function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
5239       var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
5240           objProps = keys(object),
5241           objLength = objProps.length,
5242           othProps = keys(other),
5243           othLength = othProps.length;
5244
5245       if (objLength != othLength && !isPartial) {
5246         return false;
5247       }
5248       var index = objLength;
5249       while (index--) {
5250         var key = objProps[index];
5251         if (!(isPartial ? key in other : baseHas(other, key))) {
5252           return false;
5253         }
5254       }
5255       // Assume cyclic values are equal.
5256       var stacked = stack.get(object);
5257       if (stacked) {
5258         return stacked == other;
5259       }
5260       var result = true;
5261       stack.set(object, other);
5262
5263       var skipCtor = isPartial;
5264       while (++index < objLength) {
5265         key = objProps[index];
5266         var objValue = object[key],
5267             othValue = other[key];
5268
5269         if (customizer) {
5270           var compared = isPartial
5271             ? customizer(othValue, objValue, key, other, object, stack)
5272             : customizer(objValue, othValue, key, object, other, stack);
5273         }
5274         // Recursively compare objects (susceptible to call stack limits).
5275         if (!(compared === undefined
5276               ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
5277               : compared
5278             )) {
5279           result = false;
5280           break;
5281         }
5282         skipCtor || (skipCtor = key == 'constructor');
5283       }
5284       if (result && !skipCtor) {
5285         var objCtor = object.constructor,
5286             othCtor = other.constructor;
5287
5288         // Non `Object` object instances with different constructors are not equal.
5289         if (objCtor != othCtor &&
5290             ('constructor' in object && 'constructor' in other) &&
5291             !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
5292               typeof othCtor == 'function' && othCtor instanceof othCtor)) {
5293           result = false;
5294         }
5295       }
5296       stack['delete'](object);
5297       return result;
5298     }
5299
5300     /**
5301      * Creates an array of own enumerable property names and symbols of `object`.
5302      *
5303      * @private
5304      * @param {Object} object The object to query.
5305      * @returns {Array} Returns the array of property names and symbols.
5306      */
5307     function getAllKeys(object) {
5308       return baseGetAllKeys(object, keys, getSymbols);
5309     }
5310
5311     /**
5312      * Creates an array of own and inherited enumerable property names and
5313      * symbols of `object`.
5314      *
5315      * @private
5316      * @param {Object} object The object to query.
5317      * @returns {Array} Returns the array of property names and symbols.
5318      */
5319     function getAllKeysIn(object) {
5320       return baseGetAllKeys(object, keysIn, getSymbolsIn);
5321     }
5322
5323     /**
5324      * Gets metadata for `func`.
5325      *
5326      * @private
5327      * @param {Function} func The function to query.
5328      * @returns {*} Returns the metadata for `func`.
5329      */
5330     var getData = !metaMap ? noop : function(func) {
5331       return metaMap.get(func);
5332     };
5333
5334     /**
5335      * Gets the name of `func`.
5336      *
5337      * @private
5338      * @param {Function} func The function to query.
5339      * @returns {string} Returns the function name.
5340      */
5341     function getFuncName(func) {
5342       var result = (func.name + ''),
5343           array = realNames[result],
5344           length = hasOwnProperty.call(realNames, result) ? array.length : 0;
5345
5346       while (length--) {
5347         var data = array[length],
5348             otherFunc = data.func;
5349         if (otherFunc == null || otherFunc == func) {
5350           return data.name;
5351         }
5352       }
5353       return result;
5354     }
5355
5356     /**
5357      * Gets the argument placeholder value for `func`.
5358      *
5359      * @private
5360      * @param {Function} func The function to inspect.
5361      * @returns {*} Returns the placeholder value.
5362      */
5363     function getHolder(func) {
5364       var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
5365       return object.placeholder;
5366     }
5367
5368     /**
5369      * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
5370      * this function returns the custom method, otherwise it returns `baseIteratee`.
5371      * If arguments are provided, the chosen function is invoked with them and
5372      * its result is returned.
5373      *
5374      * @private
5375      * @param {*} [value] The value to convert to an iteratee.
5376      * @param {number} [arity] The arity of the created iteratee.
5377      * @returns {Function} Returns the chosen function or its result.
5378      */
5379     function getIteratee() {
5380       var result = lodash.iteratee || iteratee;
5381       result = result === iteratee ? baseIteratee : result;
5382       return arguments.length ? result(arguments[0], arguments[1]) : result;
5383     }
5384
5385     /**
5386      * Gets the "length" property value of `object`.
5387      *
5388      * **Note:** This function is used to avoid a
5389      * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects
5390      * Safari on at least iOS 8.1-8.3 ARM64.
5391      *
5392      * @private
5393      * @param {Object} object The object to query.
5394      * @returns {*} Returns the "length" value.
5395      */
5396     var getLength = baseProperty('length');
5397
5398     /**
5399      * Gets the data for `map`.
5400      *
5401      * @private
5402      * @param {Object} map The map to query.
5403      * @param {string} key The reference key.
5404      * @returns {*} Returns the map data.
5405      */
5406     function getMapData(map, key) {
5407       var data = map.__data__;
5408       return isKeyable(key)
5409         ? data[typeof key == 'string' ? 'string' : 'hash']
5410         : data.map;
5411     }
5412
5413     /**
5414      * Gets the property names, values, and compare flags of `object`.
5415      *
5416      * @private
5417      * @param {Object} object The object to query.
5418      * @returns {Array} Returns the match data of `object`.
5419      */
5420     function getMatchData(object) {
5421       var result = keys(object),
5422           length = result.length;
5423
5424       while (length--) {
5425         var key = result[length],
5426             value = object[key];
5427
5428         result[length] = [key, value, isStrictComparable(value)];
5429       }
5430       return result;
5431     }
5432
5433     /**
5434      * Gets the native function at `key` of `object`.
5435      *
5436      * @private
5437      * @param {Object} object The object to query.
5438      * @param {string} key The key of the method to get.
5439      * @returns {*} Returns the function if it's native, else `undefined`.
5440      */
5441     function getNative(object, key) {
5442       var value = getValue(object, key);
5443       return baseIsNative(value) ? value : undefined;
5444     }
5445
5446     /**
5447      * Gets the `[[Prototype]]` of `value`.
5448      *
5449      * @private
5450      * @param {*} value The value to query.
5451      * @returns {null|Object} Returns the `[[Prototype]]`.
5452      */
5453     function getPrototype(value) {
5454       return nativeGetPrototype(Object(value));
5455     }
5456
5457     /**
5458      * Creates an array of the own enumerable symbol properties of `object`.
5459      *
5460      * @private
5461      * @param {Object} object The object to query.
5462      * @returns {Array} Returns the array of symbols.
5463      */
5464     function getSymbols(object) {
5465       // Coerce `object` to an object to avoid non-object errors in V8.
5466       // See https://bugs.chromium.org/p/v8/issues/detail?id=3443 for more details.
5467       return getOwnPropertySymbols(Object(object));
5468     }
5469
5470     // Fallback for IE < 11.
5471     if (!getOwnPropertySymbols) {
5472       getSymbols = stubArray;
5473     }
5474
5475     /**
5476      * Creates an array of the own and inherited enumerable symbol properties
5477      * of `object`.
5478      *
5479      * @private
5480      * @param {Object} object The object to query.
5481      * @returns {Array} Returns the array of symbols.
5482      */
5483     var getSymbolsIn = !getOwnPropertySymbols ? getSymbols : function(object) {
5484       var result = [];
5485       while (object) {
5486         arrayPush(result, getSymbols(object));
5487         object = getPrototype(object);
5488       }
5489       return result;
5490     };
5491
5492     /**
5493      * Gets the `toStringTag` of `value`.
5494      *
5495      * @private
5496      * @param {*} value The value to query.
5497      * @returns {string} Returns the `toStringTag`.
5498      */
5499     function getTag(value) {
5500       return objectToString.call(value);
5501     }
5502
5503     // Fallback for data views, maps, sets, and weak maps in IE 11,
5504     // for data views in Edge, and promises in Node.js.
5505     if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
5506         (Map && getTag(new Map) != mapTag) ||
5507         (Promise && getTag(Promise.resolve()) != promiseTag) ||
5508         (Set && getTag(new Set) != setTag) ||
5509         (WeakMap && getTag(new WeakMap) != weakMapTag)) {
5510       getTag = function(value) {
5511         var result = objectToString.call(value),
5512             Ctor = result == objectTag ? value.constructor : undefined,
5513             ctorString = Ctor ? toSource(Ctor) : undefined;
5514
5515         if (ctorString) {
5516           switch (ctorString) {
5517             case dataViewCtorString: return dataViewTag;
5518             case mapCtorString: return mapTag;
5519             case promiseCtorString: return promiseTag;
5520             case setCtorString: return setTag;
5521             case weakMapCtorString: return weakMapTag;
5522           }
5523         }
5524         return result;
5525       };
5526     }
5527
5528     /**
5529      * Gets the view, applying any `transforms` to the `start` and `end` positions.
5530      *
5531      * @private
5532      * @param {number} start The start of the view.
5533      * @param {number} end The end of the view.
5534      * @param {Array} transforms The transformations to apply to the view.
5535      * @returns {Object} Returns an object containing the `start` and `end`
5536      *  positions of the view.
5537      */
5538     function getView(start, end, transforms) {
5539       var index = -1,
5540           length = transforms.length;
5541
5542       while (++index < length) {
5543         var data = transforms[index],
5544             size = data.size;
5545
5546         switch (data.type) {
5547           case 'drop':      start += size; break;
5548           case 'dropRight': end -= size; break;
5549           case 'take':      end = nativeMin(end, start + size); break;
5550           case 'takeRight': start = nativeMax(start, end - size); break;
5551         }
5552       }
5553       return { 'start': start, 'end': end };
5554     }
5555
5556     /**
5557      * Checks if `path` exists on `object`.
5558      *
5559      * @private
5560      * @param {Object} object The object to query.
5561      * @param {Array|string} path The path to check.
5562      * @param {Function} hasFunc The function to check properties.
5563      * @returns {boolean} Returns `true` if `path` exists, else `false`.
5564      */
5565     function hasPath(object, path, hasFunc) {
5566       path = isKey(path, object) ? [path] : castPath(path);
5567
5568       var result,
5569           index = -1,
5570           length = path.length;
5571
5572       while (++index < length) {
5573         var key = toKey(path[index]);
5574         if (!(result = object != null && hasFunc(object, key))) {
5575           break;
5576         }
5577         object = object[key];
5578       }
5579       if (result) {
5580         return result;
5581       }
5582       var length = object ? object.length : 0;
5583       return !!length && isLength(length) && isIndex(key, length) &&
5584         (isArray(object) || isString(object) || isArguments(object));
5585     }
5586
5587     /**
5588      * Initializes an array clone.
5589      *
5590      * @private
5591      * @param {Array} array The array to clone.
5592      * @returns {Array} Returns the initialized clone.
5593      */
5594     function initCloneArray(array) {
5595       var length = array.length,
5596           result = array.constructor(length);
5597
5598       // Add properties assigned by `RegExp#exec`.
5599       if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
5600         result.index = array.index;
5601         result.input = array.input;
5602       }
5603       return result;
5604     }
5605
5606     /**
5607      * Initializes an object clone.
5608      *
5609      * @private
5610      * @param {Object} object The object to clone.
5611      * @returns {Object} Returns the initialized clone.
5612      */
5613     function initCloneObject(object) {
5614       return (typeof object.constructor == 'function' && !isPrototype(object))
5615         ? baseCreate(getPrototype(object))
5616         : {};
5617     }
5618
5619     /**
5620      * Initializes an object clone based on its `toStringTag`.
5621      *
5622      * **Note:** This function only supports cloning values with tags of
5623      * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
5624      *
5625      * @private
5626      * @param {Object} object The object to clone.
5627      * @param {string} tag The `toStringTag` of the object to clone.
5628      * @param {Function} cloneFunc The function to clone values.
5629      * @param {boolean} [isDeep] Specify a deep clone.
5630      * @returns {Object} Returns the initialized clone.
5631      */
5632     function initCloneByTag(object, tag, cloneFunc, isDeep) {
5633       var Ctor = object.constructor;
5634       switch (tag) {
5635         case arrayBufferTag:
5636           return cloneArrayBuffer(object);
5637
5638         case boolTag:
5639         case dateTag:
5640           return new Ctor(+object);
5641
5642         case dataViewTag:
5643           return cloneDataView(object, isDeep);
5644
5645         case float32Tag: case float64Tag:
5646         case int8Tag: case int16Tag: case int32Tag:
5647         case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
5648           return cloneTypedArray(object, isDeep);
5649
5650         case mapTag:
5651           return cloneMap(object, isDeep, cloneFunc);
5652
5653         case numberTag:
5654         case stringTag:
5655           return new Ctor(object);
5656
5657         case regexpTag:
5658           return cloneRegExp(object);
5659
5660         case setTag:
5661           return cloneSet(object, isDeep, cloneFunc);
5662
5663         case symbolTag:
5664           return cloneSymbol(object);
5665       }
5666     }
5667
5668     /**
5669      * Creates an array of index keys for `object` values of arrays,
5670      * `arguments` objects, and strings, otherwise `null` is returned.
5671      *
5672      * @private
5673      * @param {Object} object The object to query.
5674      * @returns {Array|null} Returns index keys, else `null`.
5675      */
5676     function indexKeys(object) {
5677       var length = object ? object.length : undefined;
5678       if (isLength(length) &&
5679           (isArray(object) || isString(object) || isArguments(object))) {
5680         return baseTimes(length, String);
5681       }
5682       return null;
5683     }
5684
5685     /**
5686      * Checks if `value` is a flattenable `arguments` object or array.
5687      *
5688      * @private
5689      * @param {*} value The value to check.
5690      * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
5691      */
5692     function isFlattenable(value) {
5693       return isArray(value) || isArguments(value);
5694     }
5695
5696     /**
5697      * Checks if `value` is a flattenable array and not a `_.matchesProperty`
5698      * iteratee shorthand.
5699      *
5700      * @private
5701      * @param {*} value The value to check.
5702      * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
5703      */
5704     function isFlattenableIteratee(value) {
5705       return isArray(value) && !(value.length == 2 && !isFunction(value[0]));
5706     }
5707
5708     /**
5709      * Checks if `value` is a valid array-like index.
5710      *
5711      * @private
5712      * @param {*} value The value to check.
5713      * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
5714      * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
5715      */
5716     function isIndex(value, length) {
5717       length = length == null ? MAX_SAFE_INTEGER : length;
5718       return !!length &&
5719         (typeof value == 'number' || reIsUint.test(value)) &&
5720         (value > -1 && value % 1 == 0 && value < length);
5721     }
5722
5723     /**
5724      * Checks if the given arguments are from an iteratee call.
5725      *
5726      * @private
5727      * @param {*} value The potential iteratee value argument.
5728      * @param {*} index The potential iteratee index or key argument.
5729      * @param {*} object The potential iteratee object argument.
5730      * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
5731      *  else `false`.
5732      */
5733     function isIterateeCall(value, index, object) {
5734       if (!isObject(object)) {
5735         return false;
5736       }
5737       var type = typeof index;
5738       if (type == 'number'
5739             ? (isArrayLike(object) && isIndex(index, object.length))
5740             : (type == 'string' && index in object)
5741           ) {
5742         return eq(object[index], value);
5743       }
5744       return false;
5745     }
5746
5747     /**
5748      * Checks if `value` is a property name and not a property path.
5749      *
5750      * @private
5751      * @param {*} value The value to check.
5752      * @param {Object} [object] The object to query keys on.
5753      * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
5754      */
5755     function isKey(value, object) {
5756       if (isArray(value)) {
5757         return false;
5758       }
5759       var type = typeof value;
5760       if (type == 'number' || type == 'symbol' || type == 'boolean' ||
5761           value == null || isSymbol(value)) {
5762         return true;
5763       }
5764       return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
5765         (object != null && value in Object(object));
5766     }
5767
5768     /**
5769      * Checks if `value` is suitable for use as unique object key.
5770      *
5771      * @private
5772      * @param {*} value The value to check.
5773      * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
5774      */
5775     function isKeyable(value) {
5776       var type = typeof value;
5777       return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
5778         ? (value !== '__proto__')
5779         : (value === null);
5780     }
5781
5782     /**
5783      * Checks if `func` has a lazy counterpart.
5784      *
5785      * @private
5786      * @param {Function} func The function to check.
5787      * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
5788      *  else `false`.
5789      */
5790     function isLaziable(func) {
5791       var funcName = getFuncName(func),
5792           other = lodash[funcName];
5793
5794       if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
5795         return false;
5796       }
5797       if (func === other) {
5798         return true;
5799       }
5800       var data = getData(other);
5801       return !!data && func === data[0];
5802     }
5803
5804     /**
5805      * Checks if `func` has its source masked.
5806      *
5807      * @private
5808      * @param {Function} func The function to check.
5809      * @returns {boolean} Returns `true` if `func` is masked, else `false`.
5810      */
5811     function isMasked(func) {
5812       return !!maskSrcKey && (maskSrcKey in func);
5813     }
5814
5815     /**
5816      * Checks if `func` is capable of being masked.
5817      *
5818      * @private
5819      * @param {*} value The value to check.
5820      * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
5821      */
5822     var isMaskable = coreJsData ? isFunction : stubFalse;
5823
5824     /**
5825      * Checks if `value` is likely a prototype object.
5826      *
5827      * @private
5828      * @param {*} value The value to check.
5829      * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
5830      */
5831     function isPrototype(value) {
5832       var Ctor = value && value.constructor,
5833           proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
5834
5835       return value === proto;
5836     }
5837
5838     /**
5839      * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
5840      *
5841      * @private
5842      * @param {*} value The value to check.
5843      * @returns {boolean} Returns `true` if `value` if suitable for strict
5844      *  equality comparisons, else `false`.
5845      */
5846     function isStrictComparable(value) {
5847       return value === value && !isObject(value);
5848     }
5849
5850     /**
5851      * A specialized version of `matchesProperty` for source values suitable
5852      * for strict equality comparisons, i.e. `===`.
5853      *
5854      * @private
5855      * @param {string} key The key of the property to get.
5856      * @param {*} srcValue The value to match.
5857      * @returns {Function} Returns the new spec function.
5858      */
5859     function matchesStrictComparable(key, srcValue) {
5860       return function(object) {
5861         if (object == null) {
5862           return false;
5863         }
5864         return object[key] === srcValue &&
5865           (srcValue !== undefined || (key in Object(object)));
5866       };
5867     }
5868
5869     /**
5870      * Merges the function metadata of `source` into `data`.
5871      *
5872      * Merging metadata reduces the number of wrappers used to invoke a function.
5873      * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
5874      * may be applied regardless of execution order. Methods like `_.ary` and
5875      * `_.rearg` modify function arguments, making the order in which they are
5876      * executed important, preventing the merging of metadata. However, we make
5877      * an exception for a safe combined case where curried functions have `_.ary`
5878      * and or `_.rearg` applied.
5879      *
5880      * @private
5881      * @param {Array} data The destination metadata.
5882      * @param {Array} source The source metadata.
5883      * @returns {Array} Returns `data`.
5884      */
5885     function mergeData(data, source) {
5886       var bitmask = data[1],
5887           srcBitmask = source[1],
5888           newBitmask = bitmask | srcBitmask,
5889           isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
5890
5891       var isCombo =
5892         ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) ||
5893         ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
5894         ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
5895
5896       // Exit early if metadata can't be merged.
5897       if (!(isCommon || isCombo)) {
5898         return data;
5899       }
5900       // Use source `thisArg` if available.
5901       if (srcBitmask & BIND_FLAG) {
5902         data[2] = source[2];
5903         // Set when currying a bound function.
5904         newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG;
5905       }
5906       // Compose partial arguments.
5907       var value = source[3];
5908       if (value) {
5909         var partials = data[3];
5910         data[3] = partials ? composeArgs(partials, value, source[4]) : value;
5911         data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
5912       }
5913       // Compose partial right arguments.
5914       value = source[5];
5915       if (value) {
5916         partials = data[5];
5917         data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
5918         data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
5919       }
5920       // Use source `argPos` if available.
5921       value = source[7];
5922       if (value) {
5923         data[7] = value;
5924       }
5925       // Use source `ary` if it's smaller.
5926       if (srcBitmask & ARY_FLAG) {
5927         data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
5928       }
5929       // Use source `arity` if one is not provided.
5930       if (data[9] == null) {
5931         data[9] = source[9];
5932       }
5933       // Use source `func` and merge bitmasks.
5934       data[0] = source[0];
5935       data[1] = newBitmask;
5936
5937       return data;
5938     }
5939
5940     /**
5941      * Used by `_.defaultsDeep` to customize its `_.merge` use.
5942      *
5943      * @private
5944      * @param {*} objValue The destination value.
5945      * @param {*} srcValue The source value.
5946      * @param {string} key The key of the property to merge.
5947      * @param {Object} object The parent object of `objValue`.
5948      * @param {Object} source The parent object of `srcValue`.
5949      * @param {Object} [stack] Tracks traversed source values and their merged
5950      *  counterparts.
5951      * @returns {*} Returns the value to assign.
5952      */
5953     function mergeDefaults(objValue, srcValue, key, object, source, stack) {
5954       if (isObject(objValue) && isObject(srcValue)) {
5955         baseMerge(objValue, srcValue, undefined, mergeDefaults, stack.set(srcValue, objValue));
5956       }
5957       return objValue;
5958     }
5959
5960     /**
5961      * Gets the parent value at `path` of `object`.
5962      *
5963      * @private
5964      * @param {Object} object The object to query.
5965      * @param {Array} path The path to get the parent value of.
5966      * @returns {*} Returns the parent value.
5967      */
5968     function parent(object, path) {
5969       return path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
5970     }
5971
5972     /**
5973      * Reorder `array` according to the specified indexes where the element at
5974      * the first index is assigned as the first element, the element at
5975      * the second index is assigned as the second element, and so on.
5976      *
5977      * @private
5978      * @param {Array} array The array to reorder.
5979      * @param {Array} indexes The arranged array indexes.
5980      * @returns {Array} Returns `array`.
5981      */
5982     function reorder(array, indexes) {
5983       var arrLength = array.length,
5984           length = nativeMin(indexes.length, arrLength),
5985           oldArray = copyArray(array);
5986
5987       while (length--) {
5988         var index = indexes[length];
5989         array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
5990       }
5991       return array;
5992     }
5993
5994     /**
5995      * Sets metadata for `func`.
5996      *
5997      * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
5998      * period of time, it will trip its breaker and transition to an identity
5999      * function to avoid garbage collection pauses in V8. See
6000      * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
6001      * for more details.
6002      *
6003      * @private
6004      * @param {Function} func The function to associate metadata with.
6005      * @param {*} data The metadata.
6006      * @returns {Function} Returns `func`.
6007      */
6008     var setData = (function() {
6009       var count = 0,
6010           lastCalled = 0;
6011
6012       return function(key, value) {
6013         var stamp = now(),
6014             remaining = HOT_SPAN - (stamp - lastCalled);
6015
6016         lastCalled = stamp;
6017         if (remaining > 0) {
6018           if (++count >= HOT_COUNT) {
6019             return key;
6020           }
6021         } else {
6022           count = 0;
6023         }
6024         return baseSetData(key, value);
6025       };
6026     }());
6027
6028     /**
6029      * Converts `string` to a property path array.
6030      *
6031      * @private
6032      * @param {string} string The string to convert.
6033      * @returns {Array} Returns the property path array.
6034      */
6035     var stringToPath = memoize(function(string) {
6036       var result = [];
6037       toString(string).replace(rePropName, function(match, number, quote, string) {
6038         result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
6039       });
6040       return result;
6041     });
6042
6043     /**
6044      * Converts `value` to a string key if it's not a string or symbol.
6045      *
6046      * @private
6047      * @param {*} value The value to inspect.
6048      * @returns {string|symbol} Returns the key.
6049      */
6050     function toKey(value) {
6051       if (typeof value == 'string' || isSymbol(value)) {
6052         return value;
6053       }
6054       var result = (value + '');
6055       return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
6056     }
6057
6058     /**
6059      * Converts `func` to its source code.
6060      *
6061      * @private
6062      * @param {Function} func The function to process.
6063      * @returns {string} Returns the source code.
6064      */
6065     function toSource(func) {
6066       if (func != null) {
6067         try {
6068           return funcToString.call(func);
6069         } catch (e) {}
6070         try {
6071           return (func + '');
6072         } catch (e) {}
6073       }
6074       return '';
6075     }
6076
6077     /**
6078      * Creates a clone of `wrapper`.
6079      *
6080      * @private
6081      * @param {Object} wrapper The wrapper to clone.
6082      * @returns {Object} Returns the cloned wrapper.
6083      */
6084     function wrapperClone(wrapper) {
6085       if (wrapper instanceof LazyWrapper) {
6086         return wrapper.clone();
6087       }
6088       var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
6089       result.__actions__ = copyArray(wrapper.__actions__);
6090       result.__index__  = wrapper.__index__;
6091       result.__values__ = wrapper.__values__;
6092       return result;
6093     }
6094
6095     /*------------------------------------------------------------------------*/
6096
6097     /**
6098      * Creates an array of elements split into groups the length of `size`.
6099      * If `array` can't be split evenly, the final chunk will be the remaining
6100      * elements.
6101      *
6102      * @static
6103      * @memberOf _
6104      * @since 3.0.0
6105      * @category Array
6106      * @param {Array} array The array to process.
6107      * @param {number} [size=1] The length of each chunk
6108      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6109      * @returns {Array} Returns the new array of chunks.
6110      * @example
6111      *
6112      * _.chunk(['a', 'b', 'c', 'd'], 2);
6113      * // => [['a', 'b'], ['c', 'd']]
6114      *
6115      * _.chunk(['a', 'b', 'c', 'd'], 3);
6116      * // => [['a', 'b', 'c'], ['d']]
6117      */
6118     function chunk(array, size, guard) {
6119       if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
6120         size = 1;
6121       } else {
6122         size = nativeMax(toInteger(size), 0);
6123       }
6124       var length = array ? array.length : 0;
6125       if (!length || size < 1) {
6126         return [];
6127       }
6128       var index = 0,
6129           resIndex = 0,
6130           result = Array(nativeCeil(length / size));
6131
6132       while (index < length) {
6133         result[resIndex++] = baseSlice(array, index, (index += size));
6134       }
6135       return result;
6136     }
6137
6138     /**
6139      * Creates an array with all falsey values removed. The values `false`, `null`,
6140      * `0`, `""`, `undefined`, and `NaN` are falsey.
6141      *
6142      * @static
6143      * @memberOf _
6144      * @since 0.1.0
6145      * @category Array
6146      * @param {Array} array The array to compact.
6147      * @returns {Array} Returns the new array of filtered values.
6148      * @example
6149      *
6150      * _.compact([0, 1, false, 2, '', 3]);
6151      * // => [1, 2, 3]
6152      */
6153     function compact(array) {
6154       var index = -1,
6155           length = array ? array.length : 0,
6156           resIndex = 0,
6157           result = [];
6158
6159       while (++index < length) {
6160         var value = array[index];
6161         if (value) {
6162           result[resIndex++] = value;
6163         }
6164       }
6165       return result;
6166     }
6167
6168     /**
6169      * Creates a new array concatenating `array` with any additional arrays
6170      * and/or values.
6171      *
6172      * @static
6173      * @memberOf _
6174      * @since 4.0.0
6175      * @category Array
6176      * @param {Array} array The array to concatenate.
6177      * @param {...*} [values] The values to concatenate.
6178      * @returns {Array} Returns the new concatenated array.
6179      * @example
6180      *
6181      * var array = [1];
6182      * var other = _.concat(array, 2, [3], [[4]]);
6183      *
6184      * console.log(other);
6185      * // => [1, 2, 3, [4]]
6186      *
6187      * console.log(array);
6188      * // => [1]
6189      */
6190     function concat() {
6191       var length = arguments.length,
6192           args = Array(length ? length - 1 : 0),
6193           array = arguments[0],
6194           index = length;
6195
6196       while (index--) {
6197         args[index - 1] = arguments[index];
6198       }
6199       return length
6200         ? arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1))
6201         : [];
6202     }
6203
6204     /**
6205      * Creates an array of unique `array` values not included in the other given
6206      * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6207      * for equality comparisons. The order of result values is determined by the
6208      * order they occur in the first array.
6209      *
6210      * @static
6211      * @memberOf _
6212      * @since 0.1.0
6213      * @category Array
6214      * @param {Array} array The array to inspect.
6215      * @param {...Array} [values] The values to exclude.
6216      * @returns {Array} Returns the new array of filtered values.
6217      * @see _.without, _.xor
6218      * @example
6219      *
6220      * _.difference([2, 1], [2, 3]);
6221      * // => [1]
6222      */
6223     var difference = rest(function(array, values) {
6224       return isArrayLikeObject(array)
6225         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
6226         : [];
6227     });
6228
6229     /**
6230      * This method is like `_.difference` except that it accepts `iteratee` which
6231      * is invoked for each element of `array` and `values` to generate the criterion
6232      * by which they're compared. Result values are chosen from the first array.
6233      * The iteratee is invoked with one argument: (value).
6234      *
6235      * @static
6236      * @memberOf _
6237      * @since 4.0.0
6238      * @category Array
6239      * @param {Array} array The array to inspect.
6240      * @param {...Array} [values] The values to exclude.
6241      * @param {Array|Function|Object|string} [iteratee=_.identity]
6242      *  The iteratee invoked per element.
6243      * @returns {Array} Returns the new array of filtered values.
6244      * @example
6245      *
6246      * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
6247      * // => [1.2]
6248      *
6249      * // The `_.property` iteratee shorthand.
6250      * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
6251      * // => [{ 'x': 2 }]
6252      */
6253     var differenceBy = rest(function(array, values) {
6254       var iteratee = last(values);
6255       if (isArrayLikeObject(iteratee)) {
6256         iteratee = undefined;
6257       }
6258       return isArrayLikeObject(array)
6259         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee))
6260         : [];
6261     });
6262
6263     /**
6264      * This method is like `_.difference` except that it accepts `comparator`
6265      * which is invoked to compare elements of `array` to `values`. Result values
6266      * are chosen from the first array. The comparator is invoked with two arguments:
6267      * (arrVal, othVal).
6268      *
6269      * @static
6270      * @memberOf _
6271      * @since 4.0.0
6272      * @category Array
6273      * @param {Array} array The array to inspect.
6274      * @param {...Array} [values] The values to exclude.
6275      * @param {Function} [comparator] The comparator invoked per element.
6276      * @returns {Array} Returns the new array of filtered values.
6277      * @example
6278      *
6279      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6280      *
6281      * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
6282      * // => [{ 'x': 2, 'y': 1 }]
6283      */
6284     var differenceWith = rest(function(array, values) {
6285       var comparator = last(values);
6286       if (isArrayLikeObject(comparator)) {
6287         comparator = undefined;
6288       }
6289       return isArrayLikeObject(array)
6290         ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
6291         : [];
6292     });
6293
6294     /**
6295      * Creates a slice of `array` with `n` elements dropped from the beginning.
6296      *
6297      * @static
6298      * @memberOf _
6299      * @since 0.5.0
6300      * @category Array
6301      * @param {Array} array The array to query.
6302      * @param {number} [n=1] The number of elements to drop.
6303      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6304      * @returns {Array} Returns the slice of `array`.
6305      * @example
6306      *
6307      * _.drop([1, 2, 3]);
6308      * // => [2, 3]
6309      *
6310      * _.drop([1, 2, 3], 2);
6311      * // => [3]
6312      *
6313      * _.drop([1, 2, 3], 5);
6314      * // => []
6315      *
6316      * _.drop([1, 2, 3], 0);
6317      * // => [1, 2, 3]
6318      */
6319     function drop(array, n, guard) {
6320       var length = array ? array.length : 0;
6321       if (!length) {
6322         return [];
6323       }
6324       n = (guard || n === undefined) ? 1 : toInteger(n);
6325       return baseSlice(array, n < 0 ? 0 : n, length);
6326     }
6327
6328     /**
6329      * Creates a slice of `array` with `n` elements dropped from the end.
6330      *
6331      * @static
6332      * @memberOf _
6333      * @since 3.0.0
6334      * @category Array
6335      * @param {Array} array The array to query.
6336      * @param {number} [n=1] The number of elements to drop.
6337      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
6338      * @returns {Array} Returns the slice of `array`.
6339      * @example
6340      *
6341      * _.dropRight([1, 2, 3]);
6342      * // => [1, 2]
6343      *
6344      * _.dropRight([1, 2, 3], 2);
6345      * // => [1]
6346      *
6347      * _.dropRight([1, 2, 3], 5);
6348      * // => []
6349      *
6350      * _.dropRight([1, 2, 3], 0);
6351      * // => [1, 2, 3]
6352      */
6353     function dropRight(array, n, guard) {
6354       var length = array ? array.length : 0;
6355       if (!length) {
6356         return [];
6357       }
6358       n = (guard || n === undefined) ? 1 : toInteger(n);
6359       n = length - n;
6360       return baseSlice(array, 0, n < 0 ? 0 : n);
6361     }
6362
6363     /**
6364      * Creates a slice of `array` excluding elements dropped from the end.
6365      * Elements are dropped until `predicate` returns falsey. The predicate is
6366      * invoked with three arguments: (value, index, array).
6367      *
6368      * @static
6369      * @memberOf _
6370      * @since 3.0.0
6371      * @category Array
6372      * @param {Array} array The array to query.
6373      * @param {Array|Function|Object|string} [predicate=_.identity]
6374      *  The function invoked per iteration.
6375      * @returns {Array} Returns the slice of `array`.
6376      * @example
6377      *
6378      * var users = [
6379      *   { 'user': 'barney',  'active': true },
6380      *   { 'user': 'fred',    'active': false },
6381      *   { 'user': 'pebbles', 'active': false }
6382      * ];
6383      *
6384      * _.dropRightWhile(users, function(o) { return !o.active; });
6385      * // => objects for ['barney']
6386      *
6387      * // The `_.matches` iteratee shorthand.
6388      * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
6389      * // => objects for ['barney', 'fred']
6390      *
6391      * // The `_.matchesProperty` iteratee shorthand.
6392      * _.dropRightWhile(users, ['active', false]);
6393      * // => objects for ['barney']
6394      *
6395      * // The `_.property` iteratee shorthand.
6396      * _.dropRightWhile(users, 'active');
6397      * // => objects for ['barney', 'fred', 'pebbles']
6398      */
6399     function dropRightWhile(array, predicate) {
6400       return (array && array.length)
6401         ? baseWhile(array, getIteratee(predicate, 3), true, true)
6402         : [];
6403     }
6404
6405     /**
6406      * Creates a slice of `array` excluding elements dropped from the beginning.
6407      * Elements are dropped until `predicate` returns falsey. The predicate is
6408      * invoked with three arguments: (value, index, array).
6409      *
6410      * @static
6411      * @memberOf _
6412      * @since 3.0.0
6413      * @category Array
6414      * @param {Array} array The array to query.
6415      * @param {Array|Function|Object|string} [predicate=_.identity]
6416      *  The function invoked per iteration.
6417      * @returns {Array} Returns the slice of `array`.
6418      * @example
6419      *
6420      * var users = [
6421      *   { 'user': 'barney',  'active': false },
6422      *   { 'user': 'fred',    'active': false },
6423      *   { 'user': 'pebbles', 'active': true }
6424      * ];
6425      *
6426      * _.dropWhile(users, function(o) { return !o.active; });
6427      * // => objects for ['pebbles']
6428      *
6429      * // The `_.matches` iteratee shorthand.
6430      * _.dropWhile(users, { 'user': 'barney', 'active': false });
6431      * // => objects for ['fred', 'pebbles']
6432      *
6433      * // The `_.matchesProperty` iteratee shorthand.
6434      * _.dropWhile(users, ['active', false]);
6435      * // => objects for ['pebbles']
6436      *
6437      * // The `_.property` iteratee shorthand.
6438      * _.dropWhile(users, 'active');
6439      * // => objects for ['barney', 'fred', 'pebbles']
6440      */
6441     function dropWhile(array, predicate) {
6442       return (array && array.length)
6443         ? baseWhile(array, getIteratee(predicate, 3), true)
6444         : [];
6445     }
6446
6447     /**
6448      * Fills elements of `array` with `value` from `start` up to, but not
6449      * including, `end`.
6450      *
6451      * **Note:** This method mutates `array`.
6452      *
6453      * @static
6454      * @memberOf _
6455      * @since 3.2.0
6456      * @category Array
6457      * @param {Array} array The array to fill.
6458      * @param {*} value The value to fill `array` with.
6459      * @param {number} [start=0] The start position.
6460      * @param {number} [end=array.length] The end position.
6461      * @returns {Array} Returns `array`.
6462      * @example
6463      *
6464      * var array = [1, 2, 3];
6465      *
6466      * _.fill(array, 'a');
6467      * console.log(array);
6468      * // => ['a', 'a', 'a']
6469      *
6470      * _.fill(Array(3), 2);
6471      * // => [2, 2, 2]
6472      *
6473      * _.fill([4, 6, 8, 10], '*', 1, 3);
6474      * // => [4, '*', '*', 10]
6475      */
6476     function fill(array, value, start, end) {
6477       var length = array ? array.length : 0;
6478       if (!length) {
6479         return [];
6480       }
6481       if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
6482         start = 0;
6483         end = length;
6484       }
6485       return baseFill(array, value, start, end);
6486     }
6487
6488     /**
6489      * This method is like `_.find` except that it returns the index of the first
6490      * element `predicate` returns truthy for instead of the element itself.
6491      *
6492      * @static
6493      * @memberOf _
6494      * @since 1.1.0
6495      * @category Array
6496      * @param {Array} array The array to search.
6497      * @param {Array|Function|Object|string} [predicate=_.identity]
6498      *  The function invoked per iteration.
6499      * @param {number} [fromIndex=0] The index to search from.
6500      * @returns {number} Returns the index of the found element, else `-1`.
6501      * @example
6502      *
6503      * var users = [
6504      *   { 'user': 'barney',  'active': false },
6505      *   { 'user': 'fred',    'active': false },
6506      *   { 'user': 'pebbles', 'active': true }
6507      * ];
6508      *
6509      * _.findIndex(users, function(o) { return o.user == 'barney'; });
6510      * // => 0
6511      *
6512      * // The `_.matches` iteratee shorthand.
6513      * _.findIndex(users, { 'user': 'fred', 'active': false });
6514      * // => 1
6515      *
6516      * // The `_.matchesProperty` iteratee shorthand.
6517      * _.findIndex(users, ['active', false]);
6518      * // => 0
6519      *
6520      * // The `_.property` iteratee shorthand.
6521      * _.findIndex(users, 'active');
6522      * // => 2
6523      */
6524     function findIndex(array, predicate, fromIndex) {
6525       var length = array ? array.length : 0;
6526       if (!length) {
6527         return -1;
6528       }
6529       var index = fromIndex == null ? 0 : toInteger(fromIndex);
6530       if (index < 0) {
6531         index = nativeMax(length + index, 0);
6532       }
6533       return baseFindIndex(array, getIteratee(predicate, 3), index);
6534     }
6535
6536     /**
6537      * This method is like `_.findIndex` except that it iterates over elements
6538      * of `collection` from right to left.
6539      *
6540      * @static
6541      * @memberOf _
6542      * @since 2.0.0
6543      * @category Array
6544      * @param {Array} array The array to search.
6545      * @param {Array|Function|Object|string} [predicate=_.identity]
6546      *  The function invoked per iteration.
6547      * @param {number} [fromIndex=array.length-1] The index to search from.
6548      * @returns {number} Returns the index of the found element, else `-1`.
6549      * @example
6550      *
6551      * var users = [
6552      *   { 'user': 'barney',  'active': true },
6553      *   { 'user': 'fred',    'active': false },
6554      *   { 'user': 'pebbles', 'active': false }
6555      * ];
6556      *
6557      * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
6558      * // => 2
6559      *
6560      * // The `_.matches` iteratee shorthand.
6561      * _.findLastIndex(users, { 'user': 'barney', 'active': true });
6562      * // => 0
6563      *
6564      * // The `_.matchesProperty` iteratee shorthand.
6565      * _.findLastIndex(users, ['active', false]);
6566      * // => 2
6567      *
6568      * // The `_.property` iteratee shorthand.
6569      * _.findLastIndex(users, 'active');
6570      * // => 0
6571      */
6572     function findLastIndex(array, predicate, fromIndex) {
6573       var length = array ? array.length : 0;
6574       if (!length) {
6575         return -1;
6576       }
6577       var index = length - 1;
6578       if (fromIndex !== undefined) {
6579         index = toInteger(fromIndex);
6580         index = fromIndex < 0
6581           ? nativeMax(length + index, 0)
6582           : nativeMin(index, length - 1);
6583       }
6584       return baseFindIndex(array, getIteratee(predicate, 3), index, true);
6585     }
6586
6587     /**
6588      * Flattens `array` a single level deep.
6589      *
6590      * @static
6591      * @memberOf _
6592      * @since 0.1.0
6593      * @category Array
6594      * @param {Array} array The array to flatten.
6595      * @returns {Array} Returns the new flattened array.
6596      * @example
6597      *
6598      * _.flatten([1, [2, [3, [4]], 5]]);
6599      * // => [1, 2, [3, [4]], 5]
6600      */
6601     function flatten(array) {
6602       var length = array ? array.length : 0;
6603       return length ? baseFlatten(array, 1) : [];
6604     }
6605
6606     /**
6607      * Recursively flattens `array`.
6608      *
6609      * @static
6610      * @memberOf _
6611      * @since 3.0.0
6612      * @category Array
6613      * @param {Array} array The array to flatten.
6614      * @returns {Array} Returns the new flattened array.
6615      * @example
6616      *
6617      * _.flattenDeep([1, [2, [3, [4]], 5]]);
6618      * // => [1, 2, 3, 4, 5]
6619      */
6620     function flattenDeep(array) {
6621       var length = array ? array.length : 0;
6622       return length ? baseFlatten(array, INFINITY) : [];
6623     }
6624
6625     /**
6626      * Recursively flatten `array` up to `depth` times.
6627      *
6628      * @static
6629      * @memberOf _
6630      * @since 4.4.0
6631      * @category Array
6632      * @param {Array} array The array to flatten.
6633      * @param {number} [depth=1] The maximum recursion depth.
6634      * @returns {Array} Returns the new flattened array.
6635      * @example
6636      *
6637      * var array = [1, [2, [3, [4]], 5]];
6638      *
6639      * _.flattenDepth(array, 1);
6640      * // => [1, 2, [3, [4]], 5]
6641      *
6642      * _.flattenDepth(array, 2);
6643      * // => [1, 2, 3, [4], 5]
6644      */
6645     function flattenDepth(array, depth) {
6646       var length = array ? array.length : 0;
6647       if (!length) {
6648         return [];
6649       }
6650       depth = depth === undefined ? 1 : toInteger(depth);
6651       return baseFlatten(array, depth);
6652     }
6653
6654     /**
6655      * The inverse of `_.toPairs`; this method returns an object composed
6656      * from key-value `pairs`.
6657      *
6658      * @static
6659      * @memberOf _
6660      * @since 4.0.0
6661      * @category Array
6662      * @param {Array} pairs The key-value pairs.
6663      * @returns {Object} Returns the new object.
6664      * @example
6665      *
6666      * _.fromPairs([['fred', 30], ['barney', 40]]);
6667      * // => { 'fred': 30, 'barney': 40 }
6668      */
6669     function fromPairs(pairs) {
6670       var index = -1,
6671           length = pairs ? pairs.length : 0,
6672           result = {};
6673
6674       while (++index < length) {
6675         var pair = pairs[index];
6676         result[pair[0]] = pair[1];
6677       }
6678       return result;
6679     }
6680
6681     /**
6682      * Gets the first element of `array`.
6683      *
6684      * @static
6685      * @memberOf _
6686      * @since 0.1.0
6687      * @alias first
6688      * @category Array
6689      * @param {Array} array The array to query.
6690      * @returns {*} Returns the first element of `array`.
6691      * @example
6692      *
6693      * _.head([1, 2, 3]);
6694      * // => 1
6695      *
6696      * _.head([]);
6697      * // => undefined
6698      */
6699     function head(array) {
6700       return (array && array.length) ? array[0] : undefined;
6701     }
6702
6703     /**
6704      * Gets the index at which the first occurrence of `value` is found in `array`
6705      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6706      * for equality comparisons. If `fromIndex` is negative, it's used as the
6707      * offset from the end of `array`.
6708      *
6709      * @static
6710      * @memberOf _
6711      * @since 0.1.0
6712      * @category Array
6713      * @param {Array} array The array to search.
6714      * @param {*} value The value to search for.
6715      * @param {number} [fromIndex=0] The index to search from.
6716      * @returns {number} Returns the index of the matched value, else `-1`.
6717      * @example
6718      *
6719      * _.indexOf([1, 2, 1, 2], 2);
6720      * // => 1
6721      *
6722      * // Search from the `fromIndex`.
6723      * _.indexOf([1, 2, 1, 2], 2, 2);
6724      * // => 3
6725      */
6726     function indexOf(array, value, fromIndex) {
6727       var length = array ? array.length : 0;
6728       if (!length) {
6729         return -1;
6730       }
6731       var index = fromIndex == null ? 0 : toInteger(fromIndex);
6732       if (index < 0) {
6733         index = nativeMax(length + index, 0);
6734       }
6735       return baseIndexOf(array, value, index);
6736     }
6737
6738     /**
6739      * Gets all but the last element of `array`.
6740      *
6741      * @static
6742      * @memberOf _
6743      * @since 0.1.0
6744      * @category Array
6745      * @param {Array} array The array to query.
6746      * @returns {Array} Returns the slice of `array`.
6747      * @example
6748      *
6749      * _.initial([1, 2, 3]);
6750      * // => [1, 2]
6751      */
6752     function initial(array) {
6753       return dropRight(array, 1);
6754     }
6755
6756     /**
6757      * Creates an array of unique values that are included in all given arrays
6758      * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6759      * for equality comparisons. The order of result values is determined by the
6760      * order they occur in the first array.
6761      *
6762      * @static
6763      * @memberOf _
6764      * @since 0.1.0
6765      * @category Array
6766      * @param {...Array} [arrays] The arrays to inspect.
6767      * @returns {Array} Returns the new array of intersecting values.
6768      * @example
6769      *
6770      * _.intersection([2, 1], [2, 3]);
6771      * // => [2]
6772      */
6773     var intersection = rest(function(arrays) {
6774       var mapped = arrayMap(arrays, castArrayLikeObject);
6775       return (mapped.length && mapped[0] === arrays[0])
6776         ? baseIntersection(mapped)
6777         : [];
6778     });
6779
6780     /**
6781      * This method is like `_.intersection` except that it accepts `iteratee`
6782      * which is invoked for each element of each `arrays` to generate the criterion
6783      * by which they're compared. Result values are chosen from the first array.
6784      * The iteratee is invoked with one argument: (value).
6785      *
6786      * @static
6787      * @memberOf _
6788      * @since 4.0.0
6789      * @category Array
6790      * @param {...Array} [arrays] The arrays to inspect.
6791      * @param {Array|Function|Object|string} [iteratee=_.identity]
6792      *  The iteratee invoked per element.
6793      * @returns {Array} Returns the new array of intersecting values.
6794      * @example
6795      *
6796      * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
6797      * // => [2.1]
6798      *
6799      * // The `_.property` iteratee shorthand.
6800      * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
6801      * // => [{ 'x': 1 }]
6802      */
6803     var intersectionBy = rest(function(arrays) {
6804       var iteratee = last(arrays),
6805           mapped = arrayMap(arrays, castArrayLikeObject);
6806
6807       if (iteratee === last(mapped)) {
6808         iteratee = undefined;
6809       } else {
6810         mapped.pop();
6811       }
6812       return (mapped.length && mapped[0] === arrays[0])
6813         ? baseIntersection(mapped, getIteratee(iteratee))
6814         : [];
6815     });
6816
6817     /**
6818      * This method is like `_.intersection` except that it accepts `comparator`
6819      * which is invoked to compare elements of `arrays`. Result values are chosen
6820      * from the first array. The comparator is invoked with two arguments:
6821      * (arrVal, othVal).
6822      *
6823      * @static
6824      * @memberOf _
6825      * @since 4.0.0
6826      * @category Array
6827      * @param {...Array} [arrays] The arrays to inspect.
6828      * @param {Function} [comparator] The comparator invoked per element.
6829      * @returns {Array} Returns the new array of intersecting values.
6830      * @example
6831      *
6832      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
6833      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
6834      *
6835      * _.intersectionWith(objects, others, _.isEqual);
6836      * // => [{ 'x': 1, 'y': 2 }]
6837      */
6838     var intersectionWith = rest(function(arrays) {
6839       var comparator = last(arrays),
6840           mapped = arrayMap(arrays, castArrayLikeObject);
6841
6842       if (comparator === last(mapped)) {
6843         comparator = undefined;
6844       } else {
6845         mapped.pop();
6846       }
6847       return (mapped.length && mapped[0] === arrays[0])
6848         ? baseIntersection(mapped, undefined, comparator)
6849         : [];
6850     });
6851
6852     /**
6853      * Converts all elements in `array` into a string separated by `separator`.
6854      *
6855      * @static
6856      * @memberOf _
6857      * @since 4.0.0
6858      * @category Array
6859      * @param {Array} array The array to convert.
6860      * @param {string} [separator=','] The element separator.
6861      * @returns {string} Returns the joined string.
6862      * @example
6863      *
6864      * _.join(['a', 'b', 'c'], '~');
6865      * // => 'a~b~c'
6866      */
6867     function join(array, separator) {
6868       return array ? nativeJoin.call(array, separator) : '';
6869     }
6870
6871     /**
6872      * Gets the last element of `array`.
6873      *
6874      * @static
6875      * @memberOf _
6876      * @since 0.1.0
6877      * @category Array
6878      * @param {Array} array The array to query.
6879      * @returns {*} Returns the last element of `array`.
6880      * @example
6881      *
6882      * _.last([1, 2, 3]);
6883      * // => 3
6884      */
6885     function last(array) {
6886       var length = array ? array.length : 0;
6887       return length ? array[length - 1] : undefined;
6888     }
6889
6890     /**
6891      * This method is like `_.indexOf` except that it iterates over elements of
6892      * `array` from right to left.
6893      *
6894      * @static
6895      * @memberOf _
6896      * @since 0.1.0
6897      * @category Array
6898      * @param {Array} array The array to search.
6899      * @param {*} value The value to search for.
6900      * @param {number} [fromIndex=array.length-1] The index to search from.
6901      * @returns {number} Returns the index of the matched value, else `-1`.
6902      * @example
6903      *
6904      * _.lastIndexOf([1, 2, 1, 2], 2);
6905      * // => 3
6906      *
6907      * // Search from the `fromIndex`.
6908      * _.lastIndexOf([1, 2, 1, 2], 2, 2);
6909      * // => 1
6910      */
6911     function lastIndexOf(array, value, fromIndex) {
6912       var length = array ? array.length : 0;
6913       if (!length) {
6914         return -1;
6915       }
6916       var index = length;
6917       if (fromIndex !== undefined) {
6918         index = toInteger(fromIndex);
6919         index = (
6920           index < 0
6921             ? nativeMax(length + index, 0)
6922             : nativeMin(index, length - 1)
6923         ) + 1;
6924       }
6925       if (value !== value) {
6926         return indexOfNaN(array, index - 1, true);
6927       }
6928       while (index--) {
6929         if (array[index] === value) {
6930           return index;
6931         }
6932       }
6933       return -1;
6934     }
6935
6936     /**
6937      * Gets the element at index `n` of `array`. If `n` is negative, the nth
6938      * element from the end is returned.
6939      *
6940      * @static
6941      * @memberOf _
6942      * @since 4.11.0
6943      * @category Array
6944      * @param {Array} array The array to query.
6945      * @param {number} [n=0] The index of the element to return.
6946      * @returns {*} Returns the nth element of `array`.
6947      * @example
6948      *
6949      * var array = ['a', 'b', 'c', 'd'];
6950      *
6951      * _.nth(array, 1);
6952      * // => 'b'
6953      *
6954      * _.nth(array, -2);
6955      * // => 'c';
6956      */
6957     function nth(array, n) {
6958       return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
6959     }
6960
6961     /**
6962      * Removes all given values from `array` using
6963      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
6964      * for equality comparisons.
6965      *
6966      * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
6967      * to remove elements from an array by predicate.
6968      *
6969      * @static
6970      * @memberOf _
6971      * @since 2.0.0
6972      * @category Array
6973      * @param {Array} array The array to modify.
6974      * @param {...*} [values] The values to remove.
6975      * @returns {Array} Returns `array`.
6976      * @example
6977      *
6978      * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
6979      *
6980      * _.pull(array, 'a', 'c');
6981      * console.log(array);
6982      * // => ['b', 'b']
6983      */
6984     var pull = rest(pullAll);
6985
6986     /**
6987      * This method is like `_.pull` except that it accepts an array of values to remove.
6988      *
6989      * **Note:** Unlike `_.difference`, this method mutates `array`.
6990      *
6991      * @static
6992      * @memberOf _
6993      * @since 4.0.0
6994      * @category Array
6995      * @param {Array} array The array to modify.
6996      * @param {Array} values The values to remove.
6997      * @returns {Array} Returns `array`.
6998      * @example
6999      *
7000      * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
7001      *
7002      * _.pullAll(array, ['a', 'c']);
7003      * console.log(array);
7004      * // => ['b', 'b']
7005      */
7006     function pullAll(array, values) {
7007       return (array && array.length && values && values.length)
7008         ? basePullAll(array, values)
7009         : array;
7010     }
7011
7012     /**
7013      * This method is like `_.pullAll` except that it accepts `iteratee` which is
7014      * invoked for each element of `array` and `values` to generate the criterion
7015      * by which they're compared. The iteratee is invoked with one argument: (value).
7016      *
7017      * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
7018      *
7019      * @static
7020      * @memberOf _
7021      * @since 4.0.0
7022      * @category Array
7023      * @param {Array} array The array to modify.
7024      * @param {Array} values The values to remove.
7025      * @param {Array|Function|Object|string} [iteratee=_.identity]
7026      *  The iteratee invoked per element.
7027      * @returns {Array} Returns `array`.
7028      * @example
7029      *
7030      * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
7031      *
7032      * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
7033      * console.log(array);
7034      * // => [{ 'x': 2 }]
7035      */
7036     function pullAllBy(array, values, iteratee) {
7037       return (array && array.length && values && values.length)
7038         ? basePullAll(array, values, getIteratee(iteratee))
7039         : array;
7040     }
7041
7042     /**
7043      * This method is like `_.pullAll` except that it accepts `comparator` which
7044      * is invoked to compare elements of `array` to `values`. The comparator is
7045      * invoked with two arguments: (arrVal, othVal).
7046      *
7047      * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
7048      *
7049      * @static
7050      * @memberOf _
7051      * @since 4.6.0
7052      * @category Array
7053      * @param {Array} array The array to modify.
7054      * @param {Array} values The values to remove.
7055      * @param {Function} [comparator] The comparator invoked per element.
7056      * @returns {Array} Returns `array`.
7057      * @example
7058      *
7059      * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
7060      *
7061      * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
7062      * console.log(array);
7063      * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
7064      */
7065     function pullAllWith(array, values, comparator) {
7066       return (array && array.length && values && values.length)
7067         ? basePullAll(array, values, undefined, comparator)
7068         : array;
7069     }
7070
7071     /**
7072      * Removes elements from `array` corresponding to `indexes` and returns an
7073      * array of removed elements.
7074      *
7075      * **Note:** Unlike `_.at`, this method mutates `array`.
7076      *
7077      * @static
7078      * @memberOf _
7079      * @since 3.0.0
7080      * @category Array
7081      * @param {Array} array The array to modify.
7082      * @param {...(number|number[])} [indexes] The indexes of elements to remove.
7083      * @returns {Array} Returns the new array of removed elements.
7084      * @example
7085      *
7086      * var array = ['a', 'b', 'c', 'd'];
7087      * var pulled = _.pullAt(array, [1, 3]);
7088      *
7089      * console.log(array);
7090      * // => ['a', 'c']
7091      *
7092      * console.log(pulled);
7093      * // => ['b', 'd']
7094      */
7095     var pullAt = rest(function(array, indexes) {
7096       indexes = baseFlatten(indexes, 1);
7097
7098       var length = array ? array.length : 0,
7099           result = baseAt(array, indexes);
7100
7101       basePullAt(array, arrayMap(indexes, function(index) {
7102         return isIndex(index, length) ? +index : index;
7103       }).sort(compareAscending));
7104
7105       return result;
7106     });
7107
7108     /**
7109      * Removes all elements from `array` that `predicate` returns truthy for
7110      * and returns an array of the removed elements. The predicate is invoked
7111      * with three arguments: (value, index, array).
7112      *
7113      * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
7114      * to pull elements from an array by value.
7115      *
7116      * @static
7117      * @memberOf _
7118      * @since 2.0.0
7119      * @category Array
7120      * @param {Array} array The array to modify.
7121      * @param {Array|Function|Object|string} [predicate=_.identity]
7122      *  The function invoked per iteration.
7123      * @returns {Array} Returns the new array of removed elements.
7124      * @example
7125      *
7126      * var array = [1, 2, 3, 4];
7127      * var evens = _.remove(array, function(n) {
7128      *   return n % 2 == 0;
7129      * });
7130      *
7131      * console.log(array);
7132      * // => [1, 3]
7133      *
7134      * console.log(evens);
7135      * // => [2, 4]
7136      */
7137     function remove(array, predicate) {
7138       var result = [];
7139       if (!(array && array.length)) {
7140         return result;
7141       }
7142       var index = -1,
7143           indexes = [],
7144           length = array.length;
7145
7146       predicate = getIteratee(predicate, 3);
7147       while (++index < length) {
7148         var value = array[index];
7149         if (predicate(value, index, array)) {
7150           result.push(value);
7151           indexes.push(index);
7152         }
7153       }
7154       basePullAt(array, indexes);
7155       return result;
7156     }
7157
7158     /**
7159      * Reverses `array` so that the first element becomes the last, the second
7160      * element becomes the second to last, and so on.
7161      *
7162      * **Note:** This method mutates `array` and is based on
7163      * [`Array#reverse`](https://mdn.io/Array/reverse).
7164      *
7165      * @static
7166      * @memberOf _
7167      * @since 4.0.0
7168      * @category Array
7169      * @param {Array} array The array to modify.
7170      * @returns {Array} Returns `array`.
7171      * @example
7172      *
7173      * var array = [1, 2, 3];
7174      *
7175      * _.reverse(array);
7176      * // => [3, 2, 1]
7177      *
7178      * console.log(array);
7179      * // => [3, 2, 1]
7180      */
7181     function reverse(array) {
7182       return array ? nativeReverse.call(array) : array;
7183     }
7184
7185     /**
7186      * Creates a slice of `array` from `start` up to, but not including, `end`.
7187      *
7188      * **Note:** This method is used instead of
7189      * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
7190      * returned.
7191      *
7192      * @static
7193      * @memberOf _
7194      * @since 3.0.0
7195      * @category Array
7196      * @param {Array} array The array to slice.
7197      * @param {number} [start=0] The start position.
7198      * @param {number} [end=array.length] The end position.
7199      * @returns {Array} Returns the slice of `array`.
7200      */
7201     function slice(array, start, end) {
7202       var length = array ? array.length : 0;
7203       if (!length) {
7204         return [];
7205       }
7206       if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
7207         start = 0;
7208         end = length;
7209       }
7210       else {
7211         start = start == null ? 0 : toInteger(start);
7212         end = end === undefined ? length : toInteger(end);
7213       }
7214       return baseSlice(array, start, end);
7215     }
7216
7217     /**
7218      * Uses a binary search to determine the lowest index at which `value`
7219      * should be inserted into `array` in order to maintain its sort order.
7220      *
7221      * @static
7222      * @memberOf _
7223      * @since 0.1.0
7224      * @category Array
7225      * @param {Array} array The sorted array to inspect.
7226      * @param {*} value The value to evaluate.
7227      * @returns {number} Returns the index at which `value` should be inserted
7228      *  into `array`.
7229      * @example
7230      *
7231      * _.sortedIndex([30, 50], 40);
7232      * // => 1
7233      */
7234     function sortedIndex(array, value) {
7235       return baseSortedIndex(array, value);
7236     }
7237
7238     /**
7239      * This method is like `_.sortedIndex` except that it accepts `iteratee`
7240      * which is invoked for `value` and each element of `array` to compute their
7241      * sort ranking. The iteratee is invoked with one argument: (value).
7242      *
7243      * @static
7244      * @memberOf _
7245      * @since 4.0.0
7246      * @category Array
7247      * @param {Array} array The sorted array to inspect.
7248      * @param {*} value The value to evaluate.
7249      * @param {Array|Function|Object|string} [iteratee=_.identity]
7250      *  The iteratee invoked per element.
7251      * @returns {number} Returns the index at which `value` should be inserted
7252      *  into `array`.
7253      * @example
7254      *
7255      * var objects = [{ 'x': 4 }, { 'x': 5 }];
7256      *
7257      * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
7258      * // => 0
7259      *
7260      * // The `_.property` iteratee shorthand.
7261      * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
7262      * // => 0
7263      */
7264     function sortedIndexBy(array, value, iteratee) {
7265       return baseSortedIndexBy(array, value, getIteratee(iteratee));
7266     }
7267
7268     /**
7269      * This method is like `_.indexOf` except that it performs a binary
7270      * search on a sorted `array`.
7271      *
7272      * @static
7273      * @memberOf _
7274      * @since 4.0.0
7275      * @category Array
7276      * @param {Array} array The array to search.
7277      * @param {*} value The value to search for.
7278      * @returns {number} Returns the index of the matched value, else `-1`.
7279      * @example
7280      *
7281      * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
7282      * // => 1
7283      */
7284     function sortedIndexOf(array, value) {
7285       var length = array ? array.length : 0;
7286       if (length) {
7287         var index = baseSortedIndex(array, value);
7288         if (index < length && eq(array[index], value)) {
7289           return index;
7290         }
7291       }
7292       return -1;
7293     }
7294
7295     /**
7296      * This method is like `_.sortedIndex` except that it returns the highest
7297      * index at which `value` should be inserted into `array` in order to
7298      * maintain its sort order.
7299      *
7300      * @static
7301      * @memberOf _
7302      * @since 3.0.0
7303      * @category Array
7304      * @param {Array} array The sorted array to inspect.
7305      * @param {*} value The value to evaluate.
7306      * @returns {number} Returns the index at which `value` should be inserted
7307      *  into `array`.
7308      * @example
7309      *
7310      * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
7311      * // => 4
7312      */
7313     function sortedLastIndex(array, value) {
7314       return baseSortedIndex(array, value, true);
7315     }
7316
7317     /**
7318      * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
7319      * which is invoked for `value` and each element of `array` to compute their
7320      * sort ranking. The iteratee is invoked with one argument: (value).
7321      *
7322      * @static
7323      * @memberOf _
7324      * @since 4.0.0
7325      * @category Array
7326      * @param {Array} array The sorted array to inspect.
7327      * @param {*} value The value to evaluate.
7328      * @param {Array|Function|Object|string} [iteratee=_.identity]
7329      *  The iteratee invoked per element.
7330      * @returns {number} Returns the index at which `value` should be inserted
7331      *  into `array`.
7332      * @example
7333      *
7334      * var objects = [{ 'x': 4 }, { 'x': 5 }];
7335      *
7336      * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
7337      * // => 1
7338      *
7339      * // The `_.property` iteratee shorthand.
7340      * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
7341      * // => 1
7342      */
7343     function sortedLastIndexBy(array, value, iteratee) {
7344       return baseSortedIndexBy(array, value, getIteratee(iteratee), true);
7345     }
7346
7347     /**
7348      * This method is like `_.lastIndexOf` except that it performs a binary
7349      * search on a sorted `array`.
7350      *
7351      * @static
7352      * @memberOf _
7353      * @since 4.0.0
7354      * @category Array
7355      * @param {Array} array The array to search.
7356      * @param {*} value The value to search for.
7357      * @returns {number} Returns the index of the matched value, else `-1`.
7358      * @example
7359      *
7360      * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
7361      * // => 3
7362      */
7363     function sortedLastIndexOf(array, value) {
7364       var length = array ? array.length : 0;
7365       if (length) {
7366         var index = baseSortedIndex(array, value, true) - 1;
7367         if (eq(array[index], value)) {
7368           return index;
7369         }
7370       }
7371       return -1;
7372     }
7373
7374     /**
7375      * This method is like `_.uniq` except that it's designed and optimized
7376      * for sorted arrays.
7377      *
7378      * @static
7379      * @memberOf _
7380      * @since 4.0.0
7381      * @category Array
7382      * @param {Array} array The array to inspect.
7383      * @returns {Array} Returns the new duplicate free array.
7384      * @example
7385      *
7386      * _.sortedUniq([1, 1, 2]);
7387      * // => [1, 2]
7388      */
7389     function sortedUniq(array) {
7390       return (array && array.length)
7391         ? baseSortedUniq(array)
7392         : [];
7393     }
7394
7395     /**
7396      * This method is like `_.uniqBy` except that it's designed and optimized
7397      * for sorted arrays.
7398      *
7399      * @static
7400      * @memberOf _
7401      * @since 4.0.0
7402      * @category Array
7403      * @param {Array} array The array to inspect.
7404      * @param {Function} [iteratee] The iteratee invoked per element.
7405      * @returns {Array} Returns the new duplicate free array.
7406      * @example
7407      *
7408      * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
7409      * // => [1.1, 2.3]
7410      */
7411     function sortedUniqBy(array, iteratee) {
7412       return (array && array.length)
7413         ? baseSortedUniq(array, getIteratee(iteratee))
7414         : [];
7415     }
7416
7417     /**
7418      * Gets all but the first element of `array`.
7419      *
7420      * @static
7421      * @memberOf _
7422      * @since 4.0.0
7423      * @category Array
7424      * @param {Array} array The array to query.
7425      * @returns {Array} Returns the slice of `array`.
7426      * @example
7427      *
7428      * _.tail([1, 2, 3]);
7429      * // => [2, 3]
7430      */
7431     function tail(array) {
7432       return drop(array, 1);
7433     }
7434
7435     /**
7436      * Creates a slice of `array` with `n` elements taken from the beginning.
7437      *
7438      * @static
7439      * @memberOf _
7440      * @since 0.1.0
7441      * @category Array
7442      * @param {Array} array The array to query.
7443      * @param {number} [n=1] The number of elements to take.
7444      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7445      * @returns {Array} Returns the slice of `array`.
7446      * @example
7447      *
7448      * _.take([1, 2, 3]);
7449      * // => [1]
7450      *
7451      * _.take([1, 2, 3], 2);
7452      * // => [1, 2]
7453      *
7454      * _.take([1, 2, 3], 5);
7455      * // => [1, 2, 3]
7456      *
7457      * _.take([1, 2, 3], 0);
7458      * // => []
7459      */
7460     function take(array, n, guard) {
7461       if (!(array && array.length)) {
7462         return [];
7463       }
7464       n = (guard || n === undefined) ? 1 : toInteger(n);
7465       return baseSlice(array, 0, n < 0 ? 0 : n);
7466     }
7467
7468     /**
7469      * Creates a slice of `array` with `n` elements taken from the end.
7470      *
7471      * @static
7472      * @memberOf _
7473      * @since 3.0.0
7474      * @category Array
7475      * @param {Array} array The array to query.
7476      * @param {number} [n=1] The number of elements to take.
7477      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
7478      * @returns {Array} Returns the slice of `array`.
7479      * @example
7480      *
7481      * _.takeRight([1, 2, 3]);
7482      * // => [3]
7483      *
7484      * _.takeRight([1, 2, 3], 2);
7485      * // => [2, 3]
7486      *
7487      * _.takeRight([1, 2, 3], 5);
7488      * // => [1, 2, 3]
7489      *
7490      * _.takeRight([1, 2, 3], 0);
7491      * // => []
7492      */
7493     function takeRight(array, n, guard) {
7494       var length = array ? array.length : 0;
7495       if (!length) {
7496         return [];
7497       }
7498       n = (guard || n === undefined) ? 1 : toInteger(n);
7499       n = length - n;
7500       return baseSlice(array, n < 0 ? 0 : n, length);
7501     }
7502
7503     /**
7504      * Creates a slice of `array` with elements taken from the end. Elements are
7505      * taken until `predicate` returns falsey. The predicate is invoked with
7506      * three arguments: (value, index, array).
7507      *
7508      * @static
7509      * @memberOf _
7510      * @since 3.0.0
7511      * @category Array
7512      * @param {Array} array The array to query.
7513      * @param {Array|Function|Object|string} [predicate=_.identity]
7514      *  The function invoked per iteration.
7515      * @returns {Array} Returns the slice of `array`.
7516      * @example
7517      *
7518      * var users = [
7519      *   { 'user': 'barney',  'active': true },
7520      *   { 'user': 'fred',    'active': false },
7521      *   { 'user': 'pebbles', 'active': false }
7522      * ];
7523      *
7524      * _.takeRightWhile(users, function(o) { return !o.active; });
7525      * // => objects for ['fred', 'pebbles']
7526      *
7527      * // The `_.matches` iteratee shorthand.
7528      * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
7529      * // => objects for ['pebbles']
7530      *
7531      * // The `_.matchesProperty` iteratee shorthand.
7532      * _.takeRightWhile(users, ['active', false]);
7533      * // => objects for ['fred', 'pebbles']
7534      *
7535      * // The `_.property` iteratee shorthand.
7536      * _.takeRightWhile(users, 'active');
7537      * // => []
7538      */
7539     function takeRightWhile(array, predicate) {
7540       return (array && array.length)
7541         ? baseWhile(array, getIteratee(predicate, 3), false, true)
7542         : [];
7543     }
7544
7545     /**
7546      * Creates a slice of `array` with elements taken from the beginning. Elements
7547      * are taken until `predicate` returns falsey. The predicate is invoked with
7548      * three arguments: (value, index, array).
7549      *
7550      * @static
7551      * @memberOf _
7552      * @since 3.0.0
7553      * @category Array
7554      * @param {Array} array The array to query.
7555      * @param {Array|Function|Object|string} [predicate=_.identity]
7556      *  The function invoked per iteration.
7557      * @returns {Array} Returns the slice of `array`.
7558      * @example
7559      *
7560      * var users = [
7561      *   { 'user': 'barney',  'active': false },
7562      *   { 'user': 'fred',    'active': false},
7563      *   { 'user': 'pebbles', 'active': true }
7564      * ];
7565      *
7566      * _.takeWhile(users, function(o) { return !o.active; });
7567      * // => objects for ['barney', 'fred']
7568      *
7569      * // The `_.matches` iteratee shorthand.
7570      * _.takeWhile(users, { 'user': 'barney', 'active': false });
7571      * // => objects for ['barney']
7572      *
7573      * // The `_.matchesProperty` iteratee shorthand.
7574      * _.takeWhile(users, ['active', false]);
7575      * // => objects for ['barney', 'fred']
7576      *
7577      * // The `_.property` iteratee shorthand.
7578      * _.takeWhile(users, 'active');
7579      * // => []
7580      */
7581     function takeWhile(array, predicate) {
7582       return (array && array.length)
7583         ? baseWhile(array, getIteratee(predicate, 3))
7584         : [];
7585     }
7586
7587     /**
7588      * Creates an array of unique values, in order, from all given arrays using
7589      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7590      * for equality comparisons.
7591      *
7592      * @static
7593      * @memberOf _
7594      * @since 0.1.0
7595      * @category Array
7596      * @param {...Array} [arrays] The arrays to inspect.
7597      * @returns {Array} Returns the new array of combined values.
7598      * @example
7599      *
7600      * _.union([2], [1, 2]);
7601      * // => [2, 1]
7602      */
7603     var union = rest(function(arrays) {
7604       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
7605     });
7606
7607     /**
7608      * This method is like `_.union` except that it accepts `iteratee` which is
7609      * invoked for each element of each `arrays` to generate the criterion by
7610      * which uniqueness is computed. The iteratee is invoked with one argument:
7611      * (value).
7612      *
7613      * @static
7614      * @memberOf _
7615      * @since 4.0.0
7616      * @category Array
7617      * @param {...Array} [arrays] The arrays to inspect.
7618      * @param {Array|Function|Object|string} [iteratee=_.identity]
7619      *  The iteratee invoked per element.
7620      * @returns {Array} Returns the new array of combined values.
7621      * @example
7622      *
7623      * _.unionBy([2.1], [1.2, 2.3], Math.floor);
7624      * // => [2.1, 1.2]
7625      *
7626      * // The `_.property` iteratee shorthand.
7627      * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7628      * // => [{ 'x': 1 }, { 'x': 2 }]
7629      */
7630     var unionBy = rest(function(arrays) {
7631       var iteratee = last(arrays);
7632       if (isArrayLikeObject(iteratee)) {
7633         iteratee = undefined;
7634       }
7635       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee));
7636     });
7637
7638     /**
7639      * This method is like `_.union` except that it accepts `comparator` which
7640      * is invoked to compare elements of `arrays`. The comparator is invoked
7641      * with two arguments: (arrVal, othVal).
7642      *
7643      * @static
7644      * @memberOf _
7645      * @since 4.0.0
7646      * @category Array
7647      * @param {...Array} [arrays] The arrays to inspect.
7648      * @param {Function} [comparator] The comparator invoked per element.
7649      * @returns {Array} Returns the new array of combined values.
7650      * @example
7651      *
7652      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7653      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7654      *
7655      * _.unionWith(objects, others, _.isEqual);
7656      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
7657      */
7658     var unionWith = rest(function(arrays) {
7659       var comparator = last(arrays);
7660       if (isArrayLikeObject(comparator)) {
7661         comparator = undefined;
7662       }
7663       return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
7664     });
7665
7666     /**
7667      * Creates a duplicate-free version of an array, using
7668      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7669      * for equality comparisons, in which only the first occurrence of each
7670      * element is kept.
7671      *
7672      * @static
7673      * @memberOf _
7674      * @since 0.1.0
7675      * @category Array
7676      * @param {Array} array The array to inspect.
7677      * @returns {Array} Returns the new duplicate free array.
7678      * @example
7679      *
7680      * _.uniq([2, 1, 2]);
7681      * // => [2, 1]
7682      */
7683     function uniq(array) {
7684       return (array && array.length)
7685         ? baseUniq(array)
7686         : [];
7687     }
7688
7689     /**
7690      * This method is like `_.uniq` except that it accepts `iteratee` which is
7691      * invoked for each element in `array` to generate the criterion by which
7692      * uniqueness is computed. The iteratee is invoked with one argument: (value).
7693      *
7694      * @static
7695      * @memberOf _
7696      * @since 4.0.0
7697      * @category Array
7698      * @param {Array} array The array to inspect.
7699      * @param {Array|Function|Object|string} [iteratee=_.identity]
7700      *  The iteratee invoked per element.
7701      * @returns {Array} Returns the new duplicate free array.
7702      * @example
7703      *
7704      * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
7705      * // => [2.1, 1.2]
7706      *
7707      * // The `_.property` iteratee shorthand.
7708      * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
7709      * // => [{ 'x': 1 }, { 'x': 2 }]
7710      */
7711     function uniqBy(array, iteratee) {
7712       return (array && array.length)
7713         ? baseUniq(array, getIteratee(iteratee))
7714         : [];
7715     }
7716
7717     /**
7718      * This method is like `_.uniq` except that it accepts `comparator` which
7719      * is invoked to compare elements of `array`. The comparator is invoked with
7720      * two arguments: (arrVal, othVal).
7721      *
7722      * @static
7723      * @memberOf _
7724      * @since 4.0.0
7725      * @category Array
7726      * @param {Array} array The array to inspect.
7727      * @param {Function} [comparator] The comparator invoked per element.
7728      * @returns {Array} Returns the new duplicate free array.
7729      * @example
7730      *
7731      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
7732      *
7733      * _.uniqWith(objects, _.isEqual);
7734      * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
7735      */
7736     function uniqWith(array, comparator) {
7737       return (array && array.length)
7738         ? baseUniq(array, undefined, comparator)
7739         : [];
7740     }
7741
7742     /**
7743      * This method is like `_.zip` except that it accepts an array of grouped
7744      * elements and creates an array regrouping the elements to their pre-zip
7745      * configuration.
7746      *
7747      * @static
7748      * @memberOf _
7749      * @since 1.2.0
7750      * @category Array
7751      * @param {Array} array The array of grouped elements to process.
7752      * @returns {Array} Returns the new array of regrouped elements.
7753      * @example
7754      *
7755      * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
7756      * // => [['fred', 30, true], ['barney', 40, false]]
7757      *
7758      * _.unzip(zipped);
7759      * // => [['fred', 'barney'], [30, 40], [true, false]]
7760      */
7761     function unzip(array) {
7762       if (!(array && array.length)) {
7763         return [];
7764       }
7765       var length = 0;
7766       array = arrayFilter(array, function(group) {
7767         if (isArrayLikeObject(group)) {
7768           length = nativeMax(group.length, length);
7769           return true;
7770         }
7771       });
7772       return baseTimes(length, function(index) {
7773         return arrayMap(array, baseProperty(index));
7774       });
7775     }
7776
7777     /**
7778      * This method is like `_.unzip` except that it accepts `iteratee` to specify
7779      * how regrouped values should be combined. The iteratee is invoked with the
7780      * elements of each group: (...group).
7781      *
7782      * @static
7783      * @memberOf _
7784      * @since 3.8.0
7785      * @category Array
7786      * @param {Array} array The array of grouped elements to process.
7787      * @param {Function} [iteratee=_.identity] The function to combine
7788      *  regrouped values.
7789      * @returns {Array} Returns the new array of regrouped elements.
7790      * @example
7791      *
7792      * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
7793      * // => [[1, 10, 100], [2, 20, 200]]
7794      *
7795      * _.unzipWith(zipped, _.add);
7796      * // => [3, 30, 300]
7797      */
7798     function unzipWith(array, iteratee) {
7799       if (!(array && array.length)) {
7800         return [];
7801       }
7802       var result = unzip(array);
7803       if (iteratee == null) {
7804         return result;
7805       }
7806       return arrayMap(result, function(group) {
7807         return apply(iteratee, undefined, group);
7808       });
7809     }
7810
7811     /**
7812      * Creates an array excluding all given values using
7813      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
7814      * for equality comparisons.
7815      *
7816      * @static
7817      * @memberOf _
7818      * @since 0.1.0
7819      * @category Array
7820      * @param {Array} array The array to inspect.
7821      * @param {...*} [values] The values to exclude.
7822      * @returns {Array} Returns the new array of filtered values.
7823      * @see _.difference, _.xor
7824      * @example
7825      *
7826      * _.without([2, 1, 2, 3], 1, 2);
7827      * // => [3]
7828      */
7829     var without = rest(function(array, values) {
7830       return isArrayLikeObject(array)
7831         ? baseDifference(array, values)
7832         : [];
7833     });
7834
7835     /**
7836      * Creates an array of unique values that is the
7837      * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
7838      * of the given arrays. The order of result values is determined by the order
7839      * they occur in the arrays.
7840      *
7841      * @static
7842      * @memberOf _
7843      * @since 2.4.0
7844      * @category Array
7845      * @param {...Array} [arrays] The arrays to inspect.
7846      * @returns {Array} Returns the new array of filtered values.
7847      * @see _.difference, _.without
7848      * @example
7849      *
7850      * _.xor([2, 1], [2, 3]);
7851      * // => [1, 3]
7852      */
7853     var xor = rest(function(arrays) {
7854       return baseXor(arrayFilter(arrays, isArrayLikeObject));
7855     });
7856
7857     /**
7858      * This method is like `_.xor` except that it accepts `iteratee` which is
7859      * invoked for each element of each `arrays` to generate the criterion by
7860      * which by which they're compared. The iteratee is invoked with one argument:
7861      * (value).
7862      *
7863      * @static
7864      * @memberOf _
7865      * @since 4.0.0
7866      * @category Array
7867      * @param {...Array} [arrays] The arrays to inspect.
7868      * @param {Array|Function|Object|string} [iteratee=_.identity]
7869      *  The iteratee invoked per element.
7870      * @returns {Array} Returns the new array of filtered values.
7871      * @example
7872      *
7873      * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
7874      * // => [1.2, 3.4]
7875      *
7876      * // The `_.property` iteratee shorthand.
7877      * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
7878      * // => [{ 'x': 2 }]
7879      */
7880     var xorBy = rest(function(arrays) {
7881       var iteratee = last(arrays);
7882       if (isArrayLikeObject(iteratee)) {
7883         iteratee = undefined;
7884       }
7885       return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
7886     });
7887
7888     /**
7889      * This method is like `_.xor` except that it accepts `comparator` which is
7890      * invoked to compare elements of `arrays`. The comparator is invoked with
7891      * two arguments: (arrVal, othVal).
7892      *
7893      * @static
7894      * @memberOf _
7895      * @since 4.0.0
7896      * @category Array
7897      * @param {...Array} [arrays] The arrays to inspect.
7898      * @param {Function} [comparator] The comparator invoked per element.
7899      * @returns {Array} Returns the new array of filtered values.
7900      * @example
7901      *
7902      * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
7903      * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
7904      *
7905      * _.xorWith(objects, others, _.isEqual);
7906      * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
7907      */
7908     var xorWith = rest(function(arrays) {
7909       var comparator = last(arrays);
7910       if (isArrayLikeObject(comparator)) {
7911         comparator = undefined;
7912       }
7913       return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
7914     });
7915
7916     /**
7917      * Creates an array of grouped elements, the first of which contains the
7918      * first elements of the given arrays, the second of which contains the
7919      * second elements of the given arrays, and so on.
7920      *
7921      * @static
7922      * @memberOf _
7923      * @since 0.1.0
7924      * @category Array
7925      * @param {...Array} [arrays] The arrays to process.
7926      * @returns {Array} Returns the new array of grouped elements.
7927      * @example
7928      *
7929      * _.zip(['fred', 'barney'], [30, 40], [true, false]);
7930      * // => [['fred', 30, true], ['barney', 40, false]]
7931      */
7932     var zip = rest(unzip);
7933
7934     /**
7935      * This method is like `_.fromPairs` except that it accepts two arrays,
7936      * one of property identifiers and one of corresponding values.
7937      *
7938      * @static
7939      * @memberOf _
7940      * @since 0.4.0
7941      * @category Array
7942      * @param {Array} [props=[]] The property identifiers.
7943      * @param {Array} [values=[]] The property values.
7944      * @returns {Object} Returns the new object.
7945      * @example
7946      *
7947      * _.zipObject(['a', 'b'], [1, 2]);
7948      * // => { 'a': 1, 'b': 2 }
7949      */
7950     function zipObject(props, values) {
7951       return baseZipObject(props || [], values || [], assignValue);
7952     }
7953
7954     /**
7955      * This method is like `_.zipObject` except that it supports property paths.
7956      *
7957      * @static
7958      * @memberOf _
7959      * @since 4.1.0
7960      * @category Array
7961      * @param {Array} [props=[]] The property identifiers.
7962      * @param {Array} [values=[]] The property values.
7963      * @returns {Object} Returns the new object.
7964      * @example
7965      *
7966      * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
7967      * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
7968      */
7969     function zipObjectDeep(props, values) {
7970       return baseZipObject(props || [], values || [], baseSet);
7971     }
7972
7973     /**
7974      * This method is like `_.zip` except that it accepts `iteratee` to specify
7975      * how grouped values should be combined. The iteratee is invoked with the
7976      * elements of each group: (...group).
7977      *
7978      * @static
7979      * @memberOf _
7980      * @since 3.8.0
7981      * @category Array
7982      * @param {...Array} [arrays] The arrays to process.
7983      * @param {Function} [iteratee=_.identity] The function to combine grouped values.
7984      * @returns {Array} Returns the new array of grouped elements.
7985      * @example
7986      *
7987      * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
7988      *   return a + b + c;
7989      * });
7990      * // => [111, 222]
7991      */
7992     var zipWith = rest(function(arrays) {
7993       var length = arrays.length,
7994           iteratee = length > 1 ? arrays[length - 1] : undefined;
7995
7996       iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
7997       return unzipWith(arrays, iteratee);
7998     });
7999
8000     /*------------------------------------------------------------------------*/
8001
8002     /**
8003      * Creates a `lodash` wrapper instance that wraps `value` with explicit method
8004      * chain sequences enabled. The result of such sequences must be unwrapped
8005      * with `_#value`.
8006      *
8007      * @static
8008      * @memberOf _
8009      * @since 1.3.0
8010      * @category Seq
8011      * @param {*} value The value to wrap.
8012      * @returns {Object} Returns the new `lodash` wrapper instance.
8013      * @example
8014      *
8015      * var users = [
8016      *   { 'user': 'barney',  'age': 36 },
8017      *   { 'user': 'fred',    'age': 40 },
8018      *   { 'user': 'pebbles', 'age': 1 }
8019      * ];
8020      *
8021      * var youngest = _
8022      *   .chain(users)
8023      *   .sortBy('age')
8024      *   .map(function(o) {
8025      *     return o.user + ' is ' + o.age;
8026      *   })
8027      *   .head()
8028      *   .value();
8029      * // => 'pebbles is 1'
8030      */
8031     function chain(value) {
8032       var result = lodash(value);
8033       result.__chain__ = true;
8034       return result;
8035     }
8036
8037     /**
8038      * This method invokes `interceptor` and returns `value`. The interceptor
8039      * is invoked with one argument; (value). The purpose of this method is to
8040      * "tap into" a method chain sequence in order to modify intermediate results.
8041      *
8042      * @static
8043      * @memberOf _
8044      * @since 0.1.0
8045      * @category Seq
8046      * @param {*} value The value to provide to `interceptor`.
8047      * @param {Function} interceptor The function to invoke.
8048      * @returns {*} Returns `value`.
8049      * @example
8050      *
8051      * _([1, 2, 3])
8052      *  .tap(function(array) {
8053      *    // Mutate input array.
8054      *    array.pop();
8055      *  })
8056      *  .reverse()
8057      *  .value();
8058      * // => [2, 1]
8059      */
8060     function tap(value, interceptor) {
8061       interceptor(value);
8062       return value;
8063     }
8064
8065     /**
8066      * This method is like `_.tap` except that it returns the result of `interceptor`.
8067      * The purpose of this method is to "pass thru" values replacing intermediate
8068      * results in a method chain sequence.
8069      *
8070      * @static
8071      * @memberOf _
8072      * @since 3.0.0
8073      * @category Seq
8074      * @param {*} value The value to provide to `interceptor`.
8075      * @param {Function} interceptor The function to invoke.
8076      * @returns {*} Returns the result of `interceptor`.
8077      * @example
8078      *
8079      * _('  abc  ')
8080      *  .chain()
8081      *  .trim()
8082      *  .thru(function(value) {
8083      *    return [value];
8084      *  })
8085      *  .value();
8086      * // => ['abc']
8087      */
8088     function thru(value, interceptor) {
8089       return interceptor(value);
8090     }
8091
8092     /**
8093      * This method is the wrapper version of `_.at`.
8094      *
8095      * @name at
8096      * @memberOf _
8097      * @since 1.0.0
8098      * @category Seq
8099      * @param {...(string|string[])} [paths] The property paths of elements to pick.
8100      * @returns {Object} Returns the new `lodash` wrapper instance.
8101      * @example
8102      *
8103      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
8104      *
8105      * _(object).at(['a[0].b.c', 'a[1]']).value();
8106      * // => [3, 4]
8107      */
8108     var wrapperAt = rest(function(paths) {
8109       paths = baseFlatten(paths, 1);
8110       var length = paths.length,
8111           start = length ? paths[0] : 0,
8112           value = this.__wrapped__,
8113           interceptor = function(object) { return baseAt(object, paths); };
8114
8115       if (length > 1 || this.__actions__.length ||
8116           !(value instanceof LazyWrapper) || !isIndex(start)) {
8117         return this.thru(interceptor);
8118       }
8119       value = value.slice(start, +start + (length ? 1 : 0));
8120       value.__actions__.push({
8121         'func': thru,
8122         'args': [interceptor],
8123         'thisArg': undefined
8124       });
8125       return new LodashWrapper(value, this.__chain__).thru(function(array) {
8126         if (length && !array.length) {
8127           array.push(undefined);
8128         }
8129         return array;
8130       });
8131     });
8132
8133     /**
8134      * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
8135      *
8136      * @name chain
8137      * @memberOf _
8138      * @since 0.1.0
8139      * @category Seq
8140      * @returns {Object} Returns the new `lodash` wrapper instance.
8141      * @example
8142      *
8143      * var users = [
8144      *   { 'user': 'barney', 'age': 36 },
8145      *   { 'user': 'fred',   'age': 40 }
8146      * ];
8147      *
8148      * // A sequence without explicit chaining.
8149      * _(users).head();
8150      * // => { 'user': 'barney', 'age': 36 }
8151      *
8152      * // A sequence with explicit chaining.
8153      * _(users)
8154      *   .chain()
8155      *   .head()
8156      *   .pick('user')
8157      *   .value();
8158      * // => { 'user': 'barney' }
8159      */
8160     function wrapperChain() {
8161       return chain(this);
8162     }
8163
8164     /**
8165      * Executes the chain sequence and returns the wrapped result.
8166      *
8167      * @name commit
8168      * @memberOf _
8169      * @since 3.2.0
8170      * @category Seq
8171      * @returns {Object} Returns the new `lodash` wrapper instance.
8172      * @example
8173      *
8174      * var array = [1, 2];
8175      * var wrapped = _(array).push(3);
8176      *
8177      * console.log(array);
8178      * // => [1, 2]
8179      *
8180      * wrapped = wrapped.commit();
8181      * console.log(array);
8182      * // => [1, 2, 3]
8183      *
8184      * wrapped.last();
8185      * // => 3
8186      *
8187      * console.log(array);
8188      * // => [1, 2, 3]
8189      */
8190     function wrapperCommit() {
8191       return new LodashWrapper(this.value(), this.__chain__);
8192     }
8193
8194     /**
8195      * Gets the next value on a wrapped object following the
8196      * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
8197      *
8198      * @name next
8199      * @memberOf _
8200      * @since 4.0.0
8201      * @category Seq
8202      * @returns {Object} Returns the next iterator value.
8203      * @example
8204      *
8205      * var wrapped = _([1, 2]);
8206      *
8207      * wrapped.next();
8208      * // => { 'done': false, 'value': 1 }
8209      *
8210      * wrapped.next();
8211      * // => { 'done': false, 'value': 2 }
8212      *
8213      * wrapped.next();
8214      * // => { 'done': true, 'value': undefined }
8215      */
8216     function wrapperNext() {
8217       if (this.__values__ === undefined) {
8218         this.__values__ = toArray(this.value());
8219       }
8220       var done = this.__index__ >= this.__values__.length,
8221           value = done ? undefined : this.__values__[this.__index__++];
8222
8223       return { 'done': done, 'value': value };
8224     }
8225
8226     /**
8227      * Enables the wrapper to be iterable.
8228      *
8229      * @name Symbol.iterator
8230      * @memberOf _
8231      * @since 4.0.0
8232      * @category Seq
8233      * @returns {Object} Returns the wrapper object.
8234      * @example
8235      *
8236      * var wrapped = _([1, 2]);
8237      *
8238      * wrapped[Symbol.iterator]() === wrapped;
8239      * // => true
8240      *
8241      * Array.from(wrapped);
8242      * // => [1, 2]
8243      */
8244     function wrapperToIterator() {
8245       return this;
8246     }
8247
8248     /**
8249      * Creates a clone of the chain sequence planting `value` as the wrapped value.
8250      *
8251      * @name plant
8252      * @memberOf _
8253      * @since 3.2.0
8254      * @category Seq
8255      * @param {*} value The value to plant.
8256      * @returns {Object} Returns the new `lodash` wrapper instance.
8257      * @example
8258      *
8259      * function square(n) {
8260      *   return n * n;
8261      * }
8262      *
8263      * var wrapped = _([1, 2]).map(square);
8264      * var other = wrapped.plant([3, 4]);
8265      *
8266      * other.value();
8267      * // => [9, 16]
8268      *
8269      * wrapped.value();
8270      * // => [1, 4]
8271      */
8272     function wrapperPlant(value) {
8273       var result,
8274           parent = this;
8275
8276       while (parent instanceof baseLodash) {
8277         var clone = wrapperClone(parent);
8278         clone.__index__ = 0;
8279         clone.__values__ = undefined;
8280         if (result) {
8281           previous.__wrapped__ = clone;
8282         } else {
8283           result = clone;
8284         }
8285         var previous = clone;
8286         parent = parent.__wrapped__;
8287       }
8288       previous.__wrapped__ = value;
8289       return result;
8290     }
8291
8292     /**
8293      * This method is the wrapper version of `_.reverse`.
8294      *
8295      * **Note:** This method mutates the wrapped array.
8296      *
8297      * @name reverse
8298      * @memberOf _
8299      * @since 0.1.0
8300      * @category Seq
8301      * @returns {Object} Returns the new `lodash` wrapper instance.
8302      * @example
8303      *
8304      * var array = [1, 2, 3];
8305      *
8306      * _(array).reverse().value()
8307      * // => [3, 2, 1]
8308      *
8309      * console.log(array);
8310      * // => [3, 2, 1]
8311      */
8312     function wrapperReverse() {
8313       var value = this.__wrapped__;
8314       if (value instanceof LazyWrapper) {
8315         var wrapped = value;
8316         if (this.__actions__.length) {
8317           wrapped = new LazyWrapper(this);
8318         }
8319         wrapped = wrapped.reverse();
8320         wrapped.__actions__.push({
8321           'func': thru,
8322           'args': [reverse],
8323           'thisArg': undefined
8324         });
8325         return new LodashWrapper(wrapped, this.__chain__);
8326       }
8327       return this.thru(reverse);
8328     }
8329
8330     /**
8331      * Executes the chain sequence to resolve the unwrapped value.
8332      *
8333      * @name value
8334      * @memberOf _
8335      * @since 0.1.0
8336      * @alias toJSON, valueOf
8337      * @category Seq
8338      * @returns {*} Returns the resolved unwrapped value.
8339      * @example
8340      *
8341      * _([1, 2, 3]).value();
8342      * // => [1, 2, 3]
8343      */
8344     function wrapperValue() {
8345       return baseWrapperValue(this.__wrapped__, this.__actions__);
8346     }
8347
8348     /*------------------------------------------------------------------------*/
8349
8350     /**
8351      * Creates an object composed of keys generated from the results of running
8352      * each element of `collection` thru `iteratee`. The corresponding value of
8353      * each key is the number of times the key was returned by `iteratee`. The
8354      * iteratee is invoked with one argument: (value).
8355      *
8356      * @static
8357      * @memberOf _
8358      * @since 0.5.0
8359      * @category Collection
8360      * @param {Array|Object} collection The collection to iterate over.
8361      * @param {Array|Function|Object|string} [iteratee=_.identity]
8362      *  The iteratee to transform keys.
8363      * @returns {Object} Returns the composed aggregate object.
8364      * @example
8365      *
8366      * _.countBy([6.1, 4.2, 6.3], Math.floor);
8367      * // => { '4': 1, '6': 2 }
8368      *
8369      * // The `_.property` iteratee shorthand.
8370      * _.countBy(['one', 'two', 'three'], 'length');
8371      * // => { '3': 2, '5': 1 }
8372      */
8373     var countBy = createAggregator(function(result, value, key) {
8374       hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1);
8375     });
8376
8377     /**
8378      * Checks if `predicate` returns truthy for **all** elements of `collection`.
8379      * Iteration is stopped once `predicate` returns falsey. The predicate is
8380      * invoked with three arguments: (value, index|key, collection).
8381      *
8382      * @static
8383      * @memberOf _
8384      * @since 0.1.0
8385      * @category Collection
8386      * @param {Array|Object} collection The collection to iterate over.
8387      * @param {Array|Function|Object|string} [predicate=_.identity]
8388      *  The function invoked per iteration.
8389      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
8390      * @returns {boolean} Returns `true` if all elements pass the predicate check,
8391      *  else `false`.
8392      * @example
8393      *
8394      * _.every([true, 1, null, 'yes'], Boolean);
8395      * // => false
8396      *
8397      * var users = [
8398      *   { 'user': 'barney', 'age': 36, 'active': false },
8399      *   { 'user': 'fred',   'age': 40, 'active': false }
8400      * ];
8401      *
8402      * // The `_.matches` iteratee shorthand.
8403      * _.every(users, { 'user': 'barney', 'active': false });
8404      * // => false
8405      *
8406      * // The `_.matchesProperty` iteratee shorthand.
8407      * _.every(users, ['active', false]);
8408      * // => true
8409      *
8410      * // The `_.property` iteratee shorthand.
8411      * _.every(users, 'active');
8412      * // => false
8413      */
8414     function every(collection, predicate, guard) {
8415       var func = isArray(collection) ? arrayEvery : baseEvery;
8416       if (guard && isIterateeCall(collection, predicate, guard)) {
8417         predicate = undefined;
8418       }
8419       return func(collection, getIteratee(predicate, 3));
8420     }
8421
8422     /**
8423      * Iterates over elements of `collection`, returning an array of all elements
8424      * `predicate` returns truthy for. The predicate is invoked with three
8425      * arguments: (value, index|key, collection).
8426      *
8427      * @static
8428      * @memberOf _
8429      * @since 0.1.0
8430      * @category Collection
8431      * @param {Array|Object} collection The collection to iterate over.
8432      * @param {Array|Function|Object|string} [predicate=_.identity]
8433      *  The function invoked per iteration.
8434      * @returns {Array} Returns the new filtered array.
8435      * @see _.reject
8436      * @example
8437      *
8438      * var users = [
8439      *   { 'user': 'barney', 'age': 36, 'active': true },
8440      *   { 'user': 'fred',   'age': 40, 'active': false }
8441      * ];
8442      *
8443      * _.filter(users, function(o) { return !o.active; });
8444      * // => objects for ['fred']
8445      *
8446      * // The `_.matches` iteratee shorthand.
8447      * _.filter(users, { 'age': 36, 'active': true });
8448      * // => objects for ['barney']
8449      *
8450      * // The `_.matchesProperty` iteratee shorthand.
8451      * _.filter(users, ['active', false]);
8452      * // => objects for ['fred']
8453      *
8454      * // The `_.property` iteratee shorthand.
8455      * _.filter(users, 'active');
8456      * // => objects for ['barney']
8457      */
8458     function filter(collection, predicate) {
8459       var func = isArray(collection) ? arrayFilter : baseFilter;
8460       return func(collection, getIteratee(predicate, 3));
8461     }
8462
8463     /**
8464      * Iterates over elements of `collection`, returning the first element
8465      * `predicate` returns truthy for. The predicate is invoked with three
8466      * arguments: (value, index|key, collection).
8467      *
8468      * @static
8469      * @memberOf _
8470      * @since 0.1.0
8471      * @category Collection
8472      * @param {Array|Object} collection The collection to search.
8473      * @param {Array|Function|Object|string} [predicate=_.identity]
8474      *  The function invoked per iteration.
8475      * @param {number} [fromIndex=0] The index to search from.
8476      * @returns {*} Returns the matched element, else `undefined`.
8477      * @example
8478      *
8479      * var users = [
8480      *   { 'user': 'barney',  'age': 36, 'active': true },
8481      *   { 'user': 'fred',    'age': 40, 'active': false },
8482      *   { 'user': 'pebbles', 'age': 1,  'active': true }
8483      * ];
8484      *
8485      * _.find(users, function(o) { return o.age < 40; });
8486      * // => object for 'barney'
8487      *
8488      * // The `_.matches` iteratee shorthand.
8489      * _.find(users, { 'age': 1, 'active': true });
8490      * // => object for 'pebbles'
8491      *
8492      * // The `_.matchesProperty` iteratee shorthand.
8493      * _.find(users, ['active', false]);
8494      * // => object for 'fred'
8495      *
8496      * // The `_.property` iteratee shorthand.
8497      * _.find(users, 'active');
8498      * // => object for 'barney'
8499      */
8500     var find = createFind(findIndex);
8501
8502     /**
8503      * This method is like `_.find` except that it iterates over elements of
8504      * `collection` from right to left.
8505      *
8506      * @static
8507      * @memberOf _
8508      * @since 2.0.0
8509      * @category Collection
8510      * @param {Array|Object} collection The collection to search.
8511      * @param {Array|Function|Object|string} [predicate=_.identity]
8512      *  The function invoked per iteration.
8513      * @param {number} [fromIndex=collection.length-1] The index to search from.
8514      * @returns {*} Returns the matched element, else `undefined`.
8515      * @example
8516      *
8517      * _.findLast([1, 2, 3, 4], function(n) {
8518      *   return n % 2 == 1;
8519      * });
8520      * // => 3
8521      */
8522     var findLast = createFind(findLastIndex);
8523
8524     /**
8525      * Creates a flattened array of values by running each element in `collection`
8526      * thru `iteratee` and flattening the mapped results. The iteratee is invoked
8527      * with three arguments: (value, index|key, collection).
8528      *
8529      * @static
8530      * @memberOf _
8531      * @since 4.0.0
8532      * @category Collection
8533      * @param {Array|Object} collection The collection to iterate over.
8534      * @param {Array|Function|Object|string} [iteratee=_.identity]
8535      *  The function invoked per iteration.
8536      * @returns {Array} Returns the new flattened array.
8537      * @example
8538      *
8539      * function duplicate(n) {
8540      *   return [n, n];
8541      * }
8542      *
8543      * _.flatMap([1, 2], duplicate);
8544      * // => [1, 1, 2, 2]
8545      */
8546     function flatMap(collection, iteratee) {
8547       return baseFlatten(map(collection, iteratee), 1);
8548     }
8549
8550     /**
8551      * This method is like `_.flatMap` except that it recursively flattens the
8552      * mapped results.
8553      *
8554      * @static
8555      * @memberOf _
8556      * @since 4.7.0
8557      * @category Collection
8558      * @param {Array|Object} collection The collection to iterate over.
8559      * @param {Array|Function|Object|string} [iteratee=_.identity]
8560      *  The function invoked per iteration.
8561      * @returns {Array} Returns the new flattened array.
8562      * @example
8563      *
8564      * function duplicate(n) {
8565      *   return [[[n, n]]];
8566      * }
8567      *
8568      * _.flatMapDeep([1, 2], duplicate);
8569      * // => [1, 1, 2, 2]
8570      */
8571     function flatMapDeep(collection, iteratee) {
8572       return baseFlatten(map(collection, iteratee), INFINITY);
8573     }
8574
8575     /**
8576      * This method is like `_.flatMap` except that it recursively flattens the
8577      * mapped results up to `depth` times.
8578      *
8579      * @static
8580      * @memberOf _
8581      * @since 4.7.0
8582      * @category Collection
8583      * @param {Array|Object} collection The collection to iterate over.
8584      * @param {Array|Function|Object|string} [iteratee=_.identity]
8585      *  The function invoked per iteration.
8586      * @param {number} [depth=1] The maximum recursion depth.
8587      * @returns {Array} Returns the new flattened array.
8588      * @example
8589      *
8590      * function duplicate(n) {
8591      *   return [[[n, n]]];
8592      * }
8593      *
8594      * _.flatMapDepth([1, 2], duplicate, 2);
8595      * // => [[1, 1], [2, 2]]
8596      */
8597     function flatMapDepth(collection, iteratee, depth) {
8598       depth = depth === undefined ? 1 : toInteger(depth);
8599       return baseFlatten(map(collection, iteratee), depth);
8600     }
8601
8602     /**
8603      * Iterates over elements of `collection` and invokes `iteratee` for each element.
8604      * The iteratee is invoked with three arguments: (value, index|key, collection).
8605      * Iteratee functions may exit iteration early by explicitly returning `false`.
8606      *
8607      * **Note:** As with other "Collections" methods, objects with a "length"
8608      * property are iterated like arrays. To avoid this behavior use `_.forIn`
8609      * or `_.forOwn` for object iteration.
8610      *
8611      * @static
8612      * @memberOf _
8613      * @since 0.1.0
8614      * @alias each
8615      * @category Collection
8616      * @param {Array|Object} collection The collection to iterate over.
8617      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8618      * @returns {Array|Object} Returns `collection`.
8619      * @see _.forEachRight
8620      * @example
8621      *
8622      * _([1, 2]).forEach(function(value) {
8623      *   console.log(value);
8624      * });
8625      * // => Logs `1` then `2`.
8626      *
8627      * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
8628      *   console.log(key);
8629      * });
8630      * // => Logs 'a' then 'b' (iteration order is not guaranteed).
8631      */
8632     function forEach(collection, iteratee) {
8633       var func = isArray(collection) ? arrayEach : baseEach;
8634       return func(collection, getIteratee(iteratee, 3));
8635     }
8636
8637     /**
8638      * This method is like `_.forEach` except that it iterates over elements of
8639      * `collection` from right to left.
8640      *
8641      * @static
8642      * @memberOf _
8643      * @since 2.0.0
8644      * @alias eachRight
8645      * @category Collection
8646      * @param {Array|Object} collection The collection to iterate over.
8647      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8648      * @returns {Array|Object} Returns `collection`.
8649      * @see _.forEach
8650      * @example
8651      *
8652      * _.forEachRight([1, 2], function(value) {
8653      *   console.log(value);
8654      * });
8655      * // => Logs `2` then `1`.
8656      */
8657     function forEachRight(collection, iteratee) {
8658       var func = isArray(collection) ? arrayEachRight : baseEachRight;
8659       return func(collection, getIteratee(iteratee, 3));
8660     }
8661
8662     /**
8663      * Creates an object composed of keys generated from the results of running
8664      * each element of `collection` thru `iteratee`. The order of grouped values
8665      * is determined by the order they occur in `collection`. The corresponding
8666      * value of each key is an array of elements responsible for generating the
8667      * key. The iteratee is invoked with one argument: (value).
8668      *
8669      * @static
8670      * @memberOf _
8671      * @since 0.1.0
8672      * @category Collection
8673      * @param {Array|Object} collection The collection to iterate over.
8674      * @param {Array|Function|Object|string} [iteratee=_.identity]
8675      *  The iteratee to transform keys.
8676      * @returns {Object} Returns the composed aggregate object.
8677      * @example
8678      *
8679      * _.groupBy([6.1, 4.2, 6.3], Math.floor);
8680      * // => { '4': [4.2], '6': [6.1, 6.3] }
8681      *
8682      * // The `_.property` iteratee shorthand.
8683      * _.groupBy(['one', 'two', 'three'], 'length');
8684      * // => { '3': ['one', 'two'], '5': ['three'] }
8685      */
8686     var groupBy = createAggregator(function(result, value, key) {
8687       if (hasOwnProperty.call(result, key)) {
8688         result[key].push(value);
8689       } else {
8690         result[key] = [value];
8691       }
8692     });
8693
8694     /**
8695      * Checks if `value` is in `collection`. If `collection` is a string, it's
8696      * checked for a substring of `value`, otherwise
8697      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
8698      * is used for equality comparisons. If `fromIndex` is negative, it's used as
8699      * the offset from the end of `collection`.
8700      *
8701      * @static
8702      * @memberOf _
8703      * @since 0.1.0
8704      * @category Collection
8705      * @param {Array|Object|string} collection The collection to search.
8706      * @param {*} value The value to search for.
8707      * @param {number} [fromIndex=0] The index to search from.
8708      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
8709      * @returns {boolean} Returns `true` if `value` is found, else `false`.
8710      * @example
8711      *
8712      * _.includes([1, 2, 3], 1);
8713      * // => true
8714      *
8715      * _.includes([1, 2, 3], 1, 2);
8716      * // => false
8717      *
8718      * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
8719      * // => true
8720      *
8721      * _.includes('pebbles', 'eb');
8722      * // => true
8723      */
8724     function includes(collection, value, fromIndex, guard) {
8725       collection = isArrayLike(collection) ? collection : values(collection);
8726       fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
8727
8728       var length = collection.length;
8729       if (fromIndex < 0) {
8730         fromIndex = nativeMax(length + fromIndex, 0);
8731       }
8732       return isString(collection)
8733         ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
8734         : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
8735     }
8736
8737     /**
8738      * Invokes the method at `path` of each element in `collection`, returning
8739      * an array of the results of each invoked method. Any additional arguments
8740      * are provided to each invoked method. If `methodName` is a function, it's
8741      * invoked for and `this` bound to, each element in `collection`.
8742      *
8743      * @static
8744      * @memberOf _
8745      * @since 4.0.0
8746      * @category Collection
8747      * @param {Array|Object} collection The collection to iterate over.
8748      * @param {Array|Function|string} path The path of the method to invoke or
8749      *  the function invoked per iteration.
8750      * @param {...*} [args] The arguments to invoke each method with.
8751      * @returns {Array} Returns the array of results.
8752      * @example
8753      *
8754      * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
8755      * // => [[1, 5, 7], [1, 2, 3]]
8756      *
8757      * _.invokeMap([123, 456], String.prototype.split, '');
8758      * // => [['1', '2', '3'], ['4', '5', '6']]
8759      */
8760     var invokeMap = rest(function(collection, path, args) {
8761       var index = -1,
8762           isFunc = typeof path == 'function',
8763           isProp = isKey(path),
8764           result = isArrayLike(collection) ? Array(collection.length) : [];
8765
8766       baseEach(collection, function(value) {
8767         var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
8768         result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
8769       });
8770       return result;
8771     });
8772
8773     /**
8774      * Creates an object composed of keys generated from the results of running
8775      * each element of `collection` thru `iteratee`. The corresponding value of
8776      * each key is the last element responsible for generating the key. The
8777      * iteratee is invoked with one argument: (value).
8778      *
8779      * @static
8780      * @memberOf _
8781      * @since 4.0.0
8782      * @category Collection
8783      * @param {Array|Object} collection The collection to iterate over.
8784      * @param {Array|Function|Object|string} [iteratee=_.identity]
8785      *  The iteratee to transform keys.
8786      * @returns {Object} Returns the composed aggregate object.
8787      * @example
8788      *
8789      * var array = [
8790      *   { 'dir': 'left', 'code': 97 },
8791      *   { 'dir': 'right', 'code': 100 }
8792      * ];
8793      *
8794      * _.keyBy(array, function(o) {
8795      *   return String.fromCharCode(o.code);
8796      * });
8797      * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
8798      *
8799      * _.keyBy(array, 'dir');
8800      * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
8801      */
8802     var keyBy = createAggregator(function(result, value, key) {
8803       result[key] = value;
8804     });
8805
8806     /**
8807      * Creates an array of values by running each element in `collection` thru
8808      * `iteratee`. The iteratee is invoked with three arguments:
8809      * (value, index|key, collection).
8810      *
8811      * Many lodash methods are guarded to work as iteratees for methods like
8812      * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
8813      *
8814      * The guarded methods are:
8815      * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
8816      * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
8817      * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
8818      * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
8819      *
8820      * @static
8821      * @memberOf _
8822      * @since 0.1.0
8823      * @category Collection
8824      * @param {Array|Object} collection The collection to iterate over.
8825      * @param {Array|Function|Object|string} [iteratee=_.identity]
8826      *  The function invoked per iteration.
8827      * @returns {Array} Returns the new mapped array.
8828      * @example
8829      *
8830      * function square(n) {
8831      *   return n * n;
8832      * }
8833      *
8834      * _.map([4, 8], square);
8835      * // => [16, 64]
8836      *
8837      * _.map({ 'a': 4, 'b': 8 }, square);
8838      * // => [16, 64] (iteration order is not guaranteed)
8839      *
8840      * var users = [
8841      *   { 'user': 'barney' },
8842      *   { 'user': 'fred' }
8843      * ];
8844      *
8845      * // The `_.property` iteratee shorthand.
8846      * _.map(users, 'user');
8847      * // => ['barney', 'fred']
8848      */
8849     function map(collection, iteratee) {
8850       var func = isArray(collection) ? arrayMap : baseMap;
8851       return func(collection, getIteratee(iteratee, 3));
8852     }
8853
8854     /**
8855      * This method is like `_.sortBy` except that it allows specifying the sort
8856      * orders of the iteratees to sort by. If `orders` is unspecified, all values
8857      * are sorted in ascending order. Otherwise, specify an order of "desc" for
8858      * descending or "asc" for ascending sort order of corresponding values.
8859      *
8860      * @static
8861      * @memberOf _
8862      * @since 4.0.0
8863      * @category Collection
8864      * @param {Array|Object} collection The collection to iterate over.
8865      * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
8866      *  The iteratees to sort by.
8867      * @param {string[]} [orders] The sort orders of `iteratees`.
8868      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
8869      * @returns {Array} Returns the new sorted array.
8870      * @example
8871      *
8872      * var users = [
8873      *   { 'user': 'fred',   'age': 48 },
8874      *   { 'user': 'barney', 'age': 34 },
8875      *   { 'user': 'fred',   'age': 40 },
8876      *   { 'user': 'barney', 'age': 36 }
8877      * ];
8878      *
8879      * // Sort by `user` in ascending order and by `age` in descending order.
8880      * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
8881      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
8882      */
8883     function orderBy(collection, iteratees, orders, guard) {
8884       if (collection == null) {
8885         return [];
8886       }
8887       if (!isArray(iteratees)) {
8888         iteratees = iteratees == null ? [] : [iteratees];
8889       }
8890       orders = guard ? undefined : orders;
8891       if (!isArray(orders)) {
8892         orders = orders == null ? [] : [orders];
8893       }
8894       return baseOrderBy(collection, iteratees, orders);
8895     }
8896
8897     /**
8898      * Creates an array of elements split into two groups, the first of which
8899      * contains elements `predicate` returns truthy for, the second of which
8900      * contains elements `predicate` returns falsey for. The predicate is
8901      * invoked with one argument: (value).
8902      *
8903      * @static
8904      * @memberOf _
8905      * @since 3.0.0
8906      * @category Collection
8907      * @param {Array|Object} collection The collection to iterate over.
8908      * @param {Array|Function|Object|string} [predicate=_.identity]
8909      *  The function invoked per iteration.
8910      * @returns {Array} Returns the array of grouped elements.
8911      * @example
8912      *
8913      * var users = [
8914      *   { 'user': 'barney',  'age': 36, 'active': false },
8915      *   { 'user': 'fred',    'age': 40, 'active': true },
8916      *   { 'user': 'pebbles', 'age': 1,  'active': false }
8917      * ];
8918      *
8919      * _.partition(users, function(o) { return o.active; });
8920      * // => objects for [['fred'], ['barney', 'pebbles']]
8921      *
8922      * // The `_.matches` iteratee shorthand.
8923      * _.partition(users, { 'age': 1, 'active': false });
8924      * // => objects for [['pebbles'], ['barney', 'fred']]
8925      *
8926      * // The `_.matchesProperty` iteratee shorthand.
8927      * _.partition(users, ['active', false]);
8928      * // => objects for [['barney', 'pebbles'], ['fred']]
8929      *
8930      * // The `_.property` iteratee shorthand.
8931      * _.partition(users, 'active');
8932      * // => objects for [['fred'], ['barney', 'pebbles']]
8933      */
8934     var partition = createAggregator(function(result, value, key) {
8935       result[key ? 0 : 1].push(value);
8936     }, function() { return [[], []]; });
8937
8938     /**
8939      * Reduces `collection` to a value which is the accumulated result of running
8940      * each element in `collection` thru `iteratee`, where each successive
8941      * invocation is supplied the return value of the previous. If `accumulator`
8942      * is not given, the first element of `collection` is used as the initial
8943      * value. The iteratee is invoked with four arguments:
8944      * (accumulator, value, index|key, collection).
8945      *
8946      * Many lodash methods are guarded to work as iteratees for methods like
8947      * `_.reduce`, `_.reduceRight`, and `_.transform`.
8948      *
8949      * The guarded methods are:
8950      * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
8951      * and `sortBy`
8952      *
8953      * @static
8954      * @memberOf _
8955      * @since 0.1.0
8956      * @category Collection
8957      * @param {Array|Object} collection The collection to iterate over.
8958      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8959      * @param {*} [accumulator] The initial value.
8960      * @returns {*} Returns the accumulated value.
8961      * @see _.reduceRight
8962      * @example
8963      *
8964      * _.reduce([1, 2], function(sum, n) {
8965      *   return sum + n;
8966      * }, 0);
8967      * // => 3
8968      *
8969      * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
8970      *   (result[value] || (result[value] = [])).push(key);
8971      *   return result;
8972      * }, {});
8973      * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
8974      */
8975     function reduce(collection, iteratee, accumulator) {
8976       var func = isArray(collection) ? arrayReduce : baseReduce,
8977           initAccum = arguments.length < 3;
8978
8979       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
8980     }
8981
8982     /**
8983      * This method is like `_.reduce` except that it iterates over elements of
8984      * `collection` from right to left.
8985      *
8986      * @static
8987      * @memberOf _
8988      * @since 0.1.0
8989      * @category Collection
8990      * @param {Array|Object} collection The collection to iterate over.
8991      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
8992      * @param {*} [accumulator] The initial value.
8993      * @returns {*} Returns the accumulated value.
8994      * @see _.reduce
8995      * @example
8996      *
8997      * var array = [[0, 1], [2, 3], [4, 5]];
8998      *
8999      * _.reduceRight(array, function(flattened, other) {
9000      *   return flattened.concat(other);
9001      * }, []);
9002      * // => [4, 5, 2, 3, 0, 1]
9003      */
9004     function reduceRight(collection, iteratee, accumulator) {
9005       var func = isArray(collection) ? arrayReduceRight : baseReduce,
9006           initAccum = arguments.length < 3;
9007
9008       return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
9009     }
9010
9011     /**
9012      * The opposite of `_.filter`; this method returns the elements of `collection`
9013      * that `predicate` does **not** return truthy for.
9014      *
9015      * @static
9016      * @memberOf _
9017      * @since 0.1.0
9018      * @category Collection
9019      * @param {Array|Object} collection The collection to iterate over.
9020      * @param {Array|Function|Object|string} [predicate=_.identity]
9021      *  The function invoked per iteration.
9022      * @returns {Array} Returns the new filtered array.
9023      * @see _.filter
9024      * @example
9025      *
9026      * var users = [
9027      *   { 'user': 'barney', 'age': 36, 'active': false },
9028      *   { 'user': 'fred',   'age': 40, 'active': true }
9029      * ];
9030      *
9031      * _.reject(users, function(o) { return !o.active; });
9032      * // => objects for ['fred']
9033      *
9034      * // The `_.matches` iteratee shorthand.
9035      * _.reject(users, { 'age': 40, 'active': true });
9036      * // => objects for ['barney']
9037      *
9038      * // The `_.matchesProperty` iteratee shorthand.
9039      * _.reject(users, ['active', false]);
9040      * // => objects for ['fred']
9041      *
9042      * // The `_.property` iteratee shorthand.
9043      * _.reject(users, 'active');
9044      * // => objects for ['barney']
9045      */
9046     function reject(collection, predicate) {
9047       var func = isArray(collection) ? arrayFilter : baseFilter;
9048       predicate = getIteratee(predicate, 3);
9049       return func(collection, function(value, index, collection) {
9050         return !predicate(value, index, collection);
9051       });
9052     }
9053
9054     /**
9055      * Gets a random element from `collection`.
9056      *
9057      * @static
9058      * @memberOf _
9059      * @since 2.0.0
9060      * @category Collection
9061      * @param {Array|Object} collection The collection to sample.
9062      * @returns {*} Returns the random element.
9063      * @example
9064      *
9065      * _.sample([1, 2, 3, 4]);
9066      * // => 2
9067      */
9068     function sample(collection) {
9069       var array = isArrayLike(collection) ? collection : values(collection),
9070           length = array.length;
9071
9072       return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
9073     }
9074
9075     /**
9076      * Gets `n` random elements at unique keys from `collection` up to the
9077      * size of `collection`.
9078      *
9079      * @static
9080      * @memberOf _
9081      * @since 4.0.0
9082      * @category Collection
9083      * @param {Array|Object} collection The collection to sample.
9084      * @param {number} [n=1] The number of elements to sample.
9085      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9086      * @returns {Array} Returns the random elements.
9087      * @example
9088      *
9089      * _.sampleSize([1, 2, 3], 2);
9090      * // => [3, 1]
9091      *
9092      * _.sampleSize([1, 2, 3], 4);
9093      * // => [2, 3, 1]
9094      */
9095     function sampleSize(collection, n, guard) {
9096       var index = -1,
9097           result = toArray(collection),
9098           length = result.length,
9099           lastIndex = length - 1;
9100
9101       if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
9102         n = 1;
9103       } else {
9104         n = baseClamp(toInteger(n), 0, length);
9105       }
9106       while (++index < n) {
9107         var rand = baseRandom(index, lastIndex),
9108             value = result[rand];
9109
9110         result[rand] = result[index];
9111         result[index] = value;
9112       }
9113       result.length = n;
9114       return result;
9115     }
9116
9117     /**
9118      * Creates an array of shuffled values, using a version of the
9119      * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
9120      *
9121      * @static
9122      * @memberOf _
9123      * @since 0.1.0
9124      * @category Collection
9125      * @param {Array|Object} collection The collection to shuffle.
9126      * @returns {Array} Returns the new shuffled array.
9127      * @example
9128      *
9129      * _.shuffle([1, 2, 3, 4]);
9130      * // => [4, 1, 3, 2]
9131      */
9132     function shuffle(collection) {
9133       return sampleSize(collection, MAX_ARRAY_LENGTH);
9134     }
9135
9136     /**
9137      * Gets the size of `collection` by returning its length for array-like
9138      * values or the number of own enumerable string keyed properties for objects.
9139      *
9140      * @static
9141      * @memberOf _
9142      * @since 0.1.0
9143      * @category Collection
9144      * @param {Array|Object} collection The collection to inspect.
9145      * @returns {number} Returns the collection size.
9146      * @example
9147      *
9148      * _.size([1, 2, 3]);
9149      * // => 3
9150      *
9151      * _.size({ 'a': 1, 'b': 2 });
9152      * // => 2
9153      *
9154      * _.size('pebbles');
9155      * // => 7
9156      */
9157     function size(collection) {
9158       if (collection == null) {
9159         return 0;
9160       }
9161       if (isArrayLike(collection)) {
9162         var result = collection.length;
9163         return (result && isString(collection)) ? stringSize(collection) : result;
9164       }
9165       if (isObjectLike(collection)) {
9166         var tag = getTag(collection);
9167         if (tag == mapTag || tag == setTag) {
9168           return collection.size;
9169         }
9170       }
9171       return keys(collection).length;
9172     }
9173
9174     /**
9175      * Checks if `predicate` returns truthy for **any** element of `collection`.
9176      * Iteration is stopped once `predicate` returns truthy. The predicate is
9177      * invoked with three arguments: (value, index|key, collection).
9178      *
9179      * @static
9180      * @memberOf _
9181      * @since 0.1.0
9182      * @category Collection
9183      * @param {Array|Object} collection The collection to iterate over.
9184      * @param {Array|Function|Object|string} [predicate=_.identity]
9185      *  The function invoked per iteration.
9186      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9187      * @returns {boolean} Returns `true` if any element passes the predicate check,
9188      *  else `false`.
9189      * @example
9190      *
9191      * _.some([null, 0, 'yes', false], Boolean);
9192      * // => true
9193      *
9194      * var users = [
9195      *   { 'user': 'barney', 'active': true },
9196      *   { 'user': 'fred',   'active': false }
9197      * ];
9198      *
9199      * // The `_.matches` iteratee shorthand.
9200      * _.some(users, { 'user': 'barney', 'active': false });
9201      * // => false
9202      *
9203      * // The `_.matchesProperty` iteratee shorthand.
9204      * _.some(users, ['active', false]);
9205      * // => true
9206      *
9207      * // The `_.property` iteratee shorthand.
9208      * _.some(users, 'active');
9209      * // => true
9210      */
9211     function some(collection, predicate, guard) {
9212       var func = isArray(collection) ? arraySome : baseSome;
9213       if (guard && isIterateeCall(collection, predicate, guard)) {
9214         predicate = undefined;
9215       }
9216       return func(collection, getIteratee(predicate, 3));
9217     }
9218
9219     /**
9220      * Creates an array of elements, sorted in ascending order by the results of
9221      * running each element in a collection thru each iteratee. This method
9222      * performs a stable sort, that is, it preserves the original sort order of
9223      * equal elements. The iteratees are invoked with one argument: (value).
9224      *
9225      * @static
9226      * @memberOf _
9227      * @since 0.1.0
9228      * @category Collection
9229      * @param {Array|Object} collection The collection to iterate over.
9230      * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
9231      *  [iteratees=[_.identity]] The iteratees to sort by.
9232      * @returns {Array} Returns the new sorted array.
9233      * @example
9234      *
9235      * var users = [
9236      *   { 'user': 'fred',   'age': 48 },
9237      *   { 'user': 'barney', 'age': 36 },
9238      *   { 'user': 'fred',   'age': 40 },
9239      *   { 'user': 'barney', 'age': 34 }
9240      * ];
9241      *
9242      * _.sortBy(users, function(o) { return o.user; });
9243      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9244      *
9245      * _.sortBy(users, ['user', 'age']);
9246      * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
9247      *
9248      * _.sortBy(users, 'user', function(o) {
9249      *   return Math.floor(o.age / 10);
9250      * });
9251      * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
9252      */
9253     var sortBy = rest(function(collection, iteratees) {
9254       if (collection == null) {
9255         return [];
9256       }
9257       var length = iteratees.length;
9258       if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
9259         iteratees = [];
9260       } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
9261         iteratees = [iteratees[0]];
9262       }
9263       iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
9264         ? iteratees[0]
9265         : baseFlatten(iteratees, 1, isFlattenableIteratee);
9266
9267       return baseOrderBy(collection, iteratees, []);
9268     });
9269
9270     /*------------------------------------------------------------------------*/
9271
9272     /**
9273      * Gets the timestamp of the number of milliseconds that have elapsed since
9274      * the Unix epoch (1 January 1970 00:00:00 UTC).
9275      *
9276      * @static
9277      * @memberOf _
9278      * @since 2.4.0
9279      * @category Date
9280      * @returns {number} Returns the timestamp.
9281      * @example
9282      *
9283      * _.defer(function(stamp) {
9284      *   console.log(_.now() - stamp);
9285      * }, _.now());
9286      * // => Logs the number of milliseconds it took for the deferred invocation.
9287      */
9288     function now() {
9289       return Date.now();
9290     }
9291
9292     /*------------------------------------------------------------------------*/
9293
9294     /**
9295      * The opposite of `_.before`; this method creates a function that invokes
9296      * `func` once it's called `n` or more times.
9297      *
9298      * @static
9299      * @memberOf _
9300      * @since 0.1.0
9301      * @category Function
9302      * @param {number} n The number of calls before `func` is invoked.
9303      * @param {Function} func The function to restrict.
9304      * @returns {Function} Returns the new restricted function.
9305      * @example
9306      *
9307      * var saves = ['profile', 'settings'];
9308      *
9309      * var done = _.after(saves.length, function() {
9310      *   console.log('done saving!');
9311      * });
9312      *
9313      * _.forEach(saves, function(type) {
9314      *   asyncSave({ 'type': type, 'complete': done });
9315      * });
9316      * // => Logs 'done saving!' after the two async saves have completed.
9317      */
9318     function after(n, func) {
9319       if (typeof func != 'function') {
9320         throw new TypeError(FUNC_ERROR_TEXT);
9321       }
9322       n = toInteger(n);
9323       return function() {
9324         if (--n < 1) {
9325           return func.apply(this, arguments);
9326         }
9327       };
9328     }
9329
9330     /**
9331      * Creates a function that invokes `func`, with up to `n` arguments,
9332      * ignoring any additional arguments.
9333      *
9334      * @static
9335      * @memberOf _
9336      * @since 3.0.0
9337      * @category Function
9338      * @param {Function} func The function to cap arguments for.
9339      * @param {number} [n=func.length] The arity cap.
9340      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9341      * @returns {Function} Returns the new capped function.
9342      * @example
9343      *
9344      * _.map(['6', '8', '10'], _.ary(parseInt, 1));
9345      * // => [6, 8, 10]
9346      */
9347     function ary(func, n, guard) {
9348       n = guard ? undefined : n;
9349       n = (func && n == null) ? func.length : n;
9350       return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
9351     }
9352
9353     /**
9354      * Creates a function that invokes `func`, with the `this` binding and arguments
9355      * of the created function, while it's called less than `n` times. Subsequent
9356      * calls to the created function return the result of the last `func` invocation.
9357      *
9358      * @static
9359      * @memberOf _
9360      * @since 3.0.0
9361      * @category Function
9362      * @param {number} n The number of calls at which `func` is no longer invoked.
9363      * @param {Function} func The function to restrict.
9364      * @returns {Function} Returns the new restricted function.
9365      * @example
9366      *
9367      * jQuery(element).on('click', _.before(5, addContactToList));
9368      * // => allows adding up to 4 contacts to the list
9369      */
9370     function before(n, func) {
9371       var result;
9372       if (typeof func != 'function') {
9373         throw new TypeError(FUNC_ERROR_TEXT);
9374       }
9375       n = toInteger(n);
9376       return function() {
9377         if (--n > 0) {
9378           result = func.apply(this, arguments);
9379         }
9380         if (n <= 1) {
9381           func = undefined;
9382         }
9383         return result;
9384       };
9385     }
9386
9387     /**
9388      * Creates a function that invokes `func` with the `this` binding of `thisArg`
9389      * and `partials` prepended to the arguments it receives.
9390      *
9391      * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
9392      * may be used as a placeholder for partially applied arguments.
9393      *
9394      * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
9395      * property of bound functions.
9396      *
9397      * @static
9398      * @memberOf _
9399      * @since 0.1.0
9400      * @category Function
9401      * @param {Function} func The function to bind.
9402      * @param {*} thisArg The `this` binding of `func`.
9403      * @param {...*} [partials] The arguments to be partially applied.
9404      * @returns {Function} Returns the new bound function.
9405      * @example
9406      *
9407      * var greet = function(greeting, punctuation) {
9408      *   return greeting + ' ' + this.user + punctuation;
9409      * };
9410      *
9411      * var object = { 'user': 'fred' };
9412      *
9413      * var bound = _.bind(greet, object, 'hi');
9414      * bound('!');
9415      * // => 'hi fred!'
9416      *
9417      * // Bound with placeholders.
9418      * var bound = _.bind(greet, object, _, '!');
9419      * bound('hi');
9420      * // => 'hi fred!'
9421      */
9422     var bind = rest(function(func, thisArg, partials) {
9423       var bitmask = BIND_FLAG;
9424       if (partials.length) {
9425         var holders = replaceHolders(partials, getHolder(bind));
9426         bitmask |= PARTIAL_FLAG;
9427       }
9428       return createWrapper(func, bitmask, thisArg, partials, holders);
9429     });
9430
9431     /**
9432      * Creates a function that invokes the method at `object[key]` with `partials`
9433      * prepended to the arguments it receives.
9434      *
9435      * This method differs from `_.bind` by allowing bound functions to reference
9436      * methods that may be redefined or don't yet exist. See
9437      * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
9438      * for more details.
9439      *
9440      * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
9441      * builds, may be used as a placeholder for partially applied arguments.
9442      *
9443      * @static
9444      * @memberOf _
9445      * @since 0.10.0
9446      * @category Function
9447      * @param {Object} object The object to invoke the method on.
9448      * @param {string} key The key of the method.
9449      * @param {...*} [partials] The arguments to be partially applied.
9450      * @returns {Function} Returns the new bound function.
9451      * @example
9452      *
9453      * var object = {
9454      *   'user': 'fred',
9455      *   'greet': function(greeting, punctuation) {
9456      *     return greeting + ' ' + this.user + punctuation;
9457      *   }
9458      * };
9459      *
9460      * var bound = _.bindKey(object, 'greet', 'hi');
9461      * bound('!');
9462      * // => 'hi fred!'
9463      *
9464      * object.greet = function(greeting, punctuation) {
9465      *   return greeting + 'ya ' + this.user + punctuation;
9466      * };
9467      *
9468      * bound('!');
9469      * // => 'hiya fred!'
9470      *
9471      * // Bound with placeholders.
9472      * var bound = _.bindKey(object, 'greet', _, '!');
9473      * bound('hi');
9474      * // => 'hiya fred!'
9475      */
9476     var bindKey = rest(function(object, key, partials) {
9477       var bitmask = BIND_FLAG | BIND_KEY_FLAG;
9478       if (partials.length) {
9479         var holders = replaceHolders(partials, getHolder(bindKey));
9480         bitmask |= PARTIAL_FLAG;
9481       }
9482       return createWrapper(key, bitmask, object, partials, holders);
9483     });
9484
9485     /**
9486      * Creates a function that accepts arguments of `func` and either invokes
9487      * `func` returning its result, if at least `arity` number of arguments have
9488      * been provided, or returns a function that accepts the remaining `func`
9489      * arguments, and so on. The arity of `func` may be specified if `func.length`
9490      * is not sufficient.
9491      *
9492      * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
9493      * may be used as a placeholder for provided arguments.
9494      *
9495      * **Note:** This method doesn't set the "length" property of curried functions.
9496      *
9497      * @static
9498      * @memberOf _
9499      * @since 2.0.0
9500      * @category Function
9501      * @param {Function} func The function to curry.
9502      * @param {number} [arity=func.length] The arity of `func`.
9503      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9504      * @returns {Function} Returns the new curried function.
9505      * @example
9506      *
9507      * var abc = function(a, b, c) {
9508      *   return [a, b, c];
9509      * };
9510      *
9511      * var curried = _.curry(abc);
9512      *
9513      * curried(1)(2)(3);
9514      * // => [1, 2, 3]
9515      *
9516      * curried(1, 2)(3);
9517      * // => [1, 2, 3]
9518      *
9519      * curried(1, 2, 3);
9520      * // => [1, 2, 3]
9521      *
9522      * // Curried with placeholders.
9523      * curried(1)(_, 3)(2);
9524      * // => [1, 2, 3]
9525      */
9526     function curry(func, arity, guard) {
9527       arity = guard ? undefined : arity;
9528       var result = createWrapper(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
9529       result.placeholder = curry.placeholder;
9530       return result;
9531     }
9532
9533     /**
9534      * This method is like `_.curry` except that arguments are applied to `func`
9535      * in the manner of `_.partialRight` instead of `_.partial`.
9536      *
9537      * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
9538      * builds, may be used as a placeholder for provided arguments.
9539      *
9540      * **Note:** This method doesn't set the "length" property of curried functions.
9541      *
9542      * @static
9543      * @memberOf _
9544      * @since 3.0.0
9545      * @category Function
9546      * @param {Function} func The function to curry.
9547      * @param {number} [arity=func.length] The arity of `func`.
9548      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
9549      * @returns {Function} Returns the new curried function.
9550      * @example
9551      *
9552      * var abc = function(a, b, c) {
9553      *   return [a, b, c];
9554      * };
9555      *
9556      * var curried = _.curryRight(abc);
9557      *
9558      * curried(3)(2)(1);
9559      * // => [1, 2, 3]
9560      *
9561      * curried(2, 3)(1);
9562      * // => [1, 2, 3]
9563      *
9564      * curried(1, 2, 3);
9565      * // => [1, 2, 3]
9566      *
9567      * // Curried with placeholders.
9568      * curried(3)(1, _)(2);
9569      * // => [1, 2, 3]
9570      */
9571     function curryRight(func, arity, guard) {
9572       arity = guard ? undefined : arity;
9573       var result = createWrapper(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
9574       result.placeholder = curryRight.placeholder;
9575       return result;
9576     }
9577
9578     /**
9579      * Creates a debounced function that delays invoking `func` until after `wait`
9580      * milliseconds have elapsed since the last time the debounced function was
9581      * invoked. The debounced function comes with a `cancel` method to cancel
9582      * delayed `func` invocations and a `flush` method to immediately invoke them.
9583      * Provide an options object to indicate whether `func` should be invoked on
9584      * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
9585      * with the last arguments provided to the debounced function. Subsequent calls
9586      * to the debounced function return the result of the last `func` invocation.
9587      *
9588      * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
9589      * on the trailing edge of the timeout only if the debounced function is
9590      * invoked more than once during the `wait` timeout.
9591      *
9592      * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
9593      * for details over the differences between `_.debounce` and `_.throttle`.
9594      *
9595      * @static
9596      * @memberOf _
9597      * @since 0.1.0
9598      * @category Function
9599      * @param {Function} func The function to debounce.
9600      * @param {number} [wait=0] The number of milliseconds to delay.
9601      * @param {Object} [options={}] The options object.
9602      * @param {boolean} [options.leading=false]
9603      *  Specify invoking on the leading edge of the timeout.
9604      * @param {number} [options.maxWait]
9605      *  The maximum time `func` is allowed to be delayed before it's invoked.
9606      * @param {boolean} [options.trailing=true]
9607      *  Specify invoking on the trailing edge of the timeout.
9608      * @returns {Function} Returns the new debounced function.
9609      * @example
9610      *
9611      * // Avoid costly calculations while the window size is in flux.
9612      * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
9613      *
9614      * // Invoke `sendMail` when clicked, debouncing subsequent calls.
9615      * jQuery(element).on('click', _.debounce(sendMail, 300, {
9616      *   'leading': true,
9617      *   'trailing': false
9618      * }));
9619      *
9620      * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
9621      * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
9622      * var source = new EventSource('/stream');
9623      * jQuery(source).on('message', debounced);
9624      *
9625      * // Cancel the trailing debounced invocation.
9626      * jQuery(window).on('popstate', debounced.cancel);
9627      */
9628     function debounce(func, wait, options) {
9629       var lastArgs,
9630           lastThis,
9631           maxWait,
9632           result,
9633           timerId,
9634           lastCallTime,
9635           lastInvokeTime = 0,
9636           leading = false,
9637           maxing = false,
9638           trailing = true;
9639
9640       if (typeof func != 'function') {
9641         throw new TypeError(FUNC_ERROR_TEXT);
9642       }
9643       wait = toNumber(wait) || 0;
9644       if (isObject(options)) {
9645         leading = !!options.leading;
9646         maxing = 'maxWait' in options;
9647         maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
9648         trailing = 'trailing' in options ? !!options.trailing : trailing;
9649       }
9650
9651       function invokeFunc(time) {
9652         var args = lastArgs,
9653             thisArg = lastThis;
9654
9655         lastArgs = lastThis = undefined;
9656         lastInvokeTime = time;
9657         result = func.apply(thisArg, args);
9658         return result;
9659       }
9660
9661       function leadingEdge(time) {
9662         // Reset any `maxWait` timer.
9663         lastInvokeTime = time;
9664         // Start the timer for the trailing edge.
9665         timerId = setTimeout(timerExpired, wait);
9666         // Invoke the leading edge.
9667         return leading ? invokeFunc(time) : result;
9668       }
9669
9670       function remainingWait(time) {
9671         var timeSinceLastCall = time - lastCallTime,
9672             timeSinceLastInvoke = time - lastInvokeTime,
9673             result = wait - timeSinceLastCall;
9674
9675         return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
9676       }
9677
9678       function shouldInvoke(time) {
9679         var timeSinceLastCall = time - lastCallTime,
9680             timeSinceLastInvoke = time - lastInvokeTime;
9681
9682         // Either this is the first call, activity has stopped and we're at the
9683         // trailing edge, the system time has gone backwards and we're treating
9684         // it as the trailing edge, or we've hit the `maxWait` limit.
9685         return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
9686           (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
9687       }
9688
9689       function timerExpired() {
9690         var time = now();
9691         if (shouldInvoke(time)) {
9692           return trailingEdge(time);
9693         }
9694         // Restart the timer.
9695         timerId = setTimeout(timerExpired, remainingWait(time));
9696       }
9697
9698       function trailingEdge(time) {
9699         timerId = undefined;
9700
9701         // Only invoke if we have `lastArgs` which means `func` has been
9702         // debounced at least once.
9703         if (trailing && lastArgs) {
9704           return invokeFunc(time);
9705         }
9706         lastArgs = lastThis = undefined;
9707         return result;
9708       }
9709
9710       function cancel() {
9711         lastInvokeTime = 0;
9712         lastArgs = lastCallTime = lastThis = timerId = undefined;
9713       }
9714
9715       function flush() {
9716         return timerId === undefined ? result : trailingEdge(now());
9717       }
9718
9719       function debounced() {
9720         var time = now(),
9721             isInvoking = shouldInvoke(time);
9722
9723         lastArgs = arguments;
9724         lastThis = this;
9725         lastCallTime = time;
9726
9727         if (isInvoking) {
9728           if (timerId === undefined) {
9729             return leadingEdge(lastCallTime);
9730           }
9731           if (maxing) {
9732             // Handle invocations in a tight loop.
9733             timerId = setTimeout(timerExpired, wait);
9734             return invokeFunc(lastCallTime);
9735           }
9736         }
9737         if (timerId === undefined) {
9738           timerId = setTimeout(timerExpired, wait);
9739         }
9740         return result;
9741       }
9742       debounced.cancel = cancel;
9743       debounced.flush = flush;
9744       return debounced;
9745     }
9746
9747     /**
9748      * Defers invoking the `func` until the current call stack has cleared. Any
9749      * additional arguments are provided to `func` when it's invoked.
9750      *
9751      * @static
9752      * @memberOf _
9753      * @since 0.1.0
9754      * @category Function
9755      * @param {Function} func The function to defer.
9756      * @param {...*} [args] The arguments to invoke `func` with.
9757      * @returns {number} Returns the timer id.
9758      * @example
9759      *
9760      * _.defer(function(text) {
9761      *   console.log(text);
9762      * }, 'deferred');
9763      * // => Logs 'deferred' after one or more milliseconds.
9764      */
9765     var defer = rest(function(func, args) {
9766       return baseDelay(func, 1, args);
9767     });
9768
9769     /**
9770      * Invokes `func` after `wait` milliseconds. Any additional arguments are
9771      * provided to `func` when it's invoked.
9772      *
9773      * @static
9774      * @memberOf _
9775      * @since 0.1.0
9776      * @category Function
9777      * @param {Function} func The function to delay.
9778      * @param {number} wait The number of milliseconds to delay invocation.
9779      * @param {...*} [args] The arguments to invoke `func` with.
9780      * @returns {number} Returns the timer id.
9781      * @example
9782      *
9783      * _.delay(function(text) {
9784      *   console.log(text);
9785      * }, 1000, 'later');
9786      * // => Logs 'later' after one second.
9787      */
9788     var delay = rest(function(func, wait, args) {
9789       return baseDelay(func, toNumber(wait) || 0, args);
9790     });
9791
9792     /**
9793      * Creates a function that invokes `func` with arguments reversed.
9794      *
9795      * @static
9796      * @memberOf _
9797      * @since 4.0.0
9798      * @category Function
9799      * @param {Function} func The function to flip arguments for.
9800      * @returns {Function} Returns the new flipped function.
9801      * @example
9802      *
9803      * var flipped = _.flip(function() {
9804      *   return _.toArray(arguments);
9805      * });
9806      *
9807      * flipped('a', 'b', 'c', 'd');
9808      * // => ['d', 'c', 'b', 'a']
9809      */
9810     function flip(func) {
9811       return createWrapper(func, FLIP_FLAG);
9812     }
9813
9814     /**
9815      * Creates a function that memoizes the result of `func`. If `resolver` is
9816      * provided, it determines the cache key for storing the result based on the
9817      * arguments provided to the memoized function. By default, the first argument
9818      * provided to the memoized function is used as the map cache key. The `func`
9819      * is invoked with the `this` binding of the memoized function.
9820      *
9821      * **Note:** The cache is exposed as the `cache` property on the memoized
9822      * function. Its creation may be customized by replacing the `_.memoize.Cache`
9823      * constructor with one whose instances implement the
9824      * [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object)
9825      * method interface of `delete`, `get`, `has`, and `set`.
9826      *
9827      * @static
9828      * @memberOf _
9829      * @since 0.1.0
9830      * @category Function
9831      * @param {Function} func The function to have its output memoized.
9832      * @param {Function} [resolver] The function to resolve the cache key.
9833      * @returns {Function} Returns the new memoized function.
9834      * @example
9835      *
9836      * var object = { 'a': 1, 'b': 2 };
9837      * var other = { 'c': 3, 'd': 4 };
9838      *
9839      * var values = _.memoize(_.values);
9840      * values(object);
9841      * // => [1, 2]
9842      *
9843      * values(other);
9844      * // => [3, 4]
9845      *
9846      * object.a = 2;
9847      * values(object);
9848      * // => [1, 2]
9849      *
9850      * // Modify the result cache.
9851      * values.cache.set(object, ['a', 'b']);
9852      * values(object);
9853      * // => ['a', 'b']
9854      *
9855      * // Replace `_.memoize.Cache`.
9856      * _.memoize.Cache = WeakMap;
9857      */
9858     function memoize(func, resolver) {
9859       if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
9860         throw new TypeError(FUNC_ERROR_TEXT);
9861       }
9862       var memoized = function() {
9863         var args = arguments,
9864             key = resolver ? resolver.apply(this, args) : args[0],
9865             cache = memoized.cache;
9866
9867         if (cache.has(key)) {
9868           return cache.get(key);
9869         }
9870         var result = func.apply(this, args);
9871         memoized.cache = cache.set(key, result);
9872         return result;
9873       };
9874       memoized.cache = new (memoize.Cache || MapCache);
9875       return memoized;
9876     }
9877
9878     // Assign cache to `_.memoize`.
9879     memoize.Cache = MapCache;
9880
9881     /**
9882      * Creates a function that negates the result of the predicate `func`. The
9883      * `func` predicate is invoked with the `this` binding and arguments of the
9884      * created function.
9885      *
9886      * @static
9887      * @memberOf _
9888      * @since 3.0.0
9889      * @category Function
9890      * @param {Function} predicate The predicate to negate.
9891      * @returns {Function} Returns the new negated function.
9892      * @example
9893      *
9894      * function isEven(n) {
9895      *   return n % 2 == 0;
9896      * }
9897      *
9898      * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
9899      * // => [1, 3, 5]
9900      */
9901     function negate(predicate) {
9902       if (typeof predicate != 'function') {
9903         throw new TypeError(FUNC_ERROR_TEXT);
9904       }
9905       return function() {
9906         return !predicate.apply(this, arguments);
9907       };
9908     }
9909
9910     /**
9911      * Creates a function that is restricted to invoking `func` once. Repeat calls
9912      * to the function return the value of the first invocation. The `func` is
9913      * invoked with the `this` binding and arguments of the created function.
9914      *
9915      * @static
9916      * @memberOf _
9917      * @since 0.1.0
9918      * @category Function
9919      * @param {Function} func The function to restrict.
9920      * @returns {Function} Returns the new restricted function.
9921      * @example
9922      *
9923      * var initialize = _.once(createApplication);
9924      * initialize();
9925      * initialize();
9926      * // `initialize` invokes `createApplication` once
9927      */
9928     function once(func) {
9929       return before(2, func);
9930     }
9931
9932     /**
9933      * Creates a function that invokes `func` with arguments transformed by
9934      * corresponding `transforms`.
9935      *
9936      * @static
9937      * @since 4.0.0
9938      * @memberOf _
9939      * @category Function
9940      * @param {Function} func The function to wrap.
9941      * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
9942      *  [transforms[_.identity]] The functions to transform.
9943      * @returns {Function} Returns the new function.
9944      * @example
9945      *
9946      * function doubled(n) {
9947      *   return n * 2;
9948      * }
9949      *
9950      * function square(n) {
9951      *   return n * n;
9952      * }
9953      *
9954      * var func = _.overArgs(function(x, y) {
9955      *   return [x, y];
9956      * }, [square, doubled]);
9957      *
9958      * func(9, 3);
9959      * // => [81, 6]
9960      *
9961      * func(10, 5);
9962      * // => [100, 10]
9963      */
9964     var overArgs = rest(function(func, transforms) {
9965       transforms = (transforms.length == 1 && isArray(transforms[0]))
9966         ? arrayMap(transforms[0], baseUnary(getIteratee()))
9967         : arrayMap(baseFlatten(transforms, 1, isFlattenableIteratee), baseUnary(getIteratee()));
9968
9969       var funcsLength = transforms.length;
9970       return rest(function(args) {
9971         var index = -1,
9972             length = nativeMin(args.length, funcsLength);
9973
9974         while (++index < length) {
9975           args[index] = transforms[index].call(this, args[index]);
9976         }
9977         return apply(func, this, args);
9978       });
9979     });
9980
9981     /**
9982      * Creates a function that invokes `func` with `partials` prepended to the
9983      * arguments it receives. This method is like `_.bind` except it does **not**
9984      * alter the `this` binding.
9985      *
9986      * The `_.partial.placeholder` value, which defaults to `_` in monolithic
9987      * builds, may be used as a placeholder for partially applied arguments.
9988      *
9989      * **Note:** This method doesn't set the "length" property of partially
9990      * applied functions.
9991      *
9992      * @static
9993      * @memberOf _
9994      * @since 0.2.0
9995      * @category Function
9996      * @param {Function} func The function to partially apply arguments to.
9997      * @param {...*} [partials] The arguments to be partially applied.
9998      * @returns {Function} Returns the new partially applied function.
9999      * @example
10000      *
10001      * var greet = function(greeting, name) {
10002      *   return greeting + ' ' + name;
10003      * };
10004      *
10005      * var sayHelloTo = _.partial(greet, 'hello');
10006      * sayHelloTo('fred');
10007      * // => 'hello fred'
10008      *
10009      * // Partially applied with placeholders.
10010      * var greetFred = _.partial(greet, _, 'fred');
10011      * greetFred('hi');
10012      * // => 'hi fred'
10013      */
10014     var partial = rest(function(func, partials) {
10015       var holders = replaceHolders(partials, getHolder(partial));
10016       return createWrapper(func, PARTIAL_FLAG, undefined, partials, holders);
10017     });
10018
10019     /**
10020      * This method is like `_.partial` except that partially applied arguments
10021      * are appended to the arguments it receives.
10022      *
10023      * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
10024      * builds, may be used as a placeholder for partially applied arguments.
10025      *
10026      * **Note:** This method doesn't set the "length" property of partially
10027      * applied functions.
10028      *
10029      * @static
10030      * @memberOf _
10031      * @since 1.0.0
10032      * @category Function
10033      * @param {Function} func The function to partially apply arguments to.
10034      * @param {...*} [partials] The arguments to be partially applied.
10035      * @returns {Function} Returns the new partially applied function.
10036      * @example
10037      *
10038      * var greet = function(greeting, name) {
10039      *   return greeting + ' ' + name;
10040      * };
10041      *
10042      * var greetFred = _.partialRight(greet, 'fred');
10043      * greetFred('hi');
10044      * // => 'hi fred'
10045      *
10046      * // Partially applied with placeholders.
10047      * var sayHelloTo = _.partialRight(greet, 'hello', _);
10048      * sayHelloTo('fred');
10049      * // => 'hello fred'
10050      */
10051     var partialRight = rest(function(func, partials) {
10052       var holders = replaceHolders(partials, getHolder(partialRight));
10053       return createWrapper(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
10054     });
10055
10056     /**
10057      * Creates a function that invokes `func` with arguments arranged according
10058      * to the specified `indexes` where the argument value at the first index is
10059      * provided as the first argument, the argument value at the second index is
10060      * provided as the second argument, and so on.
10061      *
10062      * @static
10063      * @memberOf _
10064      * @since 3.0.0
10065      * @category Function
10066      * @param {Function} func The function to rearrange arguments for.
10067      * @param {...(number|number[])} indexes The arranged argument indexes.
10068      * @returns {Function} Returns the new function.
10069      * @example
10070      *
10071      * var rearged = _.rearg(function(a, b, c) {
10072      *   return [a, b, c];
10073      * }, [2, 0, 1]);
10074      *
10075      * rearged('b', 'c', 'a')
10076      * // => ['a', 'b', 'c']
10077      */
10078     var rearg = rest(function(func, indexes) {
10079       return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1));
10080     });
10081
10082     /**
10083      * Creates a function that invokes `func` with the `this` binding of the
10084      * created function and arguments from `start` and beyond provided as
10085      * an array.
10086      *
10087      * **Note:** This method is based on the
10088      * [rest parameter](https://mdn.io/rest_parameters).
10089      *
10090      * @static
10091      * @memberOf _
10092      * @since 4.0.0
10093      * @category Function
10094      * @param {Function} func The function to apply a rest parameter to.
10095      * @param {number} [start=func.length-1] The start position of the rest parameter.
10096      * @returns {Function} Returns the new function.
10097      * @example
10098      *
10099      * var say = _.rest(function(what, names) {
10100      *   return what + ' ' + _.initial(names).join(', ') +
10101      *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
10102      * });
10103      *
10104      * say('hello', 'fred', 'barney', 'pebbles');
10105      * // => 'hello fred, barney, & pebbles'
10106      */
10107     function rest(func, start) {
10108       if (typeof func != 'function') {
10109         throw new TypeError(FUNC_ERROR_TEXT);
10110       }
10111       start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
10112       return function() {
10113         var args = arguments,
10114             index = -1,
10115             length = nativeMax(args.length - start, 0),
10116             array = Array(length);
10117
10118         while (++index < length) {
10119           array[index] = args[start + index];
10120         }
10121         switch (start) {
10122           case 0: return func.call(this, array);
10123           case 1: return func.call(this, args[0], array);
10124           case 2: return func.call(this, args[0], args[1], array);
10125         }
10126         var otherArgs = Array(start + 1);
10127         index = -1;
10128         while (++index < start) {
10129           otherArgs[index] = args[index];
10130         }
10131         otherArgs[start] = array;
10132         return apply(func, this, otherArgs);
10133       };
10134     }
10135
10136     /**
10137      * Creates a function that invokes `func` with the `this` binding of the
10138      * create function and an array of arguments much like
10139      * [`Function#apply`](http://www.ecma-international.org/ecma-262/6.0/#sec-function.prototype.apply).
10140      *
10141      * **Note:** This method is based on the
10142      * [spread operator](https://mdn.io/spread_operator).
10143      *
10144      * @static
10145      * @memberOf _
10146      * @since 3.2.0
10147      * @category Function
10148      * @param {Function} func The function to spread arguments over.
10149      * @param {number} [start=0] The start position of the spread.
10150      * @returns {Function} Returns the new function.
10151      * @example
10152      *
10153      * var say = _.spread(function(who, what) {
10154      *   return who + ' says ' + what;
10155      * });
10156      *
10157      * say(['fred', 'hello']);
10158      * // => 'fred says hello'
10159      *
10160      * var numbers = Promise.all([
10161      *   Promise.resolve(40),
10162      *   Promise.resolve(36)
10163      * ]);
10164      *
10165      * numbers.then(_.spread(function(x, y) {
10166      *   return x + y;
10167      * }));
10168      * // => a Promise of 76
10169      */
10170     function spread(func, start) {
10171       if (typeof func != 'function') {
10172         throw new TypeError(FUNC_ERROR_TEXT);
10173       }
10174       start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
10175       return rest(function(args) {
10176         var array = args[start],
10177             otherArgs = castSlice(args, 0, start);
10178
10179         if (array) {
10180           arrayPush(otherArgs, array);
10181         }
10182         return apply(func, this, otherArgs);
10183       });
10184     }
10185
10186     /**
10187      * Creates a throttled function that only invokes `func` at most once per
10188      * every `wait` milliseconds. The throttled function comes with a `cancel`
10189      * method to cancel delayed `func` invocations and a `flush` method to
10190      * immediately invoke them. Provide an options object to indicate whether
10191      * `func` should be invoked on the leading and/or trailing edge of the `wait`
10192      * timeout. The `func` is invoked with the last arguments provided to the
10193      * throttled function. Subsequent calls to the throttled function return the
10194      * result of the last `func` invocation.
10195      *
10196      * **Note:** If `leading` and `trailing` options are `true`, `func` is
10197      * invoked on the trailing edge of the timeout only if the throttled function
10198      * is invoked more than once during the `wait` timeout.
10199      *
10200      * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
10201      * for details over the differences between `_.throttle` and `_.debounce`.
10202      *
10203      * @static
10204      * @memberOf _
10205      * @since 0.1.0
10206      * @category Function
10207      * @param {Function} func The function to throttle.
10208      * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
10209      * @param {Object} [options={}] The options object.
10210      * @param {boolean} [options.leading=true]
10211      *  Specify invoking on the leading edge of the timeout.
10212      * @param {boolean} [options.trailing=true]
10213      *  Specify invoking on the trailing edge of the timeout.
10214      * @returns {Function} Returns the new throttled function.
10215      * @example
10216      *
10217      * // Avoid excessively updating the position while scrolling.
10218      * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
10219      *
10220      * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
10221      * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
10222      * jQuery(element).on('click', throttled);
10223      *
10224      * // Cancel the trailing throttled invocation.
10225      * jQuery(window).on('popstate', throttled.cancel);
10226      */
10227     function throttle(func, wait, options) {
10228       var leading = true,
10229           trailing = true;
10230
10231       if (typeof func != 'function') {
10232         throw new TypeError(FUNC_ERROR_TEXT);
10233       }
10234       if (isObject(options)) {
10235         leading = 'leading' in options ? !!options.leading : leading;
10236         trailing = 'trailing' in options ? !!options.trailing : trailing;
10237       }
10238       return debounce(func, wait, {
10239         'leading': leading,
10240         'maxWait': wait,
10241         'trailing': trailing
10242       });
10243     }
10244
10245     /**
10246      * Creates a function that accepts up to one argument, ignoring any
10247      * additional arguments.
10248      *
10249      * @static
10250      * @memberOf _
10251      * @since 4.0.0
10252      * @category Function
10253      * @param {Function} func The function to cap arguments for.
10254      * @returns {Function} Returns the new capped function.
10255      * @example
10256      *
10257      * _.map(['6', '8', '10'], _.unary(parseInt));
10258      * // => [6, 8, 10]
10259      */
10260     function unary(func) {
10261       return ary(func, 1);
10262     }
10263
10264     /**
10265      * Creates a function that provides `value` to the wrapper function as its
10266      * first argument. Any additional arguments provided to the function are
10267      * appended to those provided to the wrapper function. The wrapper is invoked
10268      * with the `this` binding of the created function.
10269      *
10270      * @static
10271      * @memberOf _
10272      * @since 0.1.0
10273      * @category Function
10274      * @param {*} value The value to wrap.
10275      * @param {Function} [wrapper=identity] The wrapper function.
10276      * @returns {Function} Returns the new function.
10277      * @example
10278      *
10279      * var p = _.wrap(_.escape, function(func, text) {
10280      *   return '<p>' + func(text) + '</p>';
10281      * });
10282      *
10283      * p('fred, barney, & pebbles');
10284      * // => '<p>fred, barney, &amp; pebbles</p>'
10285      */
10286     function wrap(value, wrapper) {
10287       wrapper = wrapper == null ? identity : wrapper;
10288       return partial(wrapper, value);
10289     }
10290
10291     /*------------------------------------------------------------------------*/
10292
10293     /**
10294      * Casts `value` as an array if it's not one.
10295      *
10296      * @static
10297      * @memberOf _
10298      * @since 4.4.0
10299      * @category Lang
10300      * @param {*} value The value to inspect.
10301      * @returns {Array} Returns the cast array.
10302      * @example
10303      *
10304      * _.castArray(1);
10305      * // => [1]
10306      *
10307      * _.castArray({ 'a': 1 });
10308      * // => [{ 'a': 1 }]
10309      *
10310      * _.castArray('abc');
10311      * // => ['abc']
10312      *
10313      * _.castArray(null);
10314      * // => [null]
10315      *
10316      * _.castArray(undefined);
10317      * // => [undefined]
10318      *
10319      * _.castArray();
10320      * // => []
10321      *
10322      * var array = [1, 2, 3];
10323      * console.log(_.castArray(array) === array);
10324      * // => true
10325      */
10326     function castArray() {
10327       if (!arguments.length) {
10328         return [];
10329       }
10330       var value = arguments[0];
10331       return isArray(value) ? value : [value];
10332     }
10333
10334     /**
10335      * Creates a shallow clone of `value`.
10336      *
10337      * **Note:** This method is loosely based on the
10338      * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
10339      * and supports cloning arrays, array buffers, booleans, date objects, maps,
10340      * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
10341      * arrays. The own enumerable properties of `arguments` objects are cloned
10342      * as plain objects. An empty object is returned for uncloneable values such
10343      * as error objects, functions, DOM nodes, and WeakMaps.
10344      *
10345      * @static
10346      * @memberOf _
10347      * @since 0.1.0
10348      * @category Lang
10349      * @param {*} value The value to clone.
10350      * @returns {*} Returns the cloned value.
10351      * @see _.cloneDeep
10352      * @example
10353      *
10354      * var objects = [{ 'a': 1 }, { 'b': 2 }];
10355      *
10356      * var shallow = _.clone(objects);
10357      * console.log(shallow[0] === objects[0]);
10358      * // => true
10359      */
10360     function clone(value) {
10361       return baseClone(value, false, true);
10362     }
10363
10364     /**
10365      * This method is like `_.clone` except that it accepts `customizer` which
10366      * is invoked to produce the cloned value. If `customizer` returns `undefined`,
10367      * cloning is handled by the method instead. The `customizer` is invoked with
10368      * up to four arguments; (value [, index|key, object, stack]).
10369      *
10370      * @static
10371      * @memberOf _
10372      * @since 4.0.0
10373      * @category Lang
10374      * @param {*} value The value to clone.
10375      * @param {Function} [customizer] The function to customize cloning.
10376      * @returns {*} Returns the cloned value.
10377      * @see _.cloneDeepWith
10378      * @example
10379      *
10380      * function customizer(value) {
10381      *   if (_.isElement(value)) {
10382      *     return value.cloneNode(false);
10383      *   }
10384      * }
10385      *
10386      * var el = _.cloneWith(document.body, customizer);
10387      *
10388      * console.log(el === document.body);
10389      * // => false
10390      * console.log(el.nodeName);
10391      * // => 'BODY'
10392      * console.log(el.childNodes.length);
10393      * // => 0
10394      */
10395     function cloneWith(value, customizer) {
10396       return baseClone(value, false, true, customizer);
10397     }
10398
10399     /**
10400      * This method is like `_.clone` except that it recursively clones `value`.
10401      *
10402      * @static
10403      * @memberOf _
10404      * @since 1.0.0
10405      * @category Lang
10406      * @param {*} value The value to recursively clone.
10407      * @returns {*} Returns the deep cloned value.
10408      * @see _.clone
10409      * @example
10410      *
10411      * var objects = [{ 'a': 1 }, { 'b': 2 }];
10412      *
10413      * var deep = _.cloneDeep(objects);
10414      * console.log(deep[0] === objects[0]);
10415      * // => false
10416      */
10417     function cloneDeep(value) {
10418       return baseClone(value, true, true);
10419     }
10420
10421     /**
10422      * This method is like `_.cloneWith` except that it recursively clones `value`.
10423      *
10424      * @static
10425      * @memberOf _
10426      * @since 4.0.0
10427      * @category Lang
10428      * @param {*} value The value to recursively clone.
10429      * @param {Function} [customizer] The function to customize cloning.
10430      * @returns {*} Returns the deep cloned value.
10431      * @see _.cloneWith
10432      * @example
10433      *
10434      * function customizer(value) {
10435      *   if (_.isElement(value)) {
10436      *     return value.cloneNode(true);
10437      *   }
10438      * }
10439      *
10440      * var el = _.cloneDeepWith(document.body, customizer);
10441      *
10442      * console.log(el === document.body);
10443      * // => false
10444      * console.log(el.nodeName);
10445      * // => 'BODY'
10446      * console.log(el.childNodes.length);
10447      * // => 20
10448      */
10449     function cloneDeepWith(value, customizer) {
10450       return baseClone(value, true, true, customizer);
10451     }
10452
10453     /**
10454      * Performs a
10455      * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
10456      * comparison between two values to determine if they are equivalent.
10457      *
10458      * @static
10459      * @memberOf _
10460      * @since 4.0.0
10461      * @category Lang
10462      * @param {*} value The value to compare.
10463      * @param {*} other The other value to compare.
10464      * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
10465      * @example
10466      *
10467      * var object = { 'user': 'fred' };
10468      * var other = { 'user': 'fred' };
10469      *
10470      * _.eq(object, object);
10471      * // => true
10472      *
10473      * _.eq(object, other);
10474      * // => false
10475      *
10476      * _.eq('a', 'a');
10477      * // => true
10478      *
10479      * _.eq('a', Object('a'));
10480      * // => false
10481      *
10482      * _.eq(NaN, NaN);
10483      * // => true
10484      */
10485     function eq(value, other) {
10486       return value === other || (value !== value && other !== other);
10487     }
10488
10489     /**
10490      * Checks if `value` is greater than `other`.
10491      *
10492      * @static
10493      * @memberOf _
10494      * @since 3.9.0
10495      * @category Lang
10496      * @param {*} value The value to compare.
10497      * @param {*} other The other value to compare.
10498      * @returns {boolean} Returns `true` if `value` is greater than `other`,
10499      *  else `false`.
10500      * @see _.lt
10501      * @example
10502      *
10503      * _.gt(3, 1);
10504      * // => true
10505      *
10506      * _.gt(3, 3);
10507      * // => false
10508      *
10509      * _.gt(1, 3);
10510      * // => false
10511      */
10512     var gt = createRelationalOperation(baseGt);
10513
10514     /**
10515      * Checks if `value` is greater than or equal to `other`.
10516      *
10517      * @static
10518      * @memberOf _
10519      * @since 3.9.0
10520      * @category Lang
10521      * @param {*} value The value to compare.
10522      * @param {*} other The other value to compare.
10523      * @returns {boolean} Returns `true` if `value` is greater than or equal to
10524      *  `other`, else `false`.
10525      * @see _.lte
10526      * @example
10527      *
10528      * _.gte(3, 1);
10529      * // => true
10530      *
10531      * _.gte(3, 3);
10532      * // => true
10533      *
10534      * _.gte(1, 3);
10535      * // => false
10536      */
10537     var gte = createRelationalOperation(function(value, other) {
10538       return value >= other;
10539     });
10540
10541     /**
10542      * Checks if `value` is likely an `arguments` object.
10543      *
10544      * @static
10545      * @memberOf _
10546      * @since 0.1.0
10547      * @category Lang
10548      * @param {*} value The value to check.
10549      * @returns {boolean} Returns `true` if `value` is correctly classified,
10550      *  else `false`.
10551      * @example
10552      *
10553      * _.isArguments(function() { return arguments; }());
10554      * // => true
10555      *
10556      * _.isArguments([1, 2, 3]);
10557      * // => false
10558      */
10559     function isArguments(value) {
10560       // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
10561       return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
10562         (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
10563     }
10564
10565     /**
10566      * Checks if `value` is classified as an `Array` object.
10567      *
10568      * @static
10569      * @memberOf _
10570      * @since 0.1.0
10571      * @type {Function}
10572      * @category Lang
10573      * @param {*} value The value to check.
10574      * @returns {boolean} Returns `true` if `value` is correctly classified,
10575      *  else `false`.
10576      * @example
10577      *
10578      * _.isArray([1, 2, 3]);
10579      * // => true
10580      *
10581      * _.isArray(document.body.children);
10582      * // => false
10583      *
10584      * _.isArray('abc');
10585      * // => false
10586      *
10587      * _.isArray(_.noop);
10588      * // => false
10589      */
10590     var isArray = Array.isArray;
10591
10592     /**
10593      * Checks if `value` is classified as an `ArrayBuffer` object.
10594      *
10595      * @static
10596      * @memberOf _
10597      * @since 4.3.0
10598      * @category Lang
10599      * @param {*} value The value to check.
10600      * @returns {boolean} Returns `true` if `value` is correctly classified,
10601      *  else `false`.
10602      * @example
10603      *
10604      * _.isArrayBuffer(new ArrayBuffer(2));
10605      * // => true
10606      *
10607      * _.isArrayBuffer(new Array(2));
10608      * // => false
10609      */
10610     function isArrayBuffer(value) {
10611       return isObjectLike(value) && objectToString.call(value) == arrayBufferTag;
10612     }
10613
10614     /**
10615      * Checks if `value` is array-like. A value is considered array-like if it's
10616      * not a function and has a `value.length` that's an integer greater than or
10617      * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
10618      *
10619      * @static
10620      * @memberOf _
10621      * @since 4.0.0
10622      * @category Lang
10623      * @param {*} value The value to check.
10624      * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
10625      * @example
10626      *
10627      * _.isArrayLike([1, 2, 3]);
10628      * // => true
10629      *
10630      * _.isArrayLike(document.body.children);
10631      * // => true
10632      *
10633      * _.isArrayLike('abc');
10634      * // => true
10635      *
10636      * _.isArrayLike(_.noop);
10637      * // => false
10638      */
10639     function isArrayLike(value) {
10640       return value != null && isLength(getLength(value)) && !isFunction(value);
10641     }
10642
10643     /**
10644      * This method is like `_.isArrayLike` except that it also checks if `value`
10645      * is an object.
10646      *
10647      * @static
10648      * @memberOf _
10649      * @since 4.0.0
10650      * @category Lang
10651      * @param {*} value The value to check.
10652      * @returns {boolean} Returns `true` if `value` is an array-like object,
10653      *  else `false`.
10654      * @example
10655      *
10656      * _.isArrayLikeObject([1, 2, 3]);
10657      * // => true
10658      *
10659      * _.isArrayLikeObject(document.body.children);
10660      * // => true
10661      *
10662      * _.isArrayLikeObject('abc');
10663      * // => false
10664      *
10665      * _.isArrayLikeObject(_.noop);
10666      * // => false
10667      */
10668     function isArrayLikeObject(value) {
10669       return isObjectLike(value) && isArrayLike(value);
10670     }
10671
10672     /**
10673      * Checks if `value` is classified as a boolean primitive or object.
10674      *
10675      * @static
10676      * @memberOf _
10677      * @since 0.1.0
10678      * @category Lang
10679      * @param {*} value The value to check.
10680      * @returns {boolean} Returns `true` if `value` is correctly classified,
10681      *  else `false`.
10682      * @example
10683      *
10684      * _.isBoolean(false);
10685      * // => true
10686      *
10687      * _.isBoolean(null);
10688      * // => false
10689      */
10690     function isBoolean(value) {
10691       return value === true || value === false ||
10692         (isObjectLike(value) && objectToString.call(value) == boolTag);
10693     }
10694
10695     /**
10696      * Checks if `value` is a buffer.
10697      *
10698      * @static
10699      * @memberOf _
10700      * @since 4.3.0
10701      * @category Lang
10702      * @param {*} value The value to check.
10703      * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
10704      * @example
10705      *
10706      * _.isBuffer(new Buffer(2));
10707      * // => true
10708      *
10709      * _.isBuffer(new Uint8Array(2));
10710      * // => false
10711      */
10712     var isBuffer = !Buffer ? stubFalse : function(value) {
10713       return value instanceof Buffer;
10714     };
10715
10716     /**
10717      * Checks if `value` is classified as a `Date` object.
10718      *
10719      * @static
10720      * @memberOf _
10721      * @since 0.1.0
10722      * @category Lang
10723      * @param {*} value The value to check.
10724      * @returns {boolean} Returns `true` if `value` is correctly classified,
10725      *  else `false`.
10726      * @example
10727      *
10728      * _.isDate(new Date);
10729      * // => true
10730      *
10731      * _.isDate('Mon April 23 2012');
10732      * // => false
10733      */
10734     function isDate(value) {
10735       return isObjectLike(value) && objectToString.call(value) == dateTag;
10736     }
10737
10738     /**
10739      * Checks if `value` is likely a DOM element.
10740      *
10741      * @static
10742      * @memberOf _
10743      * @since 0.1.0
10744      * @category Lang
10745      * @param {*} value The value to check.
10746      * @returns {boolean} Returns `true` if `value` is a DOM element,
10747      *  else `false`.
10748      * @example
10749      *
10750      * _.isElement(document.body);
10751      * // => true
10752      *
10753      * _.isElement('<body>');
10754      * // => false
10755      */
10756     function isElement(value) {
10757       return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
10758     }
10759
10760     /**
10761      * Checks if `value` is an empty object, collection, map, or set.
10762      *
10763      * Objects are considered empty if they have no own enumerable string keyed
10764      * properties.
10765      *
10766      * Array-like values such as `arguments` objects, arrays, buffers, strings, or
10767      * jQuery-like collections are considered empty if they have a `length` of `0`.
10768      * Similarly, maps and sets are considered empty if they have a `size` of `0`.
10769      *
10770      * @static
10771      * @memberOf _
10772      * @since 0.1.0
10773      * @category Lang
10774      * @param {*} value The value to check.
10775      * @returns {boolean} Returns `true` if `value` is empty, else `false`.
10776      * @example
10777      *
10778      * _.isEmpty(null);
10779      * // => true
10780      *
10781      * _.isEmpty(true);
10782      * // => true
10783      *
10784      * _.isEmpty(1);
10785      * // => true
10786      *
10787      * _.isEmpty([1, 2, 3]);
10788      * // => false
10789      *
10790      * _.isEmpty({ 'a': 1 });
10791      * // => false
10792      */
10793     function isEmpty(value) {
10794       if (isArrayLike(value) &&
10795           (isArray(value) || isString(value) || isFunction(value.splice) ||
10796             isArguments(value) || isBuffer(value))) {
10797         return !value.length;
10798       }
10799       if (isObjectLike(value)) {
10800         var tag = getTag(value);
10801         if (tag == mapTag || tag == setTag) {
10802           return !value.size;
10803         }
10804       }
10805       for (var key in value) {
10806         if (hasOwnProperty.call(value, key)) {
10807           return false;
10808         }
10809       }
10810       return !(nonEnumShadows && keys(value).length);
10811     }
10812
10813     /**
10814      * Performs a deep comparison between two values to determine if they are
10815      * equivalent.
10816      *
10817      * **Note:** This method supports comparing arrays, array buffers, booleans,
10818      * date objects, error objects, maps, numbers, `Object` objects, regexes,
10819      * sets, strings, symbols, and typed arrays. `Object` objects are compared
10820      * by their own, not inherited, enumerable properties. Functions and DOM
10821      * nodes are **not** supported.
10822      *
10823      * @static
10824      * @memberOf _
10825      * @since 0.1.0
10826      * @category Lang
10827      * @param {*} value The value to compare.
10828      * @param {*} other The other value to compare.
10829      * @returns {boolean} Returns `true` if the values are equivalent,
10830      *  else `false`.
10831      * @example
10832      *
10833      * var object = { 'user': 'fred' };
10834      * var other = { 'user': 'fred' };
10835      *
10836      * _.isEqual(object, other);
10837      * // => true
10838      *
10839      * object === other;
10840      * // => false
10841      */
10842     function isEqual(value, other) {
10843       return baseIsEqual(value, other);
10844     }
10845
10846     /**
10847      * This method is like `_.isEqual` except that it accepts `customizer` which
10848      * is invoked to compare values. If `customizer` returns `undefined`, comparisons
10849      * are handled by the method instead. The `customizer` is invoked with up to
10850      * six arguments: (objValue, othValue [, index|key, object, other, stack]).
10851      *
10852      * @static
10853      * @memberOf _
10854      * @since 4.0.0
10855      * @category Lang
10856      * @param {*} value The value to compare.
10857      * @param {*} other The other value to compare.
10858      * @param {Function} [customizer] The function to customize comparisons.
10859      * @returns {boolean} Returns `true` if the values are equivalent,
10860      *  else `false`.
10861      * @example
10862      *
10863      * function isGreeting(value) {
10864      *   return /^h(?:i|ello)$/.test(value);
10865      * }
10866      *
10867      * function customizer(objValue, othValue) {
10868      *   if (isGreeting(objValue) && isGreeting(othValue)) {
10869      *     return true;
10870      *   }
10871      * }
10872      *
10873      * var array = ['hello', 'goodbye'];
10874      * var other = ['hi', 'goodbye'];
10875      *
10876      * _.isEqualWith(array, other, customizer);
10877      * // => true
10878      */
10879     function isEqualWith(value, other, customizer) {
10880       customizer = typeof customizer == 'function' ? customizer : undefined;
10881       var result = customizer ? customizer(value, other) : undefined;
10882       return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
10883     }
10884
10885     /**
10886      * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
10887      * `SyntaxError`, `TypeError`, or `URIError` object.
10888      *
10889      * @static
10890      * @memberOf _
10891      * @since 3.0.0
10892      * @category Lang
10893      * @param {*} value The value to check.
10894      * @returns {boolean} Returns `true` if `value` is an error object,
10895      *  else `false`.
10896      * @example
10897      *
10898      * _.isError(new Error);
10899      * // => true
10900      *
10901      * _.isError(Error);
10902      * // => false
10903      */
10904     function isError(value) {
10905       if (!isObjectLike(value)) {
10906         return false;
10907       }
10908       return (objectToString.call(value) == errorTag) ||
10909         (typeof value.message == 'string' && typeof value.name == 'string');
10910     }
10911
10912     /**
10913      * Checks if `value` is a finite primitive number.
10914      *
10915      * **Note:** This method is based on
10916      * [`Number.isFinite`](https://mdn.io/Number/isFinite).
10917      *
10918      * @static
10919      * @memberOf _
10920      * @since 0.1.0
10921      * @category Lang
10922      * @param {*} value The value to check.
10923      * @returns {boolean} Returns `true` if `value` is a finite number,
10924      *  else `false`.
10925      * @example
10926      *
10927      * _.isFinite(3);
10928      * // => true
10929      *
10930      * _.isFinite(Number.MIN_VALUE);
10931      * // => true
10932      *
10933      * _.isFinite(Infinity);
10934      * // => false
10935      *
10936      * _.isFinite('3');
10937      * // => false
10938      */
10939     function isFinite(value) {
10940       return typeof value == 'number' && nativeIsFinite(value);
10941     }
10942
10943     /**
10944      * Checks if `value` is classified as a `Function` object.
10945      *
10946      * @static
10947      * @memberOf _
10948      * @since 0.1.0
10949      * @category Lang
10950      * @param {*} value The value to check.
10951      * @returns {boolean} Returns `true` if `value` is correctly classified,
10952      *  else `false`.
10953      * @example
10954      *
10955      * _.isFunction(_);
10956      * // => true
10957      *
10958      * _.isFunction(/abc/);
10959      * // => false
10960      */
10961     function isFunction(value) {
10962       // The use of `Object#toString` avoids issues with the `typeof` operator
10963       // in Safari 8 which returns 'object' for typed array and weak map constructors,
10964       // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
10965       var tag = isObject(value) ? objectToString.call(value) : '';
10966       return tag == funcTag || tag == genTag;
10967     }
10968
10969     /**
10970      * Checks if `value` is an integer.
10971      *
10972      * **Note:** This method is based on
10973      * [`Number.isInteger`](https://mdn.io/Number/isInteger).
10974      *
10975      * @static
10976      * @memberOf _
10977      * @since 4.0.0
10978      * @category Lang
10979      * @param {*} value The value to check.
10980      * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
10981      * @example
10982      *
10983      * _.isInteger(3);
10984      * // => true
10985      *
10986      * _.isInteger(Number.MIN_VALUE);
10987      * // => false
10988      *
10989      * _.isInteger(Infinity);
10990      * // => false
10991      *
10992      * _.isInteger('3');
10993      * // => false
10994      */
10995     function isInteger(value) {
10996       return typeof value == 'number' && value == toInteger(value);
10997     }
10998
10999     /**
11000      * Checks if `value` is a valid array-like length.
11001      *
11002      * **Note:** This function is loosely based on
11003      * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
11004      *
11005      * @static
11006      * @memberOf _
11007      * @since 4.0.0
11008      * @category Lang
11009      * @param {*} value The value to check.
11010      * @returns {boolean} Returns `true` if `value` is a valid length,
11011      *  else `false`.
11012      * @example
11013      *
11014      * _.isLength(3);
11015      * // => true
11016      *
11017      * _.isLength(Number.MIN_VALUE);
11018      * // => false
11019      *
11020      * _.isLength(Infinity);
11021      * // => false
11022      *
11023      * _.isLength('3');
11024      * // => false
11025      */
11026     function isLength(value) {
11027       return typeof value == 'number' &&
11028         value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
11029     }
11030
11031     /**
11032      * Checks if `value` is the
11033      * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)
11034      * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
11035      *
11036      * @static
11037      * @memberOf _
11038      * @since 0.1.0
11039      * @category Lang
11040      * @param {*} value The value to check.
11041      * @returns {boolean} Returns `true` if `value` is an object, else `false`.
11042      * @example
11043      *
11044      * _.isObject({});
11045      * // => true
11046      *
11047      * _.isObject([1, 2, 3]);
11048      * // => true
11049      *
11050      * _.isObject(_.noop);
11051      * // => true
11052      *
11053      * _.isObject(null);
11054      * // => false
11055      */
11056     function isObject(value) {
11057       var type = typeof value;
11058       return !!value && (type == 'object' || type == 'function');
11059     }
11060
11061     /**
11062      * Checks if `value` is object-like. A value is object-like if it's not `null`
11063      * and has a `typeof` result of "object".
11064      *
11065      * @static
11066      * @memberOf _
11067      * @since 4.0.0
11068      * @category Lang
11069      * @param {*} value The value to check.
11070      * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
11071      * @example
11072      *
11073      * _.isObjectLike({});
11074      * // => true
11075      *
11076      * _.isObjectLike([1, 2, 3]);
11077      * // => true
11078      *
11079      * _.isObjectLike(_.noop);
11080      * // => false
11081      *
11082      * _.isObjectLike(null);
11083      * // => false
11084      */
11085     function isObjectLike(value) {
11086       return !!value && typeof value == 'object';
11087     }
11088
11089     /**
11090      * Checks if `value` is classified as a `Map` object.
11091      *
11092      * @static
11093      * @memberOf _
11094      * @since 4.3.0
11095      * @category Lang
11096      * @param {*} value The value to check.
11097      * @returns {boolean} Returns `true` if `value` is correctly classified,
11098      *  else `false`.
11099      * @example
11100      *
11101      * _.isMap(new Map);
11102      * // => true
11103      *
11104      * _.isMap(new WeakMap);
11105      * // => false
11106      */
11107     function isMap(value) {
11108       return isObjectLike(value) && getTag(value) == mapTag;
11109     }
11110
11111     /**
11112      * Performs a partial deep comparison between `object` and `source` to
11113      * determine if `object` contains equivalent property values. This method is
11114      * equivalent to a `_.matches` function when `source` is partially applied.
11115      *
11116      * **Note:** This method supports comparing the same values as `_.isEqual`.
11117      *
11118      * @static
11119      * @memberOf _
11120      * @since 3.0.0
11121      * @category Lang
11122      * @param {Object} object The object to inspect.
11123      * @param {Object} source The object of property values to match.
11124      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11125      * @example
11126      *
11127      * var object = { 'user': 'fred', 'age': 40 };
11128      *
11129      * _.isMatch(object, { 'age': 40 });
11130      * // => true
11131      *
11132      * _.isMatch(object, { 'age': 36 });
11133      * // => false
11134      */
11135     function isMatch(object, source) {
11136       return object === source || baseIsMatch(object, source, getMatchData(source));
11137     }
11138
11139     /**
11140      * This method is like `_.isMatch` except that it accepts `customizer` which
11141      * is invoked to compare values. If `customizer` returns `undefined`, comparisons
11142      * are handled by the method instead. The `customizer` is invoked with five
11143      * arguments: (objValue, srcValue, index|key, object, source).
11144      *
11145      * @static
11146      * @memberOf _
11147      * @since 4.0.0
11148      * @category Lang
11149      * @param {Object} object The object to inspect.
11150      * @param {Object} source The object of property values to match.
11151      * @param {Function} [customizer] The function to customize comparisons.
11152      * @returns {boolean} Returns `true` if `object` is a match, else `false`.
11153      * @example
11154      *
11155      * function isGreeting(value) {
11156      *   return /^h(?:i|ello)$/.test(value);
11157      * }
11158      *
11159      * function customizer(objValue, srcValue) {
11160      *   if (isGreeting(objValue) && isGreeting(srcValue)) {
11161      *     return true;
11162      *   }
11163      * }
11164      *
11165      * var object = { 'greeting': 'hello' };
11166      * var source = { 'greeting': 'hi' };
11167      *
11168      * _.isMatchWith(object, source, customizer);
11169      * // => true
11170      */
11171     function isMatchWith(object, source, customizer) {
11172       customizer = typeof customizer == 'function' ? customizer : undefined;
11173       return baseIsMatch(object, source, getMatchData(source), customizer);
11174     }
11175
11176     /**
11177      * Checks if `value` is `NaN`.
11178      *
11179      * **Note:** This method is based on
11180      * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
11181      * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
11182      * `undefined` and other non-number values.
11183      *
11184      * @static
11185      * @memberOf _
11186      * @since 0.1.0
11187      * @category Lang
11188      * @param {*} value The value to check.
11189      * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
11190      * @example
11191      *
11192      * _.isNaN(NaN);
11193      * // => true
11194      *
11195      * _.isNaN(new Number(NaN));
11196      * // => true
11197      *
11198      * isNaN(undefined);
11199      * // => true
11200      *
11201      * _.isNaN(undefined);
11202      * // => false
11203      */
11204     function isNaN(value) {
11205       // An `NaN` primitive is the only value that is not equal to itself.
11206       // Perform the `toStringTag` check first to avoid errors with some
11207       // ActiveX objects in IE.
11208       return isNumber(value) && value != +value;
11209     }
11210
11211     /**
11212      * Checks if `value` is a pristine native function.
11213      *
11214      * **Note:** This method can't reliably detect native functions in the
11215      * presence of the `core-js` package because `core-js` circumvents this kind
11216      * of detection. Despite multiple requests, the `core-js` maintainer has made
11217      * it clear: any attempt to fix the detection will be obstructed. As a result,
11218      * we're left with little choice but to throw an error. Unfortunately, this
11219      * also affects packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
11220      * which rely on `core-js`.
11221      *
11222      * @static
11223      * @memberOf _
11224      * @since 3.0.0
11225      * @category Lang
11226      * @param {*} value The value to check.
11227      * @returns {boolean} Returns `true` if `value` is a native function,
11228      *  else `false`.
11229      * @example
11230      *
11231      * _.isNative(Array.prototype.push);
11232      * // => true
11233      *
11234      * _.isNative(_);
11235      * // => false
11236      */
11237     function isNative(value) {
11238       if (isMaskable(value)) {
11239         throw new Error('This method is not supported with `core-js`. Try https://github.com/es-shims.');
11240       }
11241       return baseIsNative(value);
11242     }
11243
11244     /**
11245      * Checks if `value` is `null`.
11246      *
11247      * @static
11248      * @memberOf _
11249      * @since 0.1.0
11250      * @category Lang
11251      * @param {*} value The value to check.
11252      * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
11253      * @example
11254      *
11255      * _.isNull(null);
11256      * // => true
11257      *
11258      * _.isNull(void 0);
11259      * // => false
11260      */
11261     function isNull(value) {
11262       return value === null;
11263     }
11264
11265     /**
11266      * Checks if `value` is `null` or `undefined`.
11267      *
11268      * @static
11269      * @memberOf _
11270      * @since 4.0.0
11271      * @category Lang
11272      * @param {*} value The value to check.
11273      * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
11274      * @example
11275      *
11276      * _.isNil(null);
11277      * // => true
11278      *
11279      * _.isNil(void 0);
11280      * // => true
11281      *
11282      * _.isNil(NaN);
11283      * // => false
11284      */
11285     function isNil(value) {
11286       return value == null;
11287     }
11288
11289     /**
11290      * Checks if `value` is classified as a `Number` primitive or object.
11291      *
11292      * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
11293      * classified as numbers, use the `_.isFinite` method.
11294      *
11295      * @static
11296      * @memberOf _
11297      * @since 0.1.0
11298      * @category Lang
11299      * @param {*} value The value to check.
11300      * @returns {boolean} Returns `true` if `value` is correctly classified,
11301      *  else `false`.
11302      * @example
11303      *
11304      * _.isNumber(3);
11305      * // => true
11306      *
11307      * _.isNumber(Number.MIN_VALUE);
11308      * // => true
11309      *
11310      * _.isNumber(Infinity);
11311      * // => true
11312      *
11313      * _.isNumber('3');
11314      * // => false
11315      */
11316     function isNumber(value) {
11317       return typeof value == 'number' ||
11318         (isObjectLike(value) && objectToString.call(value) == numberTag);
11319     }
11320
11321     /**
11322      * Checks if `value` is a plain object, that is, an object created by the
11323      * `Object` constructor or one with a `[[Prototype]]` of `null`.
11324      *
11325      * @static
11326      * @memberOf _
11327      * @since 0.8.0
11328      * @category Lang
11329      * @param {*} value The value to check.
11330      * @returns {boolean} Returns `true` if `value` is a plain object,
11331      *  else `false`.
11332      * @example
11333      *
11334      * function Foo() {
11335      *   this.a = 1;
11336      * }
11337      *
11338      * _.isPlainObject(new Foo);
11339      * // => false
11340      *
11341      * _.isPlainObject([1, 2, 3]);
11342      * // => false
11343      *
11344      * _.isPlainObject({ 'x': 0, 'y': 0 });
11345      * // => true
11346      *
11347      * _.isPlainObject(Object.create(null));
11348      * // => true
11349      */
11350     function isPlainObject(value) {
11351       if (!isObjectLike(value) ||
11352           objectToString.call(value) != objectTag || isHostObject(value)) {
11353         return false;
11354       }
11355       var proto = getPrototype(value);
11356       if (proto === null) {
11357         return true;
11358       }
11359       var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
11360       return (typeof Ctor == 'function' &&
11361         Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
11362     }
11363
11364     /**
11365      * Checks if `value` is classified as a `RegExp` object.
11366      *
11367      * @static
11368      * @memberOf _
11369      * @since 0.1.0
11370      * @category Lang
11371      * @param {*} value The value to check.
11372      * @returns {boolean} Returns `true` if `value` is correctly classified,
11373      *  else `false`.
11374      * @example
11375      *
11376      * _.isRegExp(/abc/);
11377      * // => true
11378      *
11379      * _.isRegExp('/abc/');
11380      * // => false
11381      */
11382     function isRegExp(value) {
11383       return isObject(value) && objectToString.call(value) == regexpTag;
11384     }
11385
11386     /**
11387      * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
11388      * double precision number which isn't the result of a rounded unsafe integer.
11389      *
11390      * **Note:** This method is based on
11391      * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
11392      *
11393      * @static
11394      * @memberOf _
11395      * @since 4.0.0
11396      * @category Lang
11397      * @param {*} value The value to check.
11398      * @returns {boolean} Returns `true` if `value` is a safe integer,
11399      *  else `false`.
11400      * @example
11401      *
11402      * _.isSafeInteger(3);
11403      * // => true
11404      *
11405      * _.isSafeInteger(Number.MIN_VALUE);
11406      * // => false
11407      *
11408      * _.isSafeInteger(Infinity);
11409      * // => false
11410      *
11411      * _.isSafeInteger('3');
11412      * // => false
11413      */
11414     function isSafeInteger(value) {
11415       return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
11416     }
11417
11418     /**
11419      * Checks if `value` is classified as a `Set` object.
11420      *
11421      * @static
11422      * @memberOf _
11423      * @since 4.3.0
11424      * @category Lang
11425      * @param {*} value The value to check.
11426      * @returns {boolean} Returns `true` if `value` is correctly classified,
11427      *  else `false`.
11428      * @example
11429      *
11430      * _.isSet(new Set);
11431      * // => true
11432      *
11433      * _.isSet(new WeakSet);
11434      * // => false
11435      */
11436     function isSet(value) {
11437       return isObjectLike(value) && getTag(value) == setTag;
11438     }
11439
11440     /**
11441      * Checks if `value` is classified as a `String` primitive or object.
11442      *
11443      * @static
11444      * @since 0.1.0
11445      * @memberOf _
11446      * @category Lang
11447      * @param {*} value The value to check.
11448      * @returns {boolean} Returns `true` if `value` is correctly classified,
11449      *  else `false`.
11450      * @example
11451      *
11452      * _.isString('abc');
11453      * // => true
11454      *
11455      * _.isString(1);
11456      * // => false
11457      */
11458     function isString(value) {
11459       return typeof value == 'string' ||
11460         (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
11461     }
11462
11463     /**
11464      * Checks if `value` is classified as a `Symbol` primitive or object.
11465      *
11466      * @static
11467      * @memberOf _
11468      * @since 4.0.0
11469      * @category Lang
11470      * @param {*} value The value to check.
11471      * @returns {boolean} Returns `true` if `value` is correctly classified,
11472      *  else `false`.
11473      * @example
11474      *
11475      * _.isSymbol(Symbol.iterator);
11476      * // => true
11477      *
11478      * _.isSymbol('abc');
11479      * // => false
11480      */
11481     function isSymbol(value) {
11482       return typeof value == 'symbol' ||
11483         (isObjectLike(value) && objectToString.call(value) == symbolTag);
11484     }
11485
11486     /**
11487      * Checks if `value` is classified as a typed array.
11488      *
11489      * @static
11490      * @memberOf _
11491      * @since 3.0.0
11492      * @category Lang
11493      * @param {*} value The value to check.
11494      * @returns {boolean} Returns `true` if `value` is correctly classified,
11495      *  else `false`.
11496      * @example
11497      *
11498      * _.isTypedArray(new Uint8Array);
11499      * // => true
11500      *
11501      * _.isTypedArray([]);
11502      * // => false
11503      */
11504     function isTypedArray(value) {
11505       return isObjectLike(value) &&
11506         isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
11507     }
11508
11509     /**
11510      * Checks if `value` is `undefined`.
11511      *
11512      * @static
11513      * @since 0.1.0
11514      * @memberOf _
11515      * @category Lang
11516      * @param {*} value The value to check.
11517      * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
11518      * @example
11519      *
11520      * _.isUndefined(void 0);
11521      * // => true
11522      *
11523      * _.isUndefined(null);
11524      * // => false
11525      */
11526     function isUndefined(value) {
11527       return value === undefined;
11528     }
11529
11530     /**
11531      * Checks if `value` is classified as a `WeakMap` object.
11532      *
11533      * @static
11534      * @memberOf _
11535      * @since 4.3.0
11536      * @category Lang
11537      * @param {*} value The value to check.
11538      * @returns {boolean} Returns `true` if `value` is correctly classified,
11539      *  else `false`.
11540      * @example
11541      *
11542      * _.isWeakMap(new WeakMap);
11543      * // => true
11544      *
11545      * _.isWeakMap(new Map);
11546      * // => false
11547      */
11548     function isWeakMap(value) {
11549       return isObjectLike(value) && getTag(value) == weakMapTag;
11550     }
11551
11552     /**
11553      * Checks if `value` is classified as a `WeakSet` object.
11554      *
11555      * @static
11556      * @memberOf _
11557      * @since 4.3.0
11558      * @category Lang
11559      * @param {*} value The value to check.
11560      * @returns {boolean} Returns `true` if `value` is correctly classified,
11561      *  else `false`.
11562      * @example
11563      *
11564      * _.isWeakSet(new WeakSet);
11565      * // => true
11566      *
11567      * _.isWeakSet(new Set);
11568      * // => false
11569      */
11570     function isWeakSet(value) {
11571       return isObjectLike(value) && objectToString.call(value) == weakSetTag;
11572     }
11573
11574     /**
11575      * Checks if `value` is less than `other`.
11576      *
11577      * @static
11578      * @memberOf _
11579      * @since 3.9.0
11580      * @category Lang
11581      * @param {*} value The value to compare.
11582      * @param {*} other The other value to compare.
11583      * @returns {boolean} Returns `true` if `value` is less than `other`,
11584      *  else `false`.
11585      * @see _.gt
11586      * @example
11587      *
11588      * _.lt(1, 3);
11589      * // => true
11590      *
11591      * _.lt(3, 3);
11592      * // => false
11593      *
11594      * _.lt(3, 1);
11595      * // => false
11596      */
11597     var lt = createRelationalOperation(baseLt);
11598
11599     /**
11600      * Checks if `value` is less than or equal to `other`.
11601      *
11602      * @static
11603      * @memberOf _
11604      * @since 3.9.0
11605      * @category Lang
11606      * @param {*} value The value to compare.
11607      * @param {*} other The other value to compare.
11608      * @returns {boolean} Returns `true` if `value` is less than or equal to
11609      *  `other`, else `false`.
11610      * @see _.gte
11611      * @example
11612      *
11613      * _.lte(1, 3);
11614      * // => true
11615      *
11616      * _.lte(3, 3);
11617      * // => true
11618      *
11619      * _.lte(3, 1);
11620      * // => false
11621      */
11622     var lte = createRelationalOperation(function(value, other) {
11623       return value <= other;
11624     });
11625
11626     /**
11627      * Converts `value` to an array.
11628      *
11629      * @static
11630      * @since 0.1.0
11631      * @memberOf _
11632      * @category Lang
11633      * @param {*} value The value to convert.
11634      * @returns {Array} Returns the converted array.
11635      * @example
11636      *
11637      * _.toArray({ 'a': 1, 'b': 2 });
11638      * // => [1, 2]
11639      *
11640      * _.toArray('abc');
11641      * // => ['a', 'b', 'c']
11642      *
11643      * _.toArray(1);
11644      * // => []
11645      *
11646      * _.toArray(null);
11647      * // => []
11648      */
11649     function toArray(value) {
11650       if (!value) {
11651         return [];
11652       }
11653       if (isArrayLike(value)) {
11654         return isString(value) ? stringToArray(value) : copyArray(value);
11655       }
11656       if (iteratorSymbol && value[iteratorSymbol]) {
11657         return iteratorToArray(value[iteratorSymbol]());
11658       }
11659       var tag = getTag(value),
11660           func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
11661
11662       return func(value);
11663     }
11664
11665     /**
11666      * Converts `value` to a finite number.
11667      *
11668      * @static
11669      * @memberOf _
11670      * @since 4.12.0
11671      * @category Lang
11672      * @param {*} value The value to convert.
11673      * @returns {number} Returns the converted number.
11674      * @example
11675      *
11676      * _.toFinite(3.2);
11677      * // => 3.2
11678      *
11679      * _.toFinite(Number.MIN_VALUE);
11680      * // => 5e-324
11681      *
11682      * _.toFinite(Infinity);
11683      * // => 1.7976931348623157e+308
11684      *
11685      * _.toFinite('3.2');
11686      * // => 3.2
11687      */
11688     function toFinite(value) {
11689       if (!value) {
11690         return value === 0 ? value : 0;
11691       }
11692       value = toNumber(value);
11693       if (value === INFINITY || value === -INFINITY) {
11694         var sign = (value < 0 ? -1 : 1);
11695         return sign * MAX_INTEGER;
11696       }
11697       return value === value ? value : 0;
11698     }
11699
11700     /**
11701      * Converts `value` to an integer.
11702      *
11703      * **Note:** This method is loosely based on
11704      * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
11705      *
11706      * @static
11707      * @memberOf _
11708      * @since 4.0.0
11709      * @category Lang
11710      * @param {*} value The value to convert.
11711      * @returns {number} Returns the converted integer.
11712      * @example
11713      *
11714      * _.toInteger(3.2);
11715      * // => 3
11716      *
11717      * _.toInteger(Number.MIN_VALUE);
11718      * // => 0
11719      *
11720      * _.toInteger(Infinity);
11721      * // => 1.7976931348623157e+308
11722      *
11723      * _.toInteger('3.2');
11724      * // => 3
11725      */
11726     function toInteger(value) {
11727       var result = toFinite(value),
11728           remainder = result % 1;
11729
11730       return result === result ? (remainder ? result - remainder : result) : 0;
11731     }
11732
11733     /**
11734      * Converts `value` to an integer suitable for use as the length of an
11735      * array-like object.
11736      *
11737      * **Note:** This method is based on
11738      * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
11739      *
11740      * @static
11741      * @memberOf _
11742      * @since 4.0.0
11743      * @category Lang
11744      * @param {*} value The value to convert.
11745      * @returns {number} Returns the converted integer.
11746      * @example
11747      *
11748      * _.toLength(3.2);
11749      * // => 3
11750      *
11751      * _.toLength(Number.MIN_VALUE);
11752      * // => 0
11753      *
11754      * _.toLength(Infinity);
11755      * // => 4294967295
11756      *
11757      * _.toLength('3.2');
11758      * // => 3
11759      */
11760     function toLength(value) {
11761       return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
11762     }
11763
11764     /**
11765      * Converts `value` to a number.
11766      *
11767      * @static
11768      * @memberOf _
11769      * @since 4.0.0
11770      * @category Lang
11771      * @param {*} value The value to process.
11772      * @returns {number} Returns the number.
11773      * @example
11774      *
11775      * _.toNumber(3.2);
11776      * // => 3.2
11777      *
11778      * _.toNumber(Number.MIN_VALUE);
11779      * // => 5e-324
11780      *
11781      * _.toNumber(Infinity);
11782      * // => Infinity
11783      *
11784      * _.toNumber('3.2');
11785      * // => 3.2
11786      */
11787     function toNumber(value) {
11788       if (typeof value == 'number') {
11789         return value;
11790       }
11791       if (isSymbol(value)) {
11792         return NAN;
11793       }
11794       if (isObject(value)) {
11795         var other = isFunction(value.valueOf) ? value.valueOf() : value;
11796         value = isObject(other) ? (other + '') : other;
11797       }
11798       if (typeof value != 'string') {
11799         return value === 0 ? value : +value;
11800       }
11801       value = value.replace(reTrim, '');
11802       var isBinary = reIsBinary.test(value);
11803       return (isBinary || reIsOctal.test(value))
11804         ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
11805         : (reIsBadHex.test(value) ? NAN : +value);
11806     }
11807
11808     /**
11809      * Converts `value` to a plain object flattening inherited enumerable string
11810      * keyed properties of `value` to own properties of the plain object.
11811      *
11812      * @static
11813      * @memberOf _
11814      * @since 3.0.0
11815      * @category Lang
11816      * @param {*} value The value to convert.
11817      * @returns {Object} Returns the converted plain object.
11818      * @example
11819      *
11820      * function Foo() {
11821      *   this.b = 2;
11822      * }
11823      *
11824      * Foo.prototype.c = 3;
11825      *
11826      * _.assign({ 'a': 1 }, new Foo);
11827      * // => { 'a': 1, 'b': 2 }
11828      *
11829      * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
11830      * // => { 'a': 1, 'b': 2, 'c': 3 }
11831      */
11832     function toPlainObject(value) {
11833       return copyObject(value, keysIn(value));
11834     }
11835
11836     /**
11837      * Converts `value` to a safe integer. A safe integer can be compared and
11838      * represented correctly.
11839      *
11840      * @static
11841      * @memberOf _
11842      * @since 4.0.0
11843      * @category Lang
11844      * @param {*} value The value to convert.
11845      * @returns {number} Returns the converted integer.
11846      * @example
11847      *
11848      * _.toSafeInteger(3.2);
11849      * // => 3
11850      *
11851      * _.toSafeInteger(Number.MIN_VALUE);
11852      * // => 0
11853      *
11854      * _.toSafeInteger(Infinity);
11855      * // => 9007199254740991
11856      *
11857      * _.toSafeInteger('3.2');
11858      * // => 3
11859      */
11860     function toSafeInteger(value) {
11861       return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
11862     }
11863
11864     /**
11865      * Converts `value` to a string. An empty string is returned for `null`
11866      * and `undefined` values. The sign of `-0` is preserved.
11867      *
11868      * @static
11869      * @memberOf _
11870      * @since 4.0.0
11871      * @category Lang
11872      * @param {*} value The value to process.
11873      * @returns {string} Returns the string.
11874      * @example
11875      *
11876      * _.toString(null);
11877      * // => ''
11878      *
11879      * _.toString(-0);
11880      * // => '-0'
11881      *
11882      * _.toString([1, 2, 3]);
11883      * // => '1,2,3'
11884      */
11885     function toString(value) {
11886       return value == null ? '' : baseToString(value);
11887     }
11888
11889     /*------------------------------------------------------------------------*/
11890
11891     /**
11892      * Assigns own enumerable string keyed properties of source objects to the
11893      * destination object. Source objects are applied from left to right.
11894      * Subsequent sources overwrite property assignments of previous sources.
11895      *
11896      * **Note:** This method mutates `object` and is loosely based on
11897      * [`Object.assign`](https://mdn.io/Object/assign).
11898      *
11899      * @static
11900      * @memberOf _
11901      * @since 0.10.0
11902      * @category Object
11903      * @param {Object} object The destination object.
11904      * @param {...Object} [sources] The source objects.
11905      * @returns {Object} Returns `object`.
11906      * @see _.assignIn
11907      * @example
11908      *
11909      * function Foo() {
11910      *   this.c = 3;
11911      * }
11912      *
11913      * function Bar() {
11914      *   this.e = 5;
11915      * }
11916      *
11917      * Foo.prototype.d = 4;
11918      * Bar.prototype.f = 6;
11919      *
11920      * _.assign({ 'a': 1 }, new Foo, new Bar);
11921      * // => { 'a': 1, 'c': 3, 'e': 5 }
11922      */
11923     var assign = createAssigner(function(object, source) {
11924       if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {
11925         copyObject(source, keys(source), object);
11926         return;
11927       }
11928       for (var key in source) {
11929         if (hasOwnProperty.call(source, key)) {
11930           assignValue(object, key, source[key]);
11931         }
11932       }
11933     });
11934
11935     /**
11936      * This method is like `_.assign` except that it iterates over own and
11937      * inherited source properties.
11938      *
11939      * **Note:** This method mutates `object`.
11940      *
11941      * @static
11942      * @memberOf _
11943      * @since 4.0.0
11944      * @alias extend
11945      * @category Object
11946      * @param {Object} object The destination object.
11947      * @param {...Object} [sources] The source objects.
11948      * @returns {Object} Returns `object`.
11949      * @see _.assign
11950      * @example
11951      *
11952      * function Foo() {
11953      *   this.b = 2;
11954      * }
11955      *
11956      * function Bar() {
11957      *   this.d = 4;
11958      * }
11959      *
11960      * Foo.prototype.c = 3;
11961      * Bar.prototype.e = 5;
11962      *
11963      * _.assignIn({ 'a': 1 }, new Foo, new Bar);
11964      * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
11965      */
11966     var assignIn = createAssigner(function(object, source) {
11967       if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {
11968         copyObject(source, keysIn(source), object);
11969         return;
11970       }
11971       for (var key in source) {
11972         assignValue(object, key, source[key]);
11973       }
11974     });
11975
11976     /**
11977      * This method is like `_.assignIn` except that it accepts `customizer`
11978      * which is invoked to produce the assigned values. If `customizer` returns
11979      * `undefined`, assignment is handled by the method instead. The `customizer`
11980      * is invoked with five arguments: (objValue, srcValue, key, object, source).
11981      *
11982      * **Note:** This method mutates `object`.
11983      *
11984      * @static
11985      * @memberOf _
11986      * @since 4.0.0
11987      * @alias extendWith
11988      * @category Object
11989      * @param {Object} object The destination object.
11990      * @param {...Object} sources The source objects.
11991      * @param {Function} [customizer] The function to customize assigned values.
11992      * @returns {Object} Returns `object`.
11993      * @see _.assignWith
11994      * @example
11995      *
11996      * function customizer(objValue, srcValue) {
11997      *   return _.isUndefined(objValue) ? srcValue : objValue;
11998      * }
11999      *
12000      * var defaults = _.partialRight(_.assignInWith, customizer);
12001      *
12002      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12003      * // => { 'a': 1, 'b': 2 }
12004      */
12005     var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
12006       copyObject(source, keysIn(source), object, customizer);
12007     });
12008
12009     /**
12010      * This method is like `_.assign` except that it accepts `customizer`
12011      * which is invoked to produce the assigned values. If `customizer` returns
12012      * `undefined`, assignment is handled by the method instead. The `customizer`
12013      * is invoked with five arguments: (objValue, srcValue, key, object, source).
12014      *
12015      * **Note:** This method mutates `object`.
12016      *
12017      * @static
12018      * @memberOf _
12019      * @since 4.0.0
12020      * @category Object
12021      * @param {Object} object The destination object.
12022      * @param {...Object} sources The source objects.
12023      * @param {Function} [customizer] The function to customize assigned values.
12024      * @returns {Object} Returns `object`.
12025      * @see _.assignInWith
12026      * @example
12027      *
12028      * function customizer(objValue, srcValue) {
12029      *   return _.isUndefined(objValue) ? srcValue : objValue;
12030      * }
12031      *
12032      * var defaults = _.partialRight(_.assignWith, customizer);
12033      *
12034      * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
12035      * // => { 'a': 1, 'b': 2 }
12036      */
12037     var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
12038       copyObject(source, keys(source), object, customizer);
12039     });
12040
12041     /**
12042      * Creates an array of values corresponding to `paths` of `object`.
12043      *
12044      * @static
12045      * @memberOf _
12046      * @since 1.0.0
12047      * @category Object
12048      * @param {Object} object The object to iterate over.
12049      * @param {...(string|string[])} [paths] The property paths of elements to pick.
12050      * @returns {Array} Returns the picked values.
12051      * @example
12052      *
12053      * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
12054      *
12055      * _.at(object, ['a[0].b.c', 'a[1]']);
12056      * // => [3, 4]
12057      */
12058     var at = rest(function(object, paths) {
12059       return baseAt(object, baseFlatten(paths, 1));
12060     });
12061
12062     /**
12063      * Creates an object that inherits from the `prototype` object. If a
12064      * `properties` object is given, its own enumerable string keyed properties
12065      * are assigned to the created object.
12066      *
12067      * @static
12068      * @memberOf _
12069      * @since 2.3.0
12070      * @category Object
12071      * @param {Object} prototype The object to inherit from.
12072      * @param {Object} [properties] The properties to assign to the object.
12073      * @returns {Object} Returns the new object.
12074      * @example
12075      *
12076      * function Shape() {
12077      *   this.x = 0;
12078      *   this.y = 0;
12079      * }
12080      *
12081      * function Circle() {
12082      *   Shape.call(this);
12083      * }
12084      *
12085      * Circle.prototype = _.create(Shape.prototype, {
12086      *   'constructor': Circle
12087      * });
12088      *
12089      * var circle = new Circle;
12090      * circle instanceof Circle;
12091      * // => true
12092      *
12093      * circle instanceof Shape;
12094      * // => true
12095      */
12096     function create(prototype, properties) {
12097       var result = baseCreate(prototype);
12098       return properties ? baseAssign(result, properties) : result;
12099     }
12100
12101     /**
12102      * Assigns own and inherited enumerable string keyed properties of source
12103      * objects to the destination object for all destination properties that
12104      * resolve to `undefined`. Source objects are applied from left to right.
12105      * Once a property is set, additional values of the same property are ignored.
12106      *
12107      * **Note:** This method mutates `object`.
12108      *
12109      * @static
12110      * @since 0.1.0
12111      * @memberOf _
12112      * @category Object
12113      * @param {Object} object The destination object.
12114      * @param {...Object} [sources] The source objects.
12115      * @returns {Object} Returns `object`.
12116      * @see _.defaultsDeep
12117      * @example
12118      *
12119      * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
12120      * // => { 'user': 'barney', 'age': 36 }
12121      */
12122     var defaults = rest(function(args) {
12123       args.push(undefined, assignInDefaults);
12124       return apply(assignInWith, undefined, args);
12125     });
12126
12127     /**
12128      * This method is like `_.defaults` except that it recursively assigns
12129      * default properties.
12130      *
12131      * **Note:** This method mutates `object`.
12132      *
12133      * @static
12134      * @memberOf _
12135      * @since 3.10.0
12136      * @category Object
12137      * @param {Object} object The destination object.
12138      * @param {...Object} [sources] The source objects.
12139      * @returns {Object} Returns `object`.
12140      * @see _.defaults
12141      * @example
12142      *
12143      * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
12144      * // => { 'user': { 'name': 'barney', 'age': 36 } }
12145      *
12146      */
12147     var defaultsDeep = rest(function(args) {
12148       args.push(undefined, mergeDefaults);
12149       return apply(mergeWith, undefined, args);
12150     });
12151
12152     /**
12153      * This method is like `_.find` except that it returns the key of the first
12154      * element `predicate` returns truthy for instead of the element itself.
12155      *
12156      * @static
12157      * @memberOf _
12158      * @since 1.1.0
12159      * @category Object
12160      * @param {Object} object The object to search.
12161      * @param {Array|Function|Object|string} [predicate=_.identity]
12162      *  The function invoked per iteration.
12163      * @returns {string|undefined} Returns the key of the matched element,
12164      *  else `undefined`.
12165      * @example
12166      *
12167      * var users = {
12168      *   'barney':  { 'age': 36, 'active': true },
12169      *   'fred':    { 'age': 40, 'active': false },
12170      *   'pebbles': { 'age': 1,  'active': true }
12171      * };
12172      *
12173      * _.findKey(users, function(o) { return o.age < 40; });
12174      * // => 'barney' (iteration order is not guaranteed)
12175      *
12176      * // The `_.matches` iteratee shorthand.
12177      * _.findKey(users, { 'age': 1, 'active': true });
12178      * // => 'pebbles'
12179      *
12180      * // The `_.matchesProperty` iteratee shorthand.
12181      * _.findKey(users, ['active', false]);
12182      * // => 'fred'
12183      *
12184      * // The `_.property` iteratee shorthand.
12185      * _.findKey(users, 'active');
12186      * // => 'barney'
12187      */
12188     function findKey(object, predicate) {
12189       return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
12190     }
12191
12192     /**
12193      * This method is like `_.findKey` except that it iterates over elements of
12194      * a collection in the opposite order.
12195      *
12196      * @static
12197      * @memberOf _
12198      * @since 2.0.0
12199      * @category Object
12200      * @param {Object} object The object to search.
12201      * @param {Array|Function|Object|string} [predicate=_.identity]
12202      *  The function invoked per iteration.
12203      * @returns {string|undefined} Returns the key of the matched element,
12204      *  else `undefined`.
12205      * @example
12206      *
12207      * var users = {
12208      *   'barney':  { 'age': 36, 'active': true },
12209      *   'fred':    { 'age': 40, 'active': false },
12210      *   'pebbles': { 'age': 1,  'active': true }
12211      * };
12212      *
12213      * _.findLastKey(users, function(o) { return o.age < 40; });
12214      * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
12215      *
12216      * // The `_.matches` iteratee shorthand.
12217      * _.findLastKey(users, { 'age': 36, 'active': true });
12218      * // => 'barney'
12219      *
12220      * // The `_.matchesProperty` iteratee shorthand.
12221      * _.findLastKey(users, ['active', false]);
12222      * // => 'fred'
12223      *
12224      * // The `_.property` iteratee shorthand.
12225      * _.findLastKey(users, 'active');
12226      * // => 'pebbles'
12227      */
12228     function findLastKey(object, predicate) {
12229       return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
12230     }
12231
12232     /**
12233      * Iterates over own and inherited enumerable string keyed properties of an
12234      * object and invokes `iteratee` for each property. The iteratee is invoked
12235      * with three arguments: (value, key, object). Iteratee functions may exit
12236      * iteration early by explicitly returning `false`.
12237      *
12238      * @static
12239      * @memberOf _
12240      * @since 0.3.0
12241      * @category Object
12242      * @param {Object} object The object to iterate over.
12243      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12244      * @returns {Object} Returns `object`.
12245      * @see _.forInRight
12246      * @example
12247      *
12248      * function Foo() {
12249      *   this.a = 1;
12250      *   this.b = 2;
12251      * }
12252      *
12253      * Foo.prototype.c = 3;
12254      *
12255      * _.forIn(new Foo, function(value, key) {
12256      *   console.log(key);
12257      * });
12258      * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
12259      */
12260     function forIn(object, iteratee) {
12261       return object == null
12262         ? object
12263         : baseFor(object, getIteratee(iteratee, 3), keysIn);
12264     }
12265
12266     /**
12267      * This method is like `_.forIn` except that it iterates over properties of
12268      * `object` in the opposite order.
12269      *
12270      * @static
12271      * @memberOf _
12272      * @since 2.0.0
12273      * @category Object
12274      * @param {Object} object The object to iterate over.
12275      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12276      * @returns {Object} Returns `object`.
12277      * @see _.forIn
12278      * @example
12279      *
12280      * function Foo() {
12281      *   this.a = 1;
12282      *   this.b = 2;
12283      * }
12284      *
12285      * Foo.prototype.c = 3;
12286      *
12287      * _.forInRight(new Foo, function(value, key) {
12288      *   console.log(key);
12289      * });
12290      * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
12291      */
12292     function forInRight(object, iteratee) {
12293       return object == null
12294         ? object
12295         : baseForRight(object, getIteratee(iteratee, 3), keysIn);
12296     }
12297
12298     /**
12299      * Iterates over own enumerable string keyed properties of an object and
12300      * invokes `iteratee` for each property. The iteratee is invoked with three
12301      * arguments: (value, key, object). Iteratee functions may exit iteration
12302      * early by explicitly returning `false`.
12303      *
12304      * @static
12305      * @memberOf _
12306      * @since 0.3.0
12307      * @category Object
12308      * @param {Object} object The object to iterate over.
12309      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12310      * @returns {Object} Returns `object`.
12311      * @see _.forOwnRight
12312      * @example
12313      *
12314      * function Foo() {
12315      *   this.a = 1;
12316      *   this.b = 2;
12317      * }
12318      *
12319      * Foo.prototype.c = 3;
12320      *
12321      * _.forOwn(new Foo, function(value, key) {
12322      *   console.log(key);
12323      * });
12324      * // => Logs 'a' then 'b' (iteration order is not guaranteed).
12325      */
12326     function forOwn(object, iteratee) {
12327       return object && baseForOwn(object, getIteratee(iteratee, 3));
12328     }
12329
12330     /**
12331      * This method is like `_.forOwn` except that it iterates over properties of
12332      * `object` in the opposite order.
12333      *
12334      * @static
12335      * @memberOf _
12336      * @since 2.0.0
12337      * @category Object
12338      * @param {Object} object The object to iterate over.
12339      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
12340      * @returns {Object} Returns `object`.
12341      * @see _.forOwn
12342      * @example
12343      *
12344      * function Foo() {
12345      *   this.a = 1;
12346      *   this.b = 2;
12347      * }
12348      *
12349      * Foo.prototype.c = 3;
12350      *
12351      * _.forOwnRight(new Foo, function(value, key) {
12352      *   console.log(key);
12353      * });
12354      * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
12355      */
12356     function forOwnRight(object, iteratee) {
12357       return object && baseForOwnRight(object, getIteratee(iteratee, 3));
12358     }
12359
12360     /**
12361      * Creates an array of function property names from own enumerable properties
12362      * of `object`.
12363      *
12364      * @static
12365      * @since 0.1.0
12366      * @memberOf _
12367      * @category Object
12368      * @param {Object} object The object to inspect.
12369      * @returns {Array} Returns the function names.
12370      * @see _.functionsIn
12371      * @example
12372      *
12373      * function Foo() {
12374      *   this.a = _.constant('a');
12375      *   this.b = _.constant('b');
12376      * }
12377      *
12378      * Foo.prototype.c = _.constant('c');
12379      *
12380      * _.functions(new Foo);
12381      * // => ['a', 'b']
12382      */
12383     function functions(object) {
12384       return object == null ? [] : baseFunctions(object, keys(object));
12385     }
12386
12387     /**
12388      * Creates an array of function property names from own and inherited
12389      * enumerable properties of `object`.
12390      *
12391      * @static
12392      * @memberOf _
12393      * @since 4.0.0
12394      * @category Object
12395      * @param {Object} object The object to inspect.
12396      * @returns {Array} Returns the function names.
12397      * @see _.functions
12398      * @example
12399      *
12400      * function Foo() {
12401      *   this.a = _.constant('a');
12402      *   this.b = _.constant('b');
12403      * }
12404      *
12405      * Foo.prototype.c = _.constant('c');
12406      *
12407      * _.functionsIn(new Foo);
12408      * // => ['a', 'b', 'c']
12409      */
12410     function functionsIn(object) {
12411       return object == null ? [] : baseFunctions(object, keysIn(object));
12412     }
12413
12414     /**
12415      * Gets the value at `path` of `object`. If the resolved value is
12416      * `undefined`, the `defaultValue` is used in its place.
12417      *
12418      * @static
12419      * @memberOf _
12420      * @since 3.7.0
12421      * @category Object
12422      * @param {Object} object The object to query.
12423      * @param {Array|string} path The path of the property to get.
12424      * @param {*} [defaultValue] The value returned for `undefined` resolved values.
12425      * @returns {*} Returns the resolved value.
12426      * @example
12427      *
12428      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
12429      *
12430      * _.get(object, 'a[0].b.c');
12431      * // => 3
12432      *
12433      * _.get(object, ['a', '0', 'b', 'c']);
12434      * // => 3
12435      *
12436      * _.get(object, 'a.b.c', 'default');
12437      * // => 'default'
12438      */
12439     function get(object, path, defaultValue) {
12440       var result = object == null ? undefined : baseGet(object, path);
12441       return result === undefined ? defaultValue : result;
12442     }
12443
12444     /**
12445      * Checks if `path` is a direct property of `object`.
12446      *
12447      * @static
12448      * @since 0.1.0
12449      * @memberOf _
12450      * @category Object
12451      * @param {Object} object The object to query.
12452      * @param {Array|string} path The path to check.
12453      * @returns {boolean} Returns `true` if `path` exists, else `false`.
12454      * @example
12455      *
12456      * var object = { 'a': { 'b': 2 } };
12457      * var other = _.create({ 'a': _.create({ 'b': 2 }) });
12458      *
12459      * _.has(object, 'a');
12460      * // => true
12461      *
12462      * _.has(object, 'a.b');
12463      * // => true
12464      *
12465      * _.has(object, ['a', 'b']);
12466      * // => true
12467      *
12468      * _.has(other, 'a');
12469      * // => false
12470      */
12471     function has(object, path) {
12472       return object != null && hasPath(object, path, baseHas);
12473     }
12474
12475     /**
12476      * Checks if `path` is a direct or inherited property of `object`.
12477      *
12478      * @static
12479      * @memberOf _
12480      * @since 4.0.0
12481      * @category Object
12482      * @param {Object} object The object to query.
12483      * @param {Array|string} path The path to check.
12484      * @returns {boolean} Returns `true` if `path` exists, else `false`.
12485      * @example
12486      *
12487      * var object = _.create({ 'a': _.create({ 'b': 2 }) });
12488      *
12489      * _.hasIn(object, 'a');
12490      * // => true
12491      *
12492      * _.hasIn(object, 'a.b');
12493      * // => true
12494      *
12495      * _.hasIn(object, ['a', 'b']);
12496      * // => true
12497      *
12498      * _.hasIn(object, 'b');
12499      * // => false
12500      */
12501     function hasIn(object, path) {
12502       return object != null && hasPath(object, path, baseHasIn);
12503     }
12504
12505     /**
12506      * Creates an object composed of the inverted keys and values of `object`.
12507      * If `object` contains duplicate values, subsequent values overwrite
12508      * property assignments of previous values.
12509      *
12510      * @static
12511      * @memberOf _
12512      * @since 0.7.0
12513      * @category Object
12514      * @param {Object} object The object to invert.
12515      * @returns {Object} Returns the new inverted object.
12516      * @example
12517      *
12518      * var object = { 'a': 1, 'b': 2, 'c': 1 };
12519      *
12520      * _.invert(object);
12521      * // => { '1': 'c', '2': 'b' }
12522      */
12523     var invert = createInverter(function(result, value, key) {
12524       result[value] = key;
12525     }, constant(identity));
12526
12527     /**
12528      * This method is like `_.invert` except that the inverted object is generated
12529      * from the results of running each element of `object` thru `iteratee`. The
12530      * corresponding inverted value of each inverted key is an array of keys
12531      * responsible for generating the inverted value. The iteratee is invoked
12532      * with one argument: (value).
12533      *
12534      * @static
12535      * @memberOf _
12536      * @since 4.1.0
12537      * @category Object
12538      * @param {Object} object The object to invert.
12539      * @param {Array|Function|Object|string} [iteratee=_.identity]
12540      *  The iteratee invoked per element.
12541      * @returns {Object} Returns the new inverted object.
12542      * @example
12543      *
12544      * var object = { 'a': 1, 'b': 2, 'c': 1 };
12545      *
12546      * _.invertBy(object);
12547      * // => { '1': ['a', 'c'], '2': ['b'] }
12548      *
12549      * _.invertBy(object, function(value) {
12550      *   return 'group' + value;
12551      * });
12552      * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
12553      */
12554     var invertBy = createInverter(function(result, value, key) {
12555       if (hasOwnProperty.call(result, value)) {
12556         result[value].push(key);
12557       } else {
12558         result[value] = [key];
12559       }
12560     }, getIteratee);
12561
12562     /**
12563      * Invokes the method at `path` of `object`.
12564      *
12565      * @static
12566      * @memberOf _
12567      * @since 4.0.0
12568      * @category Object
12569      * @param {Object} object The object to query.
12570      * @param {Array|string} path The path of the method to invoke.
12571      * @param {...*} [args] The arguments to invoke the method with.
12572      * @returns {*} Returns the result of the invoked method.
12573      * @example
12574      *
12575      * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
12576      *
12577      * _.invoke(object, 'a[0].b.c.slice', 1, 3);
12578      * // => [2, 3]
12579      */
12580     var invoke = rest(baseInvoke);
12581
12582     /**
12583      * Creates an array of the own enumerable property names of `object`.
12584      *
12585      * **Note:** Non-object values are coerced to objects. See the
12586      * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
12587      * for more details.
12588      *
12589      * @static
12590      * @since 0.1.0
12591      * @memberOf _
12592      * @category Object
12593      * @param {Object} object The object to query.
12594      * @returns {Array} Returns the array of property names.
12595      * @example
12596      *
12597      * function Foo() {
12598      *   this.a = 1;
12599      *   this.b = 2;
12600      * }
12601      *
12602      * Foo.prototype.c = 3;
12603      *
12604      * _.keys(new Foo);
12605      * // => ['a', 'b'] (iteration order is not guaranteed)
12606      *
12607      * _.keys('hi');
12608      * // => ['0', '1']
12609      */
12610     function keys(object) {
12611       var isProto = isPrototype(object);
12612       if (!(isProto || isArrayLike(object))) {
12613         return baseKeys(object);
12614       }
12615       var indexes = indexKeys(object),
12616           skipIndexes = !!indexes,
12617           result = indexes || [],
12618           length = result.length;
12619
12620       for (var key in object) {
12621         if (baseHas(object, key) &&
12622             !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
12623             !(isProto && key == 'constructor')) {
12624           result.push(key);
12625         }
12626       }
12627       return result;
12628     }
12629
12630     /**
12631      * Creates an array of the own and inherited enumerable property names of `object`.
12632      *
12633      * **Note:** Non-object values are coerced to objects.
12634      *
12635      * @static
12636      * @memberOf _
12637      * @since 3.0.0
12638      * @category Object
12639      * @param {Object} object The object to query.
12640      * @returns {Array} Returns the array of property names.
12641      * @example
12642      *
12643      * function Foo() {
12644      *   this.a = 1;
12645      *   this.b = 2;
12646      * }
12647      *
12648      * Foo.prototype.c = 3;
12649      *
12650      * _.keysIn(new Foo);
12651      * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
12652      */
12653     function keysIn(object) {
12654       var index = -1,
12655           isProto = isPrototype(object),
12656           props = baseKeysIn(object),
12657           propsLength = props.length,
12658           indexes = indexKeys(object),
12659           skipIndexes = !!indexes,
12660           result = indexes || [],
12661           length = result.length;
12662
12663       while (++index < propsLength) {
12664         var key = props[index];
12665         if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
12666             !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
12667           result.push(key);
12668         }
12669       }
12670       return result;
12671     }
12672
12673     /**
12674      * The opposite of `_.mapValues`; this method creates an object with the
12675      * same values as `object` and keys generated by running each own enumerable
12676      * string keyed property of `object` thru `iteratee`. The iteratee is invoked
12677      * with three arguments: (value, key, object).
12678      *
12679      * @static
12680      * @memberOf _
12681      * @since 3.8.0
12682      * @category Object
12683      * @param {Object} object The object to iterate over.
12684      * @param {Array|Function|Object|string} [iteratee=_.identity]
12685      *  The function invoked per iteration.
12686      * @returns {Object} Returns the new mapped object.
12687      * @see _.mapValues
12688      * @example
12689      *
12690      * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
12691      *   return key + value;
12692      * });
12693      * // => { 'a1': 1, 'b2': 2 }
12694      */
12695     function mapKeys(object, iteratee) {
12696       var result = {};
12697       iteratee = getIteratee(iteratee, 3);
12698
12699       baseForOwn(object, function(value, key, object) {
12700         result[iteratee(value, key, object)] = value;
12701       });
12702       return result;
12703     }
12704
12705     /**
12706      * Creates an object with the same keys as `object` and values generated
12707      * by running each own enumerable string keyed property of `object` thru
12708      * `iteratee`. The iteratee is invoked with three arguments:
12709      * (value, key, object).
12710      *
12711      * @static
12712      * @memberOf _
12713      * @since 2.4.0
12714      * @category Object
12715      * @param {Object} object The object to iterate over.
12716      * @param {Array|Function|Object|string} [iteratee=_.identity]
12717      *  The function invoked per iteration.
12718      * @returns {Object} Returns the new mapped object.
12719      * @see _.mapKeys
12720      * @example
12721      *
12722      * var users = {
12723      *   'fred':    { 'user': 'fred',    'age': 40 },
12724      *   'pebbles': { 'user': 'pebbles', 'age': 1 }
12725      * };
12726      *
12727      * _.mapValues(users, function(o) { return o.age; });
12728      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
12729      *
12730      * // The `_.property` iteratee shorthand.
12731      * _.mapValues(users, 'age');
12732      * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
12733      */
12734     function mapValues(object, iteratee) {
12735       var result = {};
12736       iteratee = getIteratee(iteratee, 3);
12737
12738       baseForOwn(object, function(value, key, object) {
12739         result[key] = iteratee(value, key, object);
12740       });
12741       return result;
12742     }
12743
12744     /**
12745      * This method is like `_.assign` except that it recursively merges own and
12746      * inherited enumerable string keyed properties of source objects into the
12747      * destination object. Source properties that resolve to `undefined` are
12748      * skipped if a destination value exists. Array and plain object properties
12749      * are merged recursively. Other objects and value types are overridden by
12750      * assignment. Source objects are applied from left to right. Subsequent
12751      * sources overwrite property assignments of previous sources.
12752      *
12753      * **Note:** This method mutates `object`.
12754      *
12755      * @static
12756      * @memberOf _
12757      * @since 0.5.0
12758      * @category Object
12759      * @param {Object} object The destination object.
12760      * @param {...Object} [sources] The source objects.
12761      * @returns {Object} Returns `object`.
12762      * @example
12763      *
12764      * var users = {
12765      *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
12766      * };
12767      *
12768      * var ages = {
12769      *   'data': [{ 'age': 36 }, { 'age': 40 }]
12770      * };
12771      *
12772      * _.merge(users, ages);
12773      * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
12774      */
12775     var merge = createAssigner(function(object, source, srcIndex) {
12776       baseMerge(object, source, srcIndex);
12777     });
12778
12779     /**
12780      * This method is like `_.merge` except that it accepts `customizer` which
12781      * is invoked to produce the merged values of the destination and source
12782      * properties. If `customizer` returns `undefined`, merging is handled by the
12783      * method instead. The `customizer` is invoked with seven arguments:
12784      * (objValue, srcValue, key, object, source, stack).
12785      *
12786      * **Note:** This method mutates `object`.
12787      *
12788      * @static
12789      * @memberOf _
12790      * @since 4.0.0
12791      * @category Object
12792      * @param {Object} object The destination object.
12793      * @param {...Object} sources The source objects.
12794      * @param {Function} customizer The function to customize assigned values.
12795      * @returns {Object} Returns `object`.
12796      * @example
12797      *
12798      * function customizer(objValue, srcValue) {
12799      *   if (_.isArray(objValue)) {
12800      *     return objValue.concat(srcValue);
12801      *   }
12802      * }
12803      *
12804      * var object = {
12805      *   'fruits': ['apple'],
12806      *   'vegetables': ['beet']
12807      * };
12808      *
12809      * var other = {
12810      *   'fruits': ['banana'],
12811      *   'vegetables': ['carrot']
12812      * };
12813      *
12814      * _.mergeWith(object, other, customizer);
12815      * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
12816      */
12817     var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
12818       baseMerge(object, source, srcIndex, customizer);
12819     });
12820
12821     /**
12822      * The opposite of `_.pick`; this method creates an object composed of the
12823      * own and inherited enumerable string keyed properties of `object` that are
12824      * not omitted.
12825      *
12826      * @static
12827      * @since 0.1.0
12828      * @memberOf _
12829      * @category Object
12830      * @param {Object} object The source object.
12831      * @param {...(string|string[])} [props] The property identifiers to omit.
12832      * @returns {Object} Returns the new object.
12833      * @example
12834      *
12835      * var object = { 'a': 1, 'b': '2', 'c': 3 };
12836      *
12837      * _.omit(object, ['a', 'c']);
12838      * // => { 'b': '2' }
12839      */
12840     var omit = rest(function(object, props) {
12841       if (object == null) {
12842         return {};
12843       }
12844       props = arrayMap(baseFlatten(props, 1), toKey);
12845       return basePick(object, baseDifference(getAllKeysIn(object), props));
12846     });
12847
12848     /**
12849      * The opposite of `_.pickBy`; this method creates an object composed of
12850      * the own and inherited enumerable string keyed properties of `object` that
12851      * `predicate` doesn't return truthy for. The predicate is invoked with two
12852      * arguments: (value, key).
12853      *
12854      * @static
12855      * @memberOf _
12856      * @since 4.0.0
12857      * @category Object
12858      * @param {Object} object The source object.
12859      * @param {Array|Function|Object|string} [predicate=_.identity]
12860      *  The function invoked per property.
12861      * @returns {Object} Returns the new object.
12862      * @example
12863      *
12864      * var object = { 'a': 1, 'b': '2', 'c': 3 };
12865      *
12866      * _.omitBy(object, _.isNumber);
12867      * // => { 'b': '2' }
12868      */
12869     function omitBy(object, predicate) {
12870       predicate = getIteratee(predicate);
12871       return basePickBy(object, function(value, key) {
12872         return !predicate(value, key);
12873       });
12874     }
12875
12876     /**
12877      * Creates an object composed of the picked `object` properties.
12878      *
12879      * @static
12880      * @since 0.1.0
12881      * @memberOf _
12882      * @category Object
12883      * @param {Object} object The source object.
12884      * @param {...(string|string[])} [props] The property identifiers to pick.
12885      * @returns {Object} Returns the new object.
12886      * @example
12887      *
12888      * var object = { 'a': 1, 'b': '2', 'c': 3 };
12889      *
12890      * _.pick(object, ['a', 'c']);
12891      * // => { 'a': 1, 'c': 3 }
12892      */
12893     var pick = rest(function(object, props) {
12894       return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey));
12895     });
12896
12897     /**
12898      * Creates an object composed of the `object` properties `predicate` returns
12899      * truthy for. The predicate is invoked with two arguments: (value, key).
12900      *
12901      * @static
12902      * @memberOf _
12903      * @since 4.0.0
12904      * @category Object
12905      * @param {Object} object The source object.
12906      * @param {Array|Function|Object|string} [predicate=_.identity]
12907      *  The function invoked per property.
12908      * @returns {Object} Returns the new object.
12909      * @example
12910      *
12911      * var object = { 'a': 1, 'b': '2', 'c': 3 };
12912      *
12913      * _.pickBy(object, _.isNumber);
12914      * // => { 'a': 1, 'c': 3 }
12915      */
12916     function pickBy(object, predicate) {
12917       return object == null ? {} : basePickBy(object, getIteratee(predicate));
12918     }
12919
12920     /**
12921      * This method is like `_.get` except that if the resolved value is a
12922      * function it's invoked with the `this` binding of its parent object and
12923      * its result is returned.
12924      *
12925      * @static
12926      * @since 0.1.0
12927      * @memberOf _
12928      * @category Object
12929      * @param {Object} object The object to query.
12930      * @param {Array|string} path The path of the property to resolve.
12931      * @param {*} [defaultValue] The value returned for `undefined` resolved values.
12932      * @returns {*} Returns the resolved value.
12933      * @example
12934      *
12935      * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
12936      *
12937      * _.result(object, 'a[0].b.c1');
12938      * // => 3
12939      *
12940      * _.result(object, 'a[0].b.c2');
12941      * // => 4
12942      *
12943      * _.result(object, 'a[0].b.c3', 'default');
12944      * // => 'default'
12945      *
12946      * _.result(object, 'a[0].b.c3', _.constant('default'));
12947      * // => 'default'
12948      */
12949     function result(object, path, defaultValue) {
12950       path = isKey(path, object) ? [path] : castPath(path);
12951
12952       var index = -1,
12953           length = path.length;
12954
12955       // Ensure the loop is entered when path is empty.
12956       if (!length) {
12957         object = undefined;
12958         length = 1;
12959       }
12960       while (++index < length) {
12961         var value = object == null ? undefined : object[toKey(path[index])];
12962         if (value === undefined) {
12963           index = length;
12964           value = defaultValue;
12965         }
12966         object = isFunction(value) ? value.call(object) : value;
12967       }
12968       return object;
12969     }
12970
12971     /**
12972      * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
12973      * it's created. Arrays are created for missing index properties while objects
12974      * are created for all other missing properties. Use `_.setWith` to customize
12975      * `path` creation.
12976      *
12977      * **Note:** This method mutates `object`.
12978      *
12979      * @static
12980      * @memberOf _
12981      * @since 3.7.0
12982      * @category Object
12983      * @param {Object} object The object to modify.
12984      * @param {Array|string} path The path of the property to set.
12985      * @param {*} value The value to set.
12986      * @returns {Object} Returns `object`.
12987      * @example
12988      *
12989      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
12990      *
12991      * _.set(object, 'a[0].b.c', 4);
12992      * console.log(object.a[0].b.c);
12993      * // => 4
12994      *
12995      * _.set(object, ['x', '0', 'y', 'z'], 5);
12996      * console.log(object.x[0].y.z);
12997      * // => 5
12998      */
12999     function set(object, path, value) {
13000       return object == null ? object : baseSet(object, path, value);
13001     }
13002
13003     /**
13004      * This method is like `_.set` except that it accepts `customizer` which is
13005      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
13006      * path creation is handled by the method instead. The `customizer` is invoked
13007      * with three arguments: (nsValue, key, nsObject).
13008      *
13009      * **Note:** This method mutates `object`.
13010      *
13011      * @static
13012      * @memberOf _
13013      * @since 4.0.0
13014      * @category Object
13015      * @param {Object} object The object to modify.
13016      * @param {Array|string} path The path of the property to set.
13017      * @param {*} value The value to set.
13018      * @param {Function} [customizer] The function to customize assigned values.
13019      * @returns {Object} Returns `object`.
13020      * @example
13021      *
13022      * var object = {};
13023      *
13024      * _.setWith(object, '[0][1]', 'a', Object);
13025      * // => { '0': { '1': 'a' } }
13026      */
13027     function setWith(object, path, value, customizer) {
13028       customizer = typeof customizer == 'function' ? customizer : undefined;
13029       return object == null ? object : baseSet(object, path, value, customizer);
13030     }
13031
13032     /**
13033      * Creates an array of own enumerable string keyed-value pairs for `object`
13034      * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
13035      * entries are returned.
13036      *
13037      * @static
13038      * @memberOf _
13039      * @since 4.0.0
13040      * @alias entries
13041      * @category Object
13042      * @param {Object} object The object to query.
13043      * @returns {Array} Returns the key-value pairs.
13044      * @example
13045      *
13046      * function Foo() {
13047      *   this.a = 1;
13048      *   this.b = 2;
13049      * }
13050      *
13051      * Foo.prototype.c = 3;
13052      *
13053      * _.toPairs(new Foo);
13054      * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
13055      */
13056     var toPairs = createToPairs(keys);
13057
13058     /**
13059      * Creates an array of own and inherited enumerable string keyed-value pairs
13060      * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
13061      * or set, its entries are returned.
13062      *
13063      * @static
13064      * @memberOf _
13065      * @since 4.0.0
13066      * @alias entriesIn
13067      * @category Object
13068      * @param {Object} object The object to query.
13069      * @returns {Array} Returns the key-value pairs.
13070      * @example
13071      *
13072      * function Foo() {
13073      *   this.a = 1;
13074      *   this.b = 2;
13075      * }
13076      *
13077      * Foo.prototype.c = 3;
13078      *
13079      * _.toPairsIn(new Foo);
13080      * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
13081      */
13082     var toPairsIn = createToPairs(keysIn);
13083
13084     /**
13085      * An alternative to `_.reduce`; this method transforms `object` to a new
13086      * `accumulator` object which is the result of running each of its own
13087      * enumerable string keyed properties thru `iteratee`, with each invocation
13088      * potentially mutating the `accumulator` object. If `accumulator` is not
13089      * provided, a new object with the same `[[Prototype]]` will be used. The
13090      * iteratee is invoked with four arguments: (accumulator, value, key, object).
13091      * Iteratee functions may exit iteration early by explicitly returning `false`.
13092      *
13093      * @static
13094      * @memberOf _
13095      * @since 1.3.0
13096      * @category Object
13097      * @param {Object} object The object to iterate over.
13098      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
13099      * @param {*} [accumulator] The custom accumulator value.
13100      * @returns {*} Returns the accumulated value.
13101      * @example
13102      *
13103      * _.transform([2, 3, 4], function(result, n) {
13104      *   result.push(n *= n);
13105      *   return n % 2 == 0;
13106      * }, []);
13107      * // => [4, 9]
13108      *
13109      * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
13110      *   (result[value] || (result[value] = [])).push(key);
13111      * }, {});
13112      * // => { '1': ['a', 'c'], '2': ['b'] }
13113      */
13114     function transform(object, iteratee, accumulator) {
13115       var isArr = isArray(object) || isTypedArray(object);
13116       iteratee = getIteratee(iteratee, 4);
13117
13118       if (accumulator == null) {
13119         if (isArr || isObject(object)) {
13120           var Ctor = object.constructor;
13121           if (isArr) {
13122             accumulator = isArray(object) ? new Ctor : [];
13123           } else {
13124             accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
13125           }
13126         } else {
13127           accumulator = {};
13128         }
13129       }
13130       (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
13131         return iteratee(accumulator, value, index, object);
13132       });
13133       return accumulator;
13134     }
13135
13136     /**
13137      * Removes the property at `path` of `object`.
13138      *
13139      * **Note:** This method mutates `object`.
13140      *
13141      * @static
13142      * @memberOf _
13143      * @since 4.0.0
13144      * @category Object
13145      * @param {Object} object The object to modify.
13146      * @param {Array|string} path The path of the property to unset.
13147      * @returns {boolean} Returns `true` if the property is deleted, else `false`.
13148      * @example
13149      *
13150      * var object = { 'a': [{ 'b': { 'c': 7 } }] };
13151      * _.unset(object, 'a[0].b.c');
13152      * // => true
13153      *
13154      * console.log(object);
13155      * // => { 'a': [{ 'b': {} }] };
13156      *
13157      * _.unset(object, ['a', '0', 'b', 'c']);
13158      * // => true
13159      *
13160      * console.log(object);
13161      * // => { 'a': [{ 'b': {} }] };
13162      */
13163     function unset(object, path) {
13164       return object == null ? true : baseUnset(object, path);
13165     }
13166
13167     /**
13168      * This method is like `_.set` except that accepts `updater` to produce the
13169      * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
13170      * is invoked with one argument: (value).
13171      *
13172      * **Note:** This method mutates `object`.
13173      *
13174      * @static
13175      * @memberOf _
13176      * @since 4.6.0
13177      * @category Object
13178      * @param {Object} object The object to modify.
13179      * @param {Array|string} path The path of the property to set.
13180      * @param {Function} updater The function to produce the updated value.
13181      * @returns {Object} Returns `object`.
13182      * @example
13183      *
13184      * var object = { 'a': [{ 'b': { 'c': 3 } }] };
13185      *
13186      * _.update(object, 'a[0].b.c', function(n) { return n * n; });
13187      * console.log(object.a[0].b.c);
13188      * // => 9
13189      *
13190      * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
13191      * console.log(object.x[0].y.z);
13192      * // => 0
13193      */
13194     function update(object, path, updater) {
13195       return object == null ? object : baseUpdate(object, path, castFunction(updater));
13196     }
13197
13198     /**
13199      * This method is like `_.update` except that it accepts `customizer` which is
13200      * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
13201      * path creation is handled by the method instead. The `customizer` is invoked
13202      * with three arguments: (nsValue, key, nsObject).
13203      *
13204      * **Note:** This method mutates `object`.
13205      *
13206      * @static
13207      * @memberOf _
13208      * @since 4.6.0
13209      * @category Object
13210      * @param {Object} object The object to modify.
13211      * @param {Array|string} path The path of the property to set.
13212      * @param {Function} updater The function to produce the updated value.
13213      * @param {Function} [customizer] The function to customize assigned values.
13214      * @returns {Object} Returns `object`.
13215      * @example
13216      *
13217      * var object = {};
13218      *
13219      * _.updateWith(object, '[0][1]', _.constant('a'), Object);
13220      * // => { '0': { '1': 'a' } }
13221      */
13222     function updateWith(object, path, updater, customizer) {
13223       customizer = typeof customizer == 'function' ? customizer : undefined;
13224       return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
13225     }
13226
13227     /**
13228      * Creates an array of the own enumerable string keyed property values of `object`.
13229      *
13230      * **Note:** Non-object values are coerced to objects.
13231      *
13232      * @static
13233      * @since 0.1.0
13234      * @memberOf _
13235      * @category Object
13236      * @param {Object} object The object to query.
13237      * @returns {Array} Returns the array of property values.
13238      * @example
13239      *
13240      * function Foo() {
13241      *   this.a = 1;
13242      *   this.b = 2;
13243      * }
13244      *
13245      * Foo.prototype.c = 3;
13246      *
13247      * _.values(new Foo);
13248      * // => [1, 2] (iteration order is not guaranteed)
13249      *
13250      * _.values('hi');
13251      * // => ['h', 'i']
13252      */
13253     function values(object) {
13254       return object ? baseValues(object, keys(object)) : [];
13255     }
13256
13257     /**
13258      * Creates an array of the own and inherited enumerable string keyed property
13259      * values of `object`.
13260      *
13261      * **Note:** Non-object values are coerced to objects.
13262      *
13263      * @static
13264      * @memberOf _
13265      * @since 3.0.0
13266      * @category Object
13267      * @param {Object} object The object to query.
13268      * @returns {Array} Returns the array of property values.
13269      * @example
13270      *
13271      * function Foo() {
13272      *   this.a = 1;
13273      *   this.b = 2;
13274      * }
13275      *
13276      * Foo.prototype.c = 3;
13277      *
13278      * _.valuesIn(new Foo);
13279      * // => [1, 2, 3] (iteration order is not guaranteed)
13280      */
13281     function valuesIn(object) {
13282       return object == null ? [] : baseValues(object, keysIn(object));
13283     }
13284
13285     /*------------------------------------------------------------------------*/
13286
13287     /**
13288      * Clamps `number` within the inclusive `lower` and `upper` bounds.
13289      *
13290      * @static
13291      * @memberOf _
13292      * @since 4.0.0
13293      * @category Number
13294      * @param {number} number The number to clamp.
13295      * @param {number} [lower] The lower bound.
13296      * @param {number} upper The upper bound.
13297      * @returns {number} Returns the clamped number.
13298      * @example
13299      *
13300      * _.clamp(-10, -5, 5);
13301      * // => -5
13302      *
13303      * _.clamp(10, -5, 5);
13304      * // => 5
13305      */
13306     function clamp(number, lower, upper) {
13307       if (upper === undefined) {
13308         upper = lower;
13309         lower = undefined;
13310       }
13311       if (upper !== undefined) {
13312         upper = toNumber(upper);
13313         upper = upper === upper ? upper : 0;
13314       }
13315       if (lower !== undefined) {
13316         lower = toNumber(lower);
13317         lower = lower === lower ? lower : 0;
13318       }
13319       return baseClamp(toNumber(number), lower, upper);
13320     }
13321
13322     /**
13323      * Checks if `n` is between `start` and up to, but not including, `end`. If
13324      * `end` is not specified, it's set to `start` with `start` then set to `0`.
13325      * If `start` is greater than `end` the params are swapped to support
13326      * negative ranges.
13327      *
13328      * @static
13329      * @memberOf _
13330      * @since 3.3.0
13331      * @category Number
13332      * @param {number} number The number to check.
13333      * @param {number} [start=0] The start of the range.
13334      * @param {number} end The end of the range.
13335      * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
13336      * @see _.range, _.rangeRight
13337      * @example
13338      *
13339      * _.inRange(3, 2, 4);
13340      * // => true
13341      *
13342      * _.inRange(4, 8);
13343      * // => true
13344      *
13345      * _.inRange(4, 2);
13346      * // => false
13347      *
13348      * _.inRange(2, 2);
13349      * // => false
13350      *
13351      * _.inRange(1.2, 2);
13352      * // => true
13353      *
13354      * _.inRange(5.2, 4);
13355      * // => false
13356      *
13357      * _.inRange(-3, -2, -6);
13358      * // => true
13359      */
13360     function inRange(number, start, end) {
13361       start = toNumber(start) || 0;
13362       if (end === undefined) {
13363         end = start;
13364         start = 0;
13365       } else {
13366         end = toNumber(end) || 0;
13367       }
13368       number = toNumber(number);
13369       return baseInRange(number, start, end);
13370     }
13371
13372     /**
13373      * Produces a random number between the inclusive `lower` and `upper` bounds.
13374      * If only one argument is provided a number between `0` and the given number
13375      * is returned. If `floating` is `true`, or either `lower` or `upper` are
13376      * floats, a floating-point number is returned instead of an integer.
13377      *
13378      * **Note:** JavaScript follows the IEEE-754 standard for resolving
13379      * floating-point values which can produce unexpected results.
13380      *
13381      * @static
13382      * @memberOf _
13383      * @since 0.7.0
13384      * @category Number
13385      * @param {number} [lower=0] The lower bound.
13386      * @param {number} [upper=1] The upper bound.
13387      * @param {boolean} [floating] Specify returning a floating-point number.
13388      * @returns {number} Returns the random number.
13389      * @example
13390      *
13391      * _.random(0, 5);
13392      * // => an integer between 0 and 5
13393      *
13394      * _.random(5);
13395      * // => also an integer between 0 and 5
13396      *
13397      * _.random(5, true);
13398      * // => a floating-point number between 0 and 5
13399      *
13400      * _.random(1.2, 5.2);
13401      * // => a floating-point number between 1.2 and 5.2
13402      */
13403     function random(lower, upper, floating) {
13404       if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
13405         upper = floating = undefined;
13406       }
13407       if (floating === undefined) {
13408         if (typeof upper == 'boolean') {
13409           floating = upper;
13410           upper = undefined;
13411         }
13412         else if (typeof lower == 'boolean') {
13413           floating = lower;
13414           lower = undefined;
13415         }
13416       }
13417       if (lower === undefined && upper === undefined) {
13418         lower = 0;
13419         upper = 1;
13420       }
13421       else {
13422         lower = toNumber(lower) || 0;
13423         if (upper === undefined) {
13424           upper = lower;
13425           lower = 0;
13426         } else {
13427           upper = toNumber(upper) || 0;
13428         }
13429       }
13430       if (lower > upper) {
13431         var temp = lower;
13432         lower = upper;
13433         upper = temp;
13434       }
13435       if (floating || lower % 1 || upper % 1) {
13436         var rand = nativeRandom();
13437         return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
13438       }
13439       return baseRandom(lower, upper);
13440     }
13441
13442     /*------------------------------------------------------------------------*/
13443
13444     /**
13445      * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
13446      *
13447      * @static
13448      * @memberOf _
13449      * @since 3.0.0
13450      * @category String
13451      * @param {string} [string=''] The string to convert.
13452      * @returns {string} Returns the camel cased string.
13453      * @example
13454      *
13455      * _.camelCase('Foo Bar');
13456      * // => 'fooBar'
13457      *
13458      * _.camelCase('--foo-bar--');
13459      * // => 'fooBar'
13460      *
13461      * _.camelCase('__FOO_BAR__');
13462      * // => 'fooBar'
13463      */
13464     var camelCase = createCompounder(function(result, word, index) {
13465       word = word.toLowerCase();
13466       return result + (index ? capitalize(word) : word);
13467     });
13468
13469     /**
13470      * Converts the first character of `string` to upper case and the remaining
13471      * to lower case.
13472      *
13473      * @static
13474      * @memberOf _
13475      * @since 3.0.0
13476      * @category String
13477      * @param {string} [string=''] The string to capitalize.
13478      * @returns {string} Returns the capitalized string.
13479      * @example
13480      *
13481      * _.capitalize('FRED');
13482      * // => 'Fred'
13483      */
13484     function capitalize(string) {
13485       return upperFirst(toString(string).toLowerCase());
13486     }
13487
13488     /**
13489      * Deburrs `string` by converting
13490      * [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
13491      * to basic latin letters and removing
13492      * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
13493      *
13494      * @static
13495      * @memberOf _
13496      * @since 3.0.0
13497      * @category String
13498      * @param {string} [string=''] The string to deburr.
13499      * @returns {string} Returns the deburred string.
13500      * @example
13501      *
13502      * _.deburr('déjà vu');
13503      * // => 'deja vu'
13504      */
13505     function deburr(string) {
13506       string = toString(string);
13507       return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
13508     }
13509
13510     /**
13511      * Checks if `string` ends with the given target string.
13512      *
13513      * @static
13514      * @memberOf _
13515      * @since 3.0.0
13516      * @category String
13517      * @param {string} [string=''] The string to search.
13518      * @param {string} [target] The string to search for.
13519      * @param {number} [position=string.length] The position to search up to.
13520      * @returns {boolean} Returns `true` if `string` ends with `target`,
13521      *  else `false`.
13522      * @example
13523      *
13524      * _.endsWith('abc', 'c');
13525      * // => true
13526      *
13527      * _.endsWith('abc', 'b');
13528      * // => false
13529      *
13530      * _.endsWith('abc', 'b', 2);
13531      * // => true
13532      */
13533     function endsWith(string, target, position) {
13534       string = toString(string);
13535       target = baseToString(target);
13536
13537       var length = string.length;
13538       position = position === undefined
13539         ? length
13540         : baseClamp(toInteger(position), 0, length);
13541
13542       position -= target.length;
13543       return position >= 0 && string.indexOf(target, position) == position;
13544     }
13545
13546     /**
13547      * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
13548      * their corresponding HTML entities.
13549      *
13550      * **Note:** No other characters are escaped. To escape additional
13551      * characters use a third-party library like [_he_](https://mths.be/he).
13552      *
13553      * Though the ">" character is escaped for symmetry, characters like
13554      * ">" and "/" don't need escaping in HTML and have no special meaning
13555      * unless they're part of a tag or unquoted attribute value. See
13556      * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
13557      * (under "semi-related fun fact") for more details.
13558      *
13559      * Backticks are escaped because in IE < 9, they can break out of
13560      * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
13561      * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
13562      * [#133](https://html5sec.org/#133) of the
13563      * [HTML5 Security Cheatsheet](https://html5sec.org/) for more details.
13564      *
13565      * When working with HTML you should always
13566      * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
13567      * XSS vectors.
13568      *
13569      * @static
13570      * @since 0.1.0
13571      * @memberOf _
13572      * @category String
13573      * @param {string} [string=''] The string to escape.
13574      * @returns {string} Returns the escaped string.
13575      * @example
13576      *
13577      * _.escape('fred, barney, & pebbles');
13578      * // => 'fred, barney, &amp; pebbles'
13579      */
13580     function escape(string) {
13581       string = toString(string);
13582       return (string && reHasUnescapedHtml.test(string))
13583         ? string.replace(reUnescapedHtml, escapeHtmlChar)
13584         : string;
13585     }
13586
13587     /**
13588      * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
13589      * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
13590      *
13591      * @static
13592      * @memberOf _
13593      * @since 3.0.0
13594      * @category String
13595      * @param {string} [string=''] The string to escape.
13596      * @returns {string} Returns the escaped string.
13597      * @example
13598      *
13599      * _.escapeRegExp('[lodash](https://lodash.com/)');
13600      * // => '\[lodash\]\(https://lodash\.com/\)'
13601      */
13602     function escapeRegExp(string) {
13603       string = toString(string);
13604       return (string && reHasRegExpChar.test(string))
13605         ? string.replace(reRegExpChar, '\\$&')
13606         : string;
13607     }
13608
13609     /**
13610      * Converts `string` to
13611      * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
13612      *
13613      * @static
13614      * @memberOf _
13615      * @since 3.0.0
13616      * @category String
13617      * @param {string} [string=''] The string to convert.
13618      * @returns {string} Returns the kebab cased string.
13619      * @example
13620      *
13621      * _.kebabCase('Foo Bar');
13622      * // => 'foo-bar'
13623      *
13624      * _.kebabCase('fooBar');
13625      * // => 'foo-bar'
13626      *
13627      * _.kebabCase('__FOO_BAR__');
13628      * // => 'foo-bar'
13629      */
13630     var kebabCase = createCompounder(function(result, word, index) {
13631       return result + (index ? '-' : '') + word.toLowerCase();
13632     });
13633
13634     /**
13635      * Converts `string`, as space separated words, to lower case.
13636      *
13637      * @static
13638      * @memberOf _
13639      * @since 4.0.0
13640      * @category String
13641      * @param {string} [string=''] The string to convert.
13642      * @returns {string} Returns the lower cased string.
13643      * @example
13644      *
13645      * _.lowerCase('--Foo-Bar--');
13646      * // => 'foo bar'
13647      *
13648      * _.lowerCase('fooBar');
13649      * // => 'foo bar'
13650      *
13651      * _.lowerCase('__FOO_BAR__');
13652      * // => 'foo bar'
13653      */
13654     var lowerCase = createCompounder(function(result, word, index) {
13655       return result + (index ? ' ' : '') + word.toLowerCase();
13656     });
13657
13658     /**
13659      * Converts the first character of `string` to lower case.
13660      *
13661      * @static
13662      * @memberOf _
13663      * @since 4.0.0
13664      * @category String
13665      * @param {string} [string=''] The string to convert.
13666      * @returns {string} Returns the converted string.
13667      * @example
13668      *
13669      * _.lowerFirst('Fred');
13670      * // => 'fred'
13671      *
13672      * _.lowerFirst('FRED');
13673      * // => 'fRED'
13674      */
13675     var lowerFirst = createCaseFirst('toLowerCase');
13676
13677     /**
13678      * Pads `string` on the left and right sides if it's shorter than `length`.
13679      * Padding characters are truncated if they can't be evenly divided by `length`.
13680      *
13681      * @static
13682      * @memberOf _
13683      * @since 3.0.0
13684      * @category String
13685      * @param {string} [string=''] The string to pad.
13686      * @param {number} [length=0] The padding length.
13687      * @param {string} [chars=' '] The string used as padding.
13688      * @returns {string} Returns the padded string.
13689      * @example
13690      *
13691      * _.pad('abc', 8);
13692      * // => '  abc   '
13693      *
13694      * _.pad('abc', 8, '_-');
13695      * // => '_-abc_-_'
13696      *
13697      * _.pad('abc', 3);
13698      * // => 'abc'
13699      */
13700     function pad(string, length, chars) {
13701       string = toString(string);
13702       length = toInteger(length);
13703
13704       var strLength = length ? stringSize(string) : 0;
13705       if (!length || strLength >= length) {
13706         return string;
13707       }
13708       var mid = (length - strLength) / 2;
13709       return (
13710         createPadding(nativeFloor(mid), chars) +
13711         string +
13712         createPadding(nativeCeil(mid), chars)
13713       );
13714     }
13715
13716     /**
13717      * Pads `string` on the right side if it's shorter than `length`. Padding
13718      * characters are truncated if they exceed `length`.
13719      *
13720      * @static
13721      * @memberOf _
13722      * @since 4.0.0
13723      * @category String
13724      * @param {string} [string=''] The string to pad.
13725      * @param {number} [length=0] The padding length.
13726      * @param {string} [chars=' '] The string used as padding.
13727      * @returns {string} Returns the padded string.
13728      * @example
13729      *
13730      * _.padEnd('abc', 6);
13731      * // => 'abc   '
13732      *
13733      * _.padEnd('abc', 6, '_-');
13734      * // => 'abc_-_'
13735      *
13736      * _.padEnd('abc', 3);
13737      * // => 'abc'
13738      */
13739     function padEnd(string, length, chars) {
13740       string = toString(string);
13741       length = toInteger(length);
13742
13743       var strLength = length ? stringSize(string) : 0;
13744       return (length && strLength < length)
13745         ? (string + createPadding(length - strLength, chars))
13746         : string;
13747     }
13748
13749     /**
13750      * Pads `string` on the left side if it's shorter than `length`. Padding
13751      * characters are truncated if they exceed `length`.
13752      *
13753      * @static
13754      * @memberOf _
13755      * @since 4.0.0
13756      * @category String
13757      * @param {string} [string=''] The string to pad.
13758      * @param {number} [length=0] The padding length.
13759      * @param {string} [chars=' '] The string used as padding.
13760      * @returns {string} Returns the padded string.
13761      * @example
13762      *
13763      * _.padStart('abc', 6);
13764      * // => '   abc'
13765      *
13766      * _.padStart('abc', 6, '_-');
13767      * // => '_-_abc'
13768      *
13769      * _.padStart('abc', 3);
13770      * // => 'abc'
13771      */
13772     function padStart(string, length, chars) {
13773       string = toString(string);
13774       length = toInteger(length);
13775
13776       var strLength = length ? stringSize(string) : 0;
13777       return (length && strLength < length)
13778         ? (createPadding(length - strLength, chars) + string)
13779         : string;
13780     }
13781
13782     /**
13783      * Converts `string` to an integer of the specified radix. If `radix` is
13784      * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
13785      * hexadecimal, in which case a `radix` of `16` is used.
13786      *
13787      * **Note:** This method aligns with the
13788      * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
13789      *
13790      * @static
13791      * @memberOf _
13792      * @since 1.1.0
13793      * @category String
13794      * @param {string} string The string to convert.
13795      * @param {number} [radix=10] The radix to interpret `value` by.
13796      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
13797      * @returns {number} Returns the converted integer.
13798      * @example
13799      *
13800      * _.parseInt('08');
13801      * // => 8
13802      *
13803      * _.map(['6', '08', '10'], _.parseInt);
13804      * // => [6, 8, 10]
13805      */
13806     function parseInt(string, radix, guard) {
13807       // Chrome fails to trim leading <BOM> whitespace characters.
13808       // See https://bugs.chromium.org/p/v8/issues/detail?id=3109 for more details.
13809       if (guard || radix == null) {
13810         radix = 0;
13811       } else if (radix) {
13812         radix = +radix;
13813       }
13814       string = toString(string).replace(reTrim, '');
13815       return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
13816     }
13817
13818     /**
13819      * Repeats the given string `n` times.
13820      *
13821      * @static
13822      * @memberOf _
13823      * @since 3.0.0
13824      * @category String
13825      * @param {string} [string=''] The string to repeat.
13826      * @param {number} [n=1] The number of times to repeat the string.
13827      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
13828      * @returns {string} Returns the repeated string.
13829      * @example
13830      *
13831      * _.repeat('*', 3);
13832      * // => '***'
13833      *
13834      * _.repeat('abc', 2);
13835      * // => 'abcabc'
13836      *
13837      * _.repeat('abc', 0);
13838      * // => ''
13839      */
13840     function repeat(string, n, guard) {
13841       if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
13842         n = 1;
13843       } else {
13844         n = toInteger(n);
13845       }
13846       return baseRepeat(toString(string), n);
13847     }
13848
13849     /**
13850      * Replaces matches for `pattern` in `string` with `replacement`.
13851      *
13852      * **Note:** This method is based on
13853      * [`String#replace`](https://mdn.io/String/replace).
13854      *
13855      * @static
13856      * @memberOf _
13857      * @since 4.0.0
13858      * @category String
13859      * @param {string} [string=''] The string to modify.
13860      * @param {RegExp|string} pattern The pattern to replace.
13861      * @param {Function|string} replacement The match replacement.
13862      * @returns {string} Returns the modified string.
13863      * @example
13864      *
13865      * _.replace('Hi Fred', 'Fred', 'Barney');
13866      * // => 'Hi Barney'
13867      */
13868     function replace() {
13869       var args = arguments,
13870           string = toString(args[0]);
13871
13872       return args.length < 3 ? string : nativeReplace.call(string, args[1], args[2]);
13873     }
13874
13875     /**
13876      * Converts `string` to
13877      * [snake case](https://en.wikipedia.org/wiki/Snake_case).
13878      *
13879      * @static
13880      * @memberOf _
13881      * @since 3.0.0
13882      * @category String
13883      * @param {string} [string=''] The string to convert.
13884      * @returns {string} Returns the snake cased string.
13885      * @example
13886      *
13887      * _.snakeCase('Foo Bar');
13888      * // => 'foo_bar'
13889      *
13890      * _.snakeCase('fooBar');
13891      * // => 'foo_bar'
13892      *
13893      * _.snakeCase('--FOO-BAR--');
13894      * // => 'foo_bar'
13895      */
13896     var snakeCase = createCompounder(function(result, word, index) {
13897       return result + (index ? '_' : '') + word.toLowerCase();
13898     });
13899
13900     /**
13901      * Splits `string` by `separator`.
13902      *
13903      * **Note:** This method is based on
13904      * [`String#split`](https://mdn.io/String/split).
13905      *
13906      * @static
13907      * @memberOf _
13908      * @since 4.0.0
13909      * @category String
13910      * @param {string} [string=''] The string to split.
13911      * @param {RegExp|string} separator The separator pattern to split by.
13912      * @param {number} [limit] The length to truncate results to.
13913      * @returns {Array} Returns the string segments.
13914      * @example
13915      *
13916      * _.split('a-b-c', '-', 2);
13917      * // => ['a', 'b']
13918      */
13919     function split(string, separator, limit) {
13920       if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
13921         separator = limit = undefined;
13922       }
13923       limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
13924       if (!limit) {
13925         return [];
13926       }
13927       string = toString(string);
13928       if (string && (
13929             typeof separator == 'string' ||
13930             (separator != null && !isRegExp(separator))
13931           )) {
13932         separator = baseToString(separator);
13933         if (separator == '' && reHasComplexSymbol.test(string)) {
13934           return castSlice(stringToArray(string), 0, limit);
13935         }
13936       }
13937       return nativeSplit.call(string, separator, limit);
13938     }
13939
13940     /**
13941      * Converts `string` to
13942      * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
13943      *
13944      * @static
13945      * @memberOf _
13946      * @since 3.1.0
13947      * @category String
13948      * @param {string} [string=''] The string to convert.
13949      * @returns {string} Returns the start cased string.
13950      * @example
13951      *
13952      * _.startCase('--foo-bar--');
13953      * // => 'Foo Bar'
13954      *
13955      * _.startCase('fooBar');
13956      * // => 'Foo Bar'
13957      *
13958      * _.startCase('__FOO_BAR__');
13959      * // => 'FOO BAR'
13960      */
13961     var startCase = createCompounder(function(result, word, index) {
13962       return result + (index ? ' ' : '') + upperFirst(word);
13963     });
13964
13965     /**
13966      * Checks if `string` starts with the given target string.
13967      *
13968      * @static
13969      * @memberOf _
13970      * @since 3.0.0
13971      * @category String
13972      * @param {string} [string=''] The string to search.
13973      * @param {string} [target] The string to search for.
13974      * @param {number} [position=0] The position to search from.
13975      * @returns {boolean} Returns `true` if `string` starts with `target`,
13976      *  else `false`.
13977      * @example
13978      *
13979      * _.startsWith('abc', 'a');
13980      * // => true
13981      *
13982      * _.startsWith('abc', 'b');
13983      * // => false
13984      *
13985      * _.startsWith('abc', 'b', 1);
13986      * // => true
13987      */
13988     function startsWith(string, target, position) {
13989       string = toString(string);
13990       position = baseClamp(toInteger(position), 0, string.length);
13991       return string.lastIndexOf(baseToString(target), position) == position;
13992     }
13993
13994     /**
13995      * Creates a compiled template function that can interpolate data properties
13996      * in "interpolate" delimiters, HTML-escape interpolated data properties in
13997      * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
13998      * properties may be accessed as free variables in the template. If a setting
13999      * object is given, it takes precedence over `_.templateSettings` values.
14000      *
14001      * **Note:** In the development build `_.template` utilizes
14002      * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
14003      * for easier debugging.
14004      *
14005      * For more information on precompiling templates see
14006      * [lodash's custom builds documentation](https://lodash.com/custom-builds).
14007      *
14008      * For more information on Chrome extension sandboxes see
14009      * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
14010      *
14011      * @static
14012      * @since 0.1.0
14013      * @memberOf _
14014      * @category String
14015      * @param {string} [string=''] The template string.
14016      * @param {Object} [options={}] The options object.
14017      * @param {RegExp} [options.escape=_.templateSettings.escape]
14018      *  The HTML "escape" delimiter.
14019      * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
14020      *  The "evaluate" delimiter.
14021      * @param {Object} [options.imports=_.templateSettings.imports]
14022      *  An object to import into the template as free variables.
14023      * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
14024      *  The "interpolate" delimiter.
14025      * @param {string} [options.sourceURL='lodash.templateSources[n]']
14026      *  The sourceURL of the compiled template.
14027      * @param {string} [options.variable='obj']
14028      *  The data object variable name.
14029      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14030      * @returns {Function} Returns the compiled template function.
14031      * @example
14032      *
14033      * // Use the "interpolate" delimiter to create a compiled template.
14034      * var compiled = _.template('hello <%= user %>!');
14035      * compiled({ 'user': 'fred' });
14036      * // => 'hello fred!'
14037      *
14038      * // Use the HTML "escape" delimiter to escape data property values.
14039      * var compiled = _.template('<b><%- value %></b>');
14040      * compiled({ 'value': '<script>' });
14041      * // => '<b>&lt;script&gt;</b>'
14042      *
14043      * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
14044      * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
14045      * compiled({ 'users': ['fred', 'barney'] });
14046      * // => '<li>fred</li><li>barney</li>'
14047      *
14048      * // Use the internal `print` function in "evaluate" delimiters.
14049      * var compiled = _.template('<% print("hello " + user); %>!');
14050      * compiled({ 'user': 'barney' });
14051      * // => 'hello barney!'
14052      *
14053      * // Use the ES delimiter as an alternative to the default "interpolate" delimiter.
14054      * var compiled = _.template('hello ${ user }!');
14055      * compiled({ 'user': 'pebbles' });
14056      * // => 'hello pebbles!'
14057      *
14058      * // Use backslashes to treat delimiters as plain text.
14059      * var compiled = _.template('<%= "\\<%- value %\\>" %>');
14060      * compiled({ 'value': 'ignored' });
14061      * // => '<%- value %>'
14062      *
14063      * // Use the `imports` option to import `jQuery` as `jq`.
14064      * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
14065      * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
14066      * compiled({ 'users': ['fred', 'barney'] });
14067      * // => '<li>fred</li><li>barney</li>'
14068      *
14069      * // Use the `sourceURL` option to specify a custom sourceURL for the template.
14070      * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
14071      * compiled(data);
14072      * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
14073      *
14074      * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
14075      * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
14076      * compiled.source;
14077      * // => function(data) {
14078      * //   var __t, __p = '';
14079      * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
14080      * //   return __p;
14081      * // }
14082      *
14083      * // Use custom template delimiters.
14084      * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
14085      * var compiled = _.template('hello {{ user }}!');
14086      * compiled({ 'user': 'mustache' });
14087      * // => 'hello mustache!'
14088      *
14089      * // Use the `source` property to inline compiled templates for meaningful
14090      * // line numbers in error messages and stack traces.
14091      * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
14092      *   var JST = {\
14093      *     "main": ' + _.template(mainText).source + '\
14094      *   };\
14095      * ');
14096      */
14097     function template(string, options, guard) {
14098       // Based on John Resig's `tmpl` implementation
14099       // (http://ejohn.org/blog/javascript-micro-templating/)
14100       // and Laura Doktorova's doT.js (https://github.com/olado/doT).
14101       var settings = lodash.templateSettings;
14102
14103       if (guard && isIterateeCall(string, options, guard)) {
14104         options = undefined;
14105       }
14106       string = toString(string);
14107       options = assignInWith({}, options, settings, assignInDefaults);
14108
14109       var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
14110           importsKeys = keys(imports),
14111           importsValues = baseValues(imports, importsKeys);
14112
14113       var isEscaping,
14114           isEvaluating,
14115           index = 0,
14116           interpolate = options.interpolate || reNoMatch,
14117           source = "__p += '";
14118
14119       // Compile the regexp to match each delimiter.
14120       var reDelimiters = RegExp(
14121         (options.escape || reNoMatch).source + '|' +
14122         interpolate.source + '|' +
14123         (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
14124         (options.evaluate || reNoMatch).source + '|$'
14125       , 'g');
14126
14127       // Use a sourceURL for easier debugging.
14128       var sourceURL = '//# sourceURL=' +
14129         ('sourceURL' in options
14130           ? options.sourceURL
14131           : ('lodash.templateSources[' + (++templateCounter) + ']')
14132         ) + '\n';
14133
14134       string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
14135         interpolateValue || (interpolateValue = esTemplateValue);
14136
14137         // Escape characters that can't be included in string literals.
14138         source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
14139
14140         // Replace delimiters with snippets.
14141         if (escapeValue) {
14142           isEscaping = true;
14143           source += "' +\n__e(" + escapeValue + ") +\n'";
14144         }
14145         if (evaluateValue) {
14146           isEvaluating = true;
14147           source += "';\n" + evaluateValue + ";\n__p += '";
14148         }
14149         if (interpolateValue) {
14150           source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
14151         }
14152         index = offset + match.length;
14153
14154         // The JS engine embedded in Adobe products needs `match` returned in
14155         // order to produce the correct `offset` value.
14156         return match;
14157       });
14158
14159       source += "';\n";
14160
14161       // If `variable` is not specified wrap a with-statement around the generated
14162       // code to add the data object to the top of the scope chain.
14163       var variable = options.variable;
14164       if (!variable) {
14165         source = 'with (obj) {\n' + source + '\n}\n';
14166       }
14167       // Cleanup code by stripping empty strings.
14168       source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
14169         .replace(reEmptyStringMiddle, '$1')
14170         .replace(reEmptyStringTrailing, '$1;');
14171
14172       // Frame code as the function body.
14173       source = 'function(' + (variable || 'obj') + ') {\n' +
14174         (variable
14175           ? ''
14176           : 'obj || (obj = {});\n'
14177         ) +
14178         "var __t, __p = ''" +
14179         (isEscaping
14180            ? ', __e = _.escape'
14181            : ''
14182         ) +
14183         (isEvaluating
14184           ? ', __j = Array.prototype.join;\n' +
14185             "function print() { __p += __j.call(arguments, '') }\n"
14186           : ';\n'
14187         ) +
14188         source +
14189         'return __p\n}';
14190
14191       var result = attempt(function() {
14192         return Function(importsKeys, sourceURL + 'return ' + source)
14193           .apply(undefined, importsValues);
14194       });
14195
14196       // Provide the compiled function's source by its `toString` method or
14197       // the `source` property as a convenience for inlining compiled templates.
14198       result.source = source;
14199       if (isError(result)) {
14200         throw result;
14201       }
14202       return result;
14203     }
14204
14205     /**
14206      * Converts `string`, as a whole, to lower case just like
14207      * [String#toLowerCase](https://mdn.io/toLowerCase).
14208      *
14209      * @static
14210      * @memberOf _
14211      * @since 4.0.0
14212      * @category String
14213      * @param {string} [string=''] The string to convert.
14214      * @returns {string} Returns the lower cased string.
14215      * @example
14216      *
14217      * _.toLower('--Foo-Bar--');
14218      * // => '--foo-bar--'
14219      *
14220      * _.toLower('fooBar');
14221      * // => 'foobar'
14222      *
14223      * _.toLower('__FOO_BAR__');
14224      * // => '__foo_bar__'
14225      */
14226     function toLower(value) {
14227       return toString(value).toLowerCase();
14228     }
14229
14230     /**
14231      * Converts `string`, as a whole, to upper case just like
14232      * [String#toUpperCase](https://mdn.io/toUpperCase).
14233      *
14234      * @static
14235      * @memberOf _
14236      * @since 4.0.0
14237      * @category String
14238      * @param {string} [string=''] The string to convert.
14239      * @returns {string} Returns the upper cased string.
14240      * @example
14241      *
14242      * _.toUpper('--foo-bar--');
14243      * // => '--FOO-BAR--'
14244      *
14245      * _.toUpper('fooBar');
14246      * // => 'FOOBAR'
14247      *
14248      * _.toUpper('__foo_bar__');
14249      * // => '__FOO_BAR__'
14250      */
14251     function toUpper(value) {
14252       return toString(value).toUpperCase();
14253     }
14254
14255     /**
14256      * Removes leading and trailing whitespace or specified characters from `string`.
14257      *
14258      * @static
14259      * @memberOf _
14260      * @since 3.0.0
14261      * @category String
14262      * @param {string} [string=''] The string to trim.
14263      * @param {string} [chars=whitespace] The characters to trim.
14264      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14265      * @returns {string} Returns the trimmed string.
14266      * @example
14267      *
14268      * _.trim('  abc  ');
14269      * // => 'abc'
14270      *
14271      * _.trim('-_-abc-_-', '_-');
14272      * // => 'abc'
14273      *
14274      * _.map(['  foo  ', '  bar  '], _.trim);
14275      * // => ['foo', 'bar']
14276      */
14277     function trim(string, chars, guard) {
14278       string = toString(string);
14279       if (string && (guard || chars === undefined)) {
14280         return string.replace(reTrim, '');
14281       }
14282       if (!string || !(chars = baseToString(chars))) {
14283         return string;
14284       }
14285       var strSymbols = stringToArray(string),
14286           chrSymbols = stringToArray(chars),
14287           start = charsStartIndex(strSymbols, chrSymbols),
14288           end = charsEndIndex(strSymbols, chrSymbols) + 1;
14289
14290       return castSlice(strSymbols, start, end).join('');
14291     }
14292
14293     /**
14294      * Removes trailing whitespace or specified characters from `string`.
14295      *
14296      * @static
14297      * @memberOf _
14298      * @since 4.0.0
14299      * @category String
14300      * @param {string} [string=''] The string to trim.
14301      * @param {string} [chars=whitespace] The characters to trim.
14302      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14303      * @returns {string} Returns the trimmed string.
14304      * @example
14305      *
14306      * _.trimEnd('  abc  ');
14307      * // => '  abc'
14308      *
14309      * _.trimEnd('-_-abc-_-', '_-');
14310      * // => '-_-abc'
14311      */
14312     function trimEnd(string, chars, guard) {
14313       string = toString(string);
14314       if (string && (guard || chars === undefined)) {
14315         return string.replace(reTrimEnd, '');
14316       }
14317       if (!string || !(chars = baseToString(chars))) {
14318         return string;
14319       }
14320       var strSymbols = stringToArray(string),
14321           end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
14322
14323       return castSlice(strSymbols, 0, end).join('');
14324     }
14325
14326     /**
14327      * Removes leading whitespace or specified characters from `string`.
14328      *
14329      * @static
14330      * @memberOf _
14331      * @since 4.0.0
14332      * @category String
14333      * @param {string} [string=''] The string to trim.
14334      * @param {string} [chars=whitespace] The characters to trim.
14335      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14336      * @returns {string} Returns the trimmed string.
14337      * @example
14338      *
14339      * _.trimStart('  abc  ');
14340      * // => 'abc  '
14341      *
14342      * _.trimStart('-_-abc-_-', '_-');
14343      * // => 'abc-_-'
14344      */
14345     function trimStart(string, chars, guard) {
14346       string = toString(string);
14347       if (string && (guard || chars === undefined)) {
14348         return string.replace(reTrimStart, '');
14349       }
14350       if (!string || !(chars = baseToString(chars))) {
14351         return string;
14352       }
14353       var strSymbols = stringToArray(string),
14354           start = charsStartIndex(strSymbols, stringToArray(chars));
14355
14356       return castSlice(strSymbols, start).join('');
14357     }
14358
14359     /**
14360      * Truncates `string` if it's longer than the given maximum string length.
14361      * The last characters of the truncated string are replaced with the omission
14362      * string which defaults to "...".
14363      *
14364      * @static
14365      * @memberOf _
14366      * @since 4.0.0
14367      * @category String
14368      * @param {string} [string=''] The string to truncate.
14369      * @param {Object} [options={}] The options object.
14370      * @param {number} [options.length=30] The maximum string length.
14371      * @param {string} [options.omission='...'] The string to indicate text is omitted.
14372      * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
14373      * @returns {string} Returns the truncated string.
14374      * @example
14375      *
14376      * _.truncate('hi-diddly-ho there, neighborino');
14377      * // => 'hi-diddly-ho there, neighbo...'
14378      *
14379      * _.truncate('hi-diddly-ho there, neighborino', {
14380      *   'length': 24,
14381      *   'separator': ' '
14382      * });
14383      * // => 'hi-diddly-ho there,...'
14384      *
14385      * _.truncate('hi-diddly-ho there, neighborino', {
14386      *   'length': 24,
14387      *   'separator': /,? +/
14388      * });
14389      * // => 'hi-diddly-ho there...'
14390      *
14391      * _.truncate('hi-diddly-ho there, neighborino', {
14392      *   'omission': ' [...]'
14393      * });
14394      * // => 'hi-diddly-ho there, neig [...]'
14395      */
14396     function truncate(string, options) {
14397       var length = DEFAULT_TRUNC_LENGTH,
14398           omission = DEFAULT_TRUNC_OMISSION;
14399
14400       if (isObject(options)) {
14401         var separator = 'separator' in options ? options.separator : separator;
14402         length = 'length' in options ? toInteger(options.length) : length;
14403         omission = 'omission' in options ? baseToString(options.omission) : omission;
14404       }
14405       string = toString(string);
14406
14407       var strLength = string.length;
14408       if (reHasComplexSymbol.test(string)) {
14409         var strSymbols = stringToArray(string);
14410         strLength = strSymbols.length;
14411       }
14412       if (length >= strLength) {
14413         return string;
14414       }
14415       var end = length - stringSize(omission);
14416       if (end < 1) {
14417         return omission;
14418       }
14419       var result = strSymbols
14420         ? castSlice(strSymbols, 0, end).join('')
14421         : string.slice(0, end);
14422
14423       if (separator === undefined) {
14424         return result + omission;
14425       }
14426       if (strSymbols) {
14427         end += (result.length - end);
14428       }
14429       if (isRegExp(separator)) {
14430         if (string.slice(end).search(separator)) {
14431           var match,
14432               substring = result;
14433
14434           if (!separator.global) {
14435             separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
14436           }
14437           separator.lastIndex = 0;
14438           while ((match = separator.exec(substring))) {
14439             var newEnd = match.index;
14440           }
14441           result = result.slice(0, newEnd === undefined ? end : newEnd);
14442         }
14443       } else if (string.indexOf(baseToString(separator), end) != end) {
14444         var index = result.lastIndexOf(separator);
14445         if (index > -1) {
14446           result = result.slice(0, index);
14447         }
14448       }
14449       return result + omission;
14450     }
14451
14452     /**
14453      * The inverse of `_.escape`; this method converts the HTML entities
14454      * `&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to
14455      * their corresponding characters.
14456      *
14457      * **Note:** No other HTML entities are unescaped. To unescape additional
14458      * HTML entities use a third-party library like [_he_](https://mths.be/he).
14459      *
14460      * @static
14461      * @memberOf _
14462      * @since 0.6.0
14463      * @category String
14464      * @param {string} [string=''] The string to unescape.
14465      * @returns {string} Returns the unescaped string.
14466      * @example
14467      *
14468      * _.unescape('fred, barney, &amp; pebbles');
14469      * // => 'fred, barney, & pebbles'
14470      */
14471     function unescape(string) {
14472       string = toString(string);
14473       return (string && reHasEscapedHtml.test(string))
14474         ? string.replace(reEscapedHtml, unescapeHtmlChar)
14475         : string;
14476     }
14477
14478     /**
14479      * Converts `string`, as space separated words, to upper case.
14480      *
14481      * @static
14482      * @memberOf _
14483      * @since 4.0.0
14484      * @category String
14485      * @param {string} [string=''] The string to convert.
14486      * @returns {string} Returns the upper cased string.
14487      * @example
14488      *
14489      * _.upperCase('--foo-bar');
14490      * // => 'FOO BAR'
14491      *
14492      * _.upperCase('fooBar');
14493      * // => 'FOO BAR'
14494      *
14495      * _.upperCase('__foo_bar__');
14496      * // => 'FOO BAR'
14497      */
14498     var upperCase = createCompounder(function(result, word, index) {
14499       return result + (index ? ' ' : '') + word.toUpperCase();
14500     });
14501
14502     /**
14503      * Converts the first character of `string` to upper case.
14504      *
14505      * @static
14506      * @memberOf _
14507      * @since 4.0.0
14508      * @category String
14509      * @param {string} [string=''] The string to convert.
14510      * @returns {string} Returns the converted string.
14511      * @example
14512      *
14513      * _.upperFirst('fred');
14514      * // => 'Fred'
14515      *
14516      * _.upperFirst('FRED');
14517      * // => 'FRED'
14518      */
14519     var upperFirst = createCaseFirst('toUpperCase');
14520
14521     /**
14522      * Splits `string` into an array of its words.
14523      *
14524      * @static
14525      * @memberOf _
14526      * @since 3.0.0
14527      * @category String
14528      * @param {string} [string=''] The string to inspect.
14529      * @param {RegExp|string} [pattern] The pattern to match words.
14530      * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
14531      * @returns {Array} Returns the words of `string`.
14532      * @example
14533      *
14534      * _.words('fred, barney, & pebbles');
14535      * // => ['fred', 'barney', 'pebbles']
14536      *
14537      * _.words('fred, barney, & pebbles', /[^, ]+/g);
14538      * // => ['fred', 'barney', '&', 'pebbles']
14539      */
14540     function words(string, pattern, guard) {
14541       string = toString(string);
14542       pattern = guard ? undefined : pattern;
14543
14544       if (pattern === undefined) {
14545         pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
14546       }
14547       return string.match(pattern) || [];
14548     }
14549
14550     /*------------------------------------------------------------------------*/
14551
14552     /**
14553      * Attempts to invoke `func`, returning either the result or the caught error
14554      * object. Any additional arguments are provided to `func` when it's invoked.
14555      *
14556      * @static
14557      * @memberOf _
14558      * @since 3.0.0
14559      * @category Util
14560      * @param {Function} func The function to attempt.
14561      * @param {...*} [args] The arguments to invoke `func` with.
14562      * @returns {*} Returns the `func` result or error object.
14563      * @example
14564      *
14565      * // Avoid throwing errors for invalid selectors.
14566      * var elements = _.attempt(function(selector) {
14567      *   return document.querySelectorAll(selector);
14568      * }, '>_>');
14569      *
14570      * if (_.isError(elements)) {
14571      *   elements = [];
14572      * }
14573      */
14574     var attempt = rest(function(func, args) {
14575       try {
14576         return apply(func, undefined, args);
14577       } catch (e) {
14578         return isError(e) ? e : new Error(e);
14579       }
14580     });
14581
14582     /**
14583      * Binds methods of an object to the object itself, overwriting the existing
14584      * method.
14585      *
14586      * **Note:** This method doesn't set the "length" property of bound functions.
14587      *
14588      * @static
14589      * @since 0.1.0
14590      * @memberOf _
14591      * @category Util
14592      * @param {Object} object The object to bind and assign the bound methods to.
14593      * @param {...(string|string[])} methodNames The object method names to bind.
14594      * @returns {Object} Returns `object`.
14595      * @example
14596      *
14597      * var view = {
14598      *   'label': 'docs',
14599      *   'onClick': function() {
14600      *     console.log('clicked ' + this.label);
14601      *   }
14602      * };
14603      *
14604      * _.bindAll(view, ['onClick']);
14605      * jQuery(element).on('click', view.onClick);
14606      * // => Logs 'clicked docs' when clicked.
14607      */
14608     var bindAll = rest(function(object, methodNames) {
14609       arrayEach(baseFlatten(methodNames, 1), function(key) {
14610         key = toKey(key);
14611         object[key] = bind(object[key], object);
14612       });
14613       return object;
14614     });
14615
14616     /**
14617      * Creates a function that iterates over `pairs` and invokes the corresponding
14618      * function of the first predicate to return truthy. The predicate-function
14619      * pairs are invoked with the `this` binding and arguments of the created
14620      * function.
14621      *
14622      * @static
14623      * @memberOf _
14624      * @since 4.0.0
14625      * @category Util
14626      * @param {Array} pairs The predicate-function pairs.
14627      * @returns {Function} Returns the new composite function.
14628      * @example
14629      *
14630      * var func = _.cond([
14631      *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
14632      *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
14633      *   [_.constant(true),                _.constant('no match')]
14634      * ]);
14635      *
14636      * func({ 'a': 1, 'b': 2 });
14637      * // => 'matches A'
14638      *
14639      * func({ 'a': 0, 'b': 1 });
14640      * // => 'matches B'
14641      *
14642      * func({ 'a': '1', 'b': '2' });
14643      * // => 'no match'
14644      */
14645     function cond(pairs) {
14646       var length = pairs ? pairs.length : 0,
14647           toIteratee = getIteratee();
14648
14649       pairs = !length ? [] : arrayMap(pairs, function(pair) {
14650         if (typeof pair[1] != 'function') {
14651           throw new TypeError(FUNC_ERROR_TEXT);
14652         }
14653         return [toIteratee(pair[0]), pair[1]];
14654       });
14655
14656       return rest(function(args) {
14657         var index = -1;
14658         while (++index < length) {
14659           var pair = pairs[index];
14660           if (apply(pair[0], this, args)) {
14661             return apply(pair[1], this, args);
14662           }
14663         }
14664       });
14665     }
14666
14667     /**
14668      * Creates a function that invokes the predicate properties of `source` with
14669      * the corresponding property values of a given object, returning `true` if
14670      * all predicates return truthy, else `false`.
14671      *
14672      * @static
14673      * @memberOf _
14674      * @since 4.0.0
14675      * @category Util
14676      * @param {Object} source The object of property predicates to conform to.
14677      * @returns {Function} Returns the new spec function.
14678      * @example
14679      *
14680      * var users = [
14681      *   { 'user': 'barney', 'age': 36 },
14682      *   { 'user': 'fred',   'age': 40 }
14683      * ];
14684      *
14685      * _.filter(users, _.conforms({ 'age': function(n) { return n > 38; } }));
14686      * // => [{ 'user': 'fred', 'age': 40 }]
14687      */
14688     function conforms(source) {
14689       return baseConforms(baseClone(source, true));
14690     }
14691
14692     /**
14693      * Creates a function that returns `value`.
14694      *
14695      * @static
14696      * @memberOf _
14697      * @since 2.4.0
14698      * @category Util
14699      * @param {*} value The value to return from the new function.
14700      * @returns {Function} Returns the new constant function.
14701      * @example
14702      *
14703      * var objects = _.times(2, _.constant({ 'a': 1 }));
14704      *
14705      * console.log(objects);
14706      * // => [{ 'a': 1 }, { 'a': 1 }]
14707      *
14708      * console.log(objects[0] === objects[1]);
14709      * // => true
14710      */
14711     function constant(value) {
14712       return function() {
14713         return value;
14714       };
14715     }
14716
14717     /**
14718      * Creates a function that returns the result of invoking the given functions
14719      * with the `this` binding of the created function, where each successive
14720      * invocation is supplied the return value of the previous.
14721      *
14722      * @static
14723      * @memberOf _
14724      * @since 3.0.0
14725      * @category Util
14726      * @param {...(Function|Function[])} [funcs] Functions to invoke.
14727      * @returns {Function} Returns the new composite function.
14728      * @see _.flowRight
14729      * @example
14730      *
14731      * function square(n) {
14732      *   return n * n;
14733      * }
14734      *
14735      * var addSquare = _.flow([_.add, square]);
14736      * addSquare(1, 2);
14737      * // => 9
14738      */
14739     var flow = createFlow();
14740
14741     /**
14742      * This method is like `_.flow` except that it creates a function that
14743      * invokes the given functions from right to left.
14744      *
14745      * @static
14746      * @since 3.0.0
14747      * @memberOf _
14748      * @category Util
14749      * @param {...(Function|Function[])} [funcs] Functions to invoke.
14750      * @returns {Function} Returns the new composite function.
14751      * @see _.flow
14752      * @example
14753      *
14754      * function square(n) {
14755      *   return n * n;
14756      * }
14757      *
14758      * var addSquare = _.flowRight([square, _.add]);
14759      * addSquare(1, 2);
14760      * // => 9
14761      */
14762     var flowRight = createFlow(true);
14763
14764     /**
14765      * This method returns the first argument given to it.
14766      *
14767      * @static
14768      * @since 0.1.0
14769      * @memberOf _
14770      * @category Util
14771      * @param {*} value Any value.
14772      * @returns {*} Returns `value`.
14773      * @example
14774      *
14775      * var object = { 'user': 'fred' };
14776      *
14777      * console.log(_.identity(object) === object);
14778      * // => true
14779      */
14780     function identity(value) {
14781       return value;
14782     }
14783
14784     /**
14785      * Creates a function that invokes `func` with the arguments of the created
14786      * function. If `func` is a property name, the created function returns the
14787      * property value for a given element. If `func` is an array or object, the
14788      * created function returns `true` for elements that contain the equivalent
14789      * source properties, otherwise it returns `false`.
14790      *
14791      * @static
14792      * @since 4.0.0
14793      * @memberOf _
14794      * @category Util
14795      * @param {*} [func=_.identity] The value to convert to a callback.
14796      * @returns {Function} Returns the callback.
14797      * @example
14798      *
14799      * var users = [
14800      *   { 'user': 'barney', 'age': 36, 'active': true },
14801      *   { 'user': 'fred',   'age': 40, 'active': false }
14802      * ];
14803      *
14804      * // The `_.matches` iteratee shorthand.
14805      * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
14806      * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
14807      *
14808      * // The `_.matchesProperty` iteratee shorthand.
14809      * _.filter(users, _.iteratee(['user', 'fred']));
14810      * // => [{ 'user': 'fred', 'age': 40 }]
14811      *
14812      * // The `_.property` iteratee shorthand.
14813      * _.map(users, _.iteratee('user'));
14814      * // => ['barney', 'fred']
14815      *
14816      * // Create custom iteratee shorthands.
14817      * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
14818      *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
14819      *     return func.test(string);
14820      *   };
14821      * });
14822      *
14823      * _.filter(['abc', 'def'], /ef/);
14824      * // => ['def']
14825      */
14826     function iteratee(func) {
14827       return baseIteratee(typeof func == 'function' ? func : baseClone(func, true));
14828     }
14829
14830     /**
14831      * Creates a function that performs a partial deep comparison between a given
14832      * object and `source`, returning `true` if the given object has equivalent
14833      * property values, else `false`. The created function is equivalent to
14834      * `_.isMatch` with a `source` partially applied.
14835      *
14836      * **Note:** This method supports comparing the same values as `_.isEqual`.
14837      *
14838      * @static
14839      * @memberOf _
14840      * @since 3.0.0
14841      * @category Util
14842      * @param {Object} source The object of property values to match.
14843      * @returns {Function} Returns the new spec function.
14844      * @example
14845      *
14846      * var users = [
14847      *   { 'user': 'barney', 'age': 36, 'active': true },
14848      *   { 'user': 'fred',   'age': 40, 'active': false }
14849      * ];
14850      *
14851      * _.filter(users, _.matches({ 'age': 40, 'active': false }));
14852      * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
14853      */
14854     function matches(source) {
14855       return baseMatches(baseClone(source, true));
14856     }
14857
14858     /**
14859      * Creates a function that performs a partial deep comparison between the
14860      * value at `path` of a given object to `srcValue`, returning `true` if the
14861      * object value is equivalent, else `false`.
14862      *
14863      * **Note:** This method supports comparing the same values as `_.isEqual`.
14864      *
14865      * @static
14866      * @memberOf _
14867      * @since 3.2.0
14868      * @category Util
14869      * @param {Array|string} path The path of the property to get.
14870      * @param {*} srcValue The value to match.
14871      * @returns {Function} Returns the new spec function.
14872      * @example
14873      *
14874      * var users = [
14875      *   { 'user': 'barney' },
14876      *   { 'user': 'fred' }
14877      * ];
14878      *
14879      * _.find(users, _.matchesProperty('user', 'fred'));
14880      * // => { 'user': 'fred' }
14881      */
14882     function matchesProperty(path, srcValue) {
14883       return baseMatchesProperty(path, baseClone(srcValue, true));
14884     }
14885
14886     /**
14887      * Creates a function that invokes the method at `path` of a given object.
14888      * Any additional arguments are provided to the invoked method.
14889      *
14890      * @static
14891      * @memberOf _
14892      * @since 3.7.0
14893      * @category Util
14894      * @param {Array|string} path The path of the method to invoke.
14895      * @param {...*} [args] The arguments to invoke the method with.
14896      * @returns {Function} Returns the new invoker function.
14897      * @example
14898      *
14899      * var objects = [
14900      *   { 'a': { 'b': _.constant(2) } },
14901      *   { 'a': { 'b': _.constant(1) } }
14902      * ];
14903      *
14904      * _.map(objects, _.method('a.b'));
14905      * // => [2, 1]
14906      *
14907      * _.map(objects, _.method(['a', 'b']));
14908      * // => [2, 1]
14909      */
14910     var method = rest(function(path, args) {
14911       return function(object) {
14912         return baseInvoke(object, path, args);
14913       };
14914     });
14915
14916     /**
14917      * The opposite of `_.method`; this method creates a function that invokes
14918      * the method at a given path of `object`. Any additional arguments are
14919      * provided to the invoked method.
14920      *
14921      * @static
14922      * @memberOf _
14923      * @since 3.7.0
14924      * @category Util
14925      * @param {Object} object The object to query.
14926      * @param {...*} [args] The arguments to invoke the method with.
14927      * @returns {Function} Returns the new invoker function.
14928      * @example
14929      *
14930      * var array = _.times(3, _.constant),
14931      *     object = { 'a': array, 'b': array, 'c': array };
14932      *
14933      * _.map(['a[2]', 'c[0]'], _.methodOf(object));
14934      * // => [2, 0]
14935      *
14936      * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
14937      * // => [2, 0]
14938      */
14939     var methodOf = rest(function(object, args) {
14940       return function(path) {
14941         return baseInvoke(object, path, args);
14942       };
14943     });
14944
14945     /**
14946      * Adds all own enumerable string keyed function properties of a source
14947      * object to the destination object. If `object` is a function, then methods
14948      * are added to its prototype as well.
14949      *
14950      * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
14951      * avoid conflicts caused by modifying the original.
14952      *
14953      * @static
14954      * @since 0.1.0
14955      * @memberOf _
14956      * @category Util
14957      * @param {Function|Object} [object=lodash] The destination object.
14958      * @param {Object} source The object of functions to add.
14959      * @param {Object} [options={}] The options object.
14960      * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
14961      * @returns {Function|Object} Returns `object`.
14962      * @example
14963      *
14964      * function vowels(string) {
14965      *   return _.filter(string, function(v) {
14966      *     return /[aeiou]/i.test(v);
14967      *   });
14968      * }
14969      *
14970      * _.mixin({ 'vowels': vowels });
14971      * _.vowels('fred');
14972      * // => ['e']
14973      *
14974      * _('fred').vowels().value();
14975      * // => ['e']
14976      *
14977      * _.mixin({ 'vowels': vowels }, { 'chain': false });
14978      * _('fred').vowels();
14979      * // => ['e']
14980      */
14981     function mixin(object, source, options) {
14982       var props = keys(source),
14983           methodNames = baseFunctions(source, props);
14984
14985       if (options == null &&
14986           !(isObject(source) && (methodNames.length || !props.length))) {
14987         options = source;
14988         source = object;
14989         object = this;
14990         methodNames = baseFunctions(source, keys(source));
14991       }
14992       var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
14993           isFunc = isFunction(object);
14994
14995       arrayEach(methodNames, function(methodName) {
14996         var func = source[methodName];
14997         object[methodName] = func;
14998         if (isFunc) {
14999           object.prototype[methodName] = function() {
15000             var chainAll = this.__chain__;
15001             if (chain || chainAll) {
15002               var result = object(this.__wrapped__),
15003                   actions = result.__actions__ = copyArray(this.__actions__);
15004
15005               actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
15006               result.__chain__ = chainAll;
15007               return result;
15008             }
15009             return func.apply(object, arrayPush([this.value()], arguments));
15010           };
15011         }
15012       });
15013
15014       return object;
15015     }
15016
15017     /**
15018      * Reverts the `_` variable to its previous value and returns a reference to
15019      * the `lodash` function.
15020      *
15021      * @static
15022      * @since 0.1.0
15023      * @memberOf _
15024      * @category Util
15025      * @returns {Function} Returns the `lodash` function.
15026      * @example
15027      *
15028      * var lodash = _.noConflict();
15029      */
15030     function noConflict() {
15031       if (root._ === this) {
15032         root._ = oldDash;
15033       }
15034       return this;
15035     }
15036
15037     /**
15038      * A method that returns `undefined`.
15039      *
15040      * @static
15041      * @memberOf _
15042      * @since 2.3.0
15043      * @category Util
15044      * @example
15045      *
15046      * _.times(2, _.noop);
15047      * // => [undefined, undefined]
15048      */
15049     function noop() {
15050       // No operation performed.
15051     }
15052
15053     /**
15054      * Creates a function that gets the argument at index `n`. If `n` is negative,
15055      * the nth argument from the end is returned.
15056      *
15057      * @static
15058      * @memberOf _
15059      * @since 4.0.0
15060      * @category Util
15061      * @param {number} [n=0] The index of the argument to return.
15062      * @returns {Function} Returns the new pass-thru function.
15063      * @example
15064      *
15065      * var func = _.nthArg(1);
15066      * func('a', 'b', 'c', 'd');
15067      * // => 'b'
15068      *
15069      * var func = _.nthArg(-2);
15070      * func('a', 'b', 'c', 'd');
15071      * // => 'c'
15072      */
15073     function nthArg(n) {
15074       n = toInteger(n);
15075       return rest(function(args) {
15076         return baseNth(args, n);
15077       });
15078     }
15079
15080     /**
15081      * Creates a function that invokes `iteratees` with the arguments it receives
15082      * and returns their results.
15083      *
15084      * @static
15085      * @memberOf _
15086      * @since 4.0.0
15087      * @category Util
15088      * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
15089      *  [iteratees=[_.identity]] The iteratees to invoke.
15090      * @returns {Function} Returns the new function.
15091      * @example
15092      *
15093      * var func = _.over([Math.max, Math.min]);
15094      *
15095      * func(1, 2, 3, 4);
15096      * // => [4, 1]
15097      */
15098     var over = createOver(arrayMap);
15099
15100     /**
15101      * Creates a function that checks if **all** of the `predicates` return
15102      * truthy when invoked with the arguments it receives.
15103      *
15104      * @static
15105      * @memberOf _
15106      * @since 4.0.0
15107      * @category Util
15108      * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
15109      *  [predicates=[_.identity]] The predicates to check.
15110      * @returns {Function} Returns the new function.
15111      * @example
15112      *
15113      * var func = _.overEvery([Boolean, isFinite]);
15114      *
15115      * func('1');
15116      * // => true
15117      *
15118      * func(null);
15119      * // => false
15120      *
15121      * func(NaN);
15122      * // => false
15123      */
15124     var overEvery = createOver(arrayEvery);
15125
15126     /**
15127      * Creates a function that checks if **any** of the `predicates` return
15128      * truthy when invoked with the arguments it receives.
15129      *
15130      * @static
15131      * @memberOf _
15132      * @since 4.0.0
15133      * @category Util
15134      * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
15135      *  [predicates=[_.identity]] The predicates to check.
15136      * @returns {Function} Returns the new function.
15137      * @example
15138      *
15139      * var func = _.overSome([Boolean, isFinite]);
15140      *
15141      * func('1');
15142      * // => true
15143      *
15144      * func(null);
15145      * // => true
15146      *
15147      * func(NaN);
15148      * // => false
15149      */
15150     var overSome = createOver(arraySome);
15151
15152     /**
15153      * Creates a function that returns the value at `path` of a given object.
15154      *
15155      * @static
15156      * @memberOf _
15157      * @since 2.4.0
15158      * @category Util
15159      * @param {Array|string} path The path of the property to get.
15160      * @returns {Function} Returns the new accessor function.
15161      * @example
15162      *
15163      * var objects = [
15164      *   { 'a': { 'b': 2 } },
15165      *   { 'a': { 'b': 1 } }
15166      * ];
15167      *
15168      * _.map(objects, _.property('a.b'));
15169      * // => [2, 1]
15170      *
15171      * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
15172      * // => [1, 2]
15173      */
15174     function property(path) {
15175       return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
15176     }
15177
15178     /**
15179      * The opposite of `_.property`; this method creates a function that returns
15180      * the value at a given path of `object`.
15181      *
15182      * @static
15183      * @memberOf _
15184      * @since 3.0.0
15185      * @category Util
15186      * @param {Object} object The object to query.
15187      * @returns {Function} Returns the new accessor function.
15188      * @example
15189      *
15190      * var array = [0, 1, 2],
15191      *     object = { 'a': array, 'b': array, 'c': array };
15192      *
15193      * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
15194      * // => [2, 0]
15195      *
15196      * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
15197      * // => [2, 0]
15198      */
15199     function propertyOf(object) {
15200       return function(path) {
15201         return object == null ? undefined : baseGet(object, path);
15202       };
15203     }
15204
15205     /**
15206      * Creates an array of numbers (positive and/or negative) progressing from
15207      * `start` up to, but not including, `end`. A step of `-1` is used if a negative
15208      * `start` is specified without an `end` or `step`. If `end` is not specified,
15209      * it's set to `start` with `start` then set to `0`.
15210      *
15211      * **Note:** JavaScript follows the IEEE-754 standard for resolving
15212      * floating-point values which can produce unexpected results.
15213      *
15214      * @static
15215      * @since 0.1.0
15216      * @memberOf _
15217      * @category Util
15218      * @param {number} [start=0] The start of the range.
15219      * @param {number} end The end of the range.
15220      * @param {number} [step=1] The value to increment or decrement by.
15221      * @returns {Array} Returns the range of numbers.
15222      * @see _.inRange, _.rangeRight
15223      * @example
15224      *
15225      * _.range(4);
15226      * // => [0, 1, 2, 3]
15227      *
15228      * _.range(-4);
15229      * // => [0, -1, -2, -3]
15230      *
15231      * _.range(1, 5);
15232      * // => [1, 2, 3, 4]
15233      *
15234      * _.range(0, 20, 5);
15235      * // => [0, 5, 10, 15]
15236      *
15237      * _.range(0, -4, -1);
15238      * // => [0, -1, -2, -3]
15239      *
15240      * _.range(1, 4, 0);
15241      * // => [1, 1, 1]
15242      *
15243      * _.range(0);
15244      * // => []
15245      */
15246     var range = createRange();
15247
15248     /**
15249      * This method is like `_.range` except that it populates values in
15250      * descending order.
15251      *
15252      * @static
15253      * @memberOf _
15254      * @since 4.0.0
15255      * @category Util
15256      * @param {number} [start=0] The start of the range.
15257      * @param {number} end The end of the range.
15258      * @param {number} [step=1] The value to increment or decrement by.
15259      * @returns {Array} Returns the range of numbers.
15260      * @see _.inRange, _.range
15261      * @example
15262      *
15263      * _.rangeRight(4);
15264      * // => [3, 2, 1, 0]
15265      *
15266      * _.rangeRight(-4);
15267      * // => [-3, -2, -1, 0]
15268      *
15269      * _.rangeRight(1, 5);
15270      * // => [4, 3, 2, 1]
15271      *
15272      * _.rangeRight(0, 20, 5);
15273      * // => [15, 10, 5, 0]
15274      *
15275      * _.rangeRight(0, -4, -1);
15276      * // => [-3, -2, -1, 0]
15277      *
15278      * _.rangeRight(1, 4, 0);
15279      * // => [1, 1, 1]
15280      *
15281      * _.rangeRight(0);
15282      * // => []
15283      */
15284     var rangeRight = createRange(true);
15285
15286     /**
15287      * A method that returns a new empty array.
15288      *
15289      * @static
15290      * @memberOf _
15291      * @since 4.13.0
15292      * @category Util
15293      * @returns {Array} Returns the new empty array.
15294      * @example
15295      *
15296      * var arrays = _.times(2, _.stubArray);
15297      *
15298      * console.log(arrays);
15299      * // => [[], []]
15300      *
15301      * console.log(arrays[0] === arrays[1]);
15302      * // => false
15303      */
15304     function stubArray() {
15305       return [];
15306     }
15307
15308     /**
15309      * A method that returns `false`.
15310      *
15311      * @static
15312      * @memberOf _
15313      * @since 4.13.0
15314      * @category Util
15315      * @returns {boolean} Returns `false`.
15316      * @example
15317      *
15318      * _.times(2, _.stubFalse);
15319      * // => [false, false]
15320      */
15321     function stubFalse() {
15322       return false;
15323     }
15324
15325     /**
15326      * A method that returns a new empty object.
15327      *
15328      * @static
15329      * @memberOf _
15330      * @since 4.13.0
15331      * @category Util
15332      * @returns {Object} Returns the new empty object.
15333      * @example
15334      *
15335      * var objects = _.times(2, _.stubObject);
15336      *
15337      * console.log(objects);
15338      * // => [{}, {}]
15339      *
15340      * console.log(objects[0] === objects[1]);
15341      * // => false
15342      */
15343     function stubObject() {
15344       return {};
15345     }
15346
15347     /**
15348      * A method that returns an empty string.
15349      *
15350      * @static
15351      * @memberOf _
15352      * @since 4.13.0
15353      * @category Util
15354      * @returns {string} Returns the empty string.
15355      * @example
15356      *
15357      * _.times(2, _.stubString);
15358      * // => ['', '']
15359      */
15360     function stubString() {
15361       return '';
15362     }
15363
15364     /**
15365      * A method that returns `true`.
15366      *
15367      * @static
15368      * @memberOf _
15369      * @since 4.13.0
15370      * @category Util
15371      * @returns {boolean} Returns `true`.
15372      * @example
15373      *
15374      * _.times(2, _.stubTrue);
15375      * // => [true, true]
15376      */
15377     function stubTrue() {
15378       return true;
15379     }
15380
15381     /**
15382      * Invokes the iteratee `n` times, returning an array of the results of
15383      * each invocation. The iteratee is invoked with one argument; (index).
15384      *
15385      * @static
15386      * @since 0.1.0
15387      * @memberOf _
15388      * @category Util
15389      * @param {number} n The number of times to invoke `iteratee`.
15390      * @param {Function} [iteratee=_.identity] The function invoked per iteration.
15391      * @returns {Array} Returns the array of results.
15392      * @example
15393      *
15394      * _.times(3, String);
15395      * // => ['0', '1', '2']
15396      *
15397      *  _.times(4, _.constant(0));
15398      * // => [0, 0, 0, 0]
15399      */
15400     function times(n, iteratee) {
15401       n = toInteger(n);
15402       if (n < 1 || n > MAX_SAFE_INTEGER) {
15403         return [];
15404       }
15405       var index = MAX_ARRAY_LENGTH,
15406           length = nativeMin(n, MAX_ARRAY_LENGTH);
15407
15408       iteratee = getIteratee(iteratee);
15409       n -= MAX_ARRAY_LENGTH;
15410
15411       var result = baseTimes(length, iteratee);
15412       while (++index < n) {
15413         iteratee(index);
15414       }
15415       return result;
15416     }
15417
15418     /**
15419      * Converts `value` to a property path array.
15420      *
15421      * @static
15422      * @memberOf _
15423      * @since 4.0.0
15424      * @category Util
15425      * @param {*} value The value to convert.
15426      * @returns {Array} Returns the new property path array.
15427      * @example
15428      *
15429      * _.toPath('a.b.c');
15430      * // => ['a', 'b', 'c']
15431      *
15432      * _.toPath('a[0].b.c');
15433      * // => ['a', '0', 'b', 'c']
15434      */
15435     function toPath(value) {
15436       if (isArray(value)) {
15437         return arrayMap(value, toKey);
15438       }
15439       return isSymbol(value) ? [value] : copyArray(stringToPath(value));
15440     }
15441
15442     /**
15443      * Generates a unique ID. If `prefix` is given, the ID is appended to it.
15444      *
15445      * @static
15446      * @since 0.1.0
15447      * @memberOf _
15448      * @category Util
15449      * @param {string} [prefix=''] The value to prefix the ID with.
15450      * @returns {string} Returns the unique ID.
15451      * @example
15452      *
15453      * _.uniqueId('contact_');
15454      * // => 'contact_104'
15455      *
15456      * _.uniqueId();
15457      * // => '105'
15458      */
15459     function uniqueId(prefix) {
15460       var id = ++idCounter;
15461       return toString(prefix) + id;
15462     }
15463
15464     /*------------------------------------------------------------------------*/
15465
15466     /**
15467      * Adds two numbers.
15468      *
15469      * @static
15470      * @memberOf _
15471      * @since 3.4.0
15472      * @category Math
15473      * @param {number} augend The first number in an addition.
15474      * @param {number} addend The second number in an addition.
15475      * @returns {number} Returns the total.
15476      * @example
15477      *
15478      * _.add(6, 4);
15479      * // => 10
15480      */
15481     var add = createMathOperation(function(augend, addend) {
15482       return augend + addend;
15483     });
15484
15485     /**
15486      * Computes `number` rounded up to `precision`.
15487      *
15488      * @static
15489      * @memberOf _
15490      * @since 3.10.0
15491      * @category Math
15492      * @param {number} number The number to round up.
15493      * @param {number} [precision=0] The precision to round up to.
15494      * @returns {number} Returns the rounded up number.
15495      * @example
15496      *
15497      * _.ceil(4.006);
15498      * // => 5
15499      *
15500      * _.ceil(6.004, 2);
15501      * // => 6.01
15502      *
15503      * _.ceil(6040, -2);
15504      * // => 6100
15505      */
15506     var ceil = createRound('ceil');
15507
15508     /**
15509      * Divide two numbers.
15510      *
15511      * @static
15512      * @memberOf _
15513      * @since 4.7.0
15514      * @category Math
15515      * @param {number} dividend The first number in a division.
15516      * @param {number} divisor The second number in a division.
15517      * @returns {number} Returns the quotient.
15518      * @example
15519      *
15520      * _.divide(6, 4);
15521      * // => 1.5
15522      */
15523     var divide = createMathOperation(function(dividend, divisor) {
15524       return dividend / divisor;
15525     });
15526
15527     /**
15528      * Computes `number` rounded down to `precision`.
15529      *
15530      * @static
15531      * @memberOf _
15532      * @since 3.10.0
15533      * @category Math
15534      * @param {number} number The number to round down.
15535      * @param {number} [precision=0] The precision to round down to.
15536      * @returns {number} Returns the rounded down number.
15537      * @example
15538      *
15539      * _.floor(4.006);
15540      * // => 4
15541      *
15542      * _.floor(0.046, 2);
15543      * // => 0.04
15544      *
15545      * _.floor(4060, -2);
15546      * // => 4000
15547      */
15548     var floor = createRound('floor');
15549
15550     /**
15551      * Computes the maximum value of `array`. If `array` is empty or falsey,
15552      * `undefined` is returned.
15553      *
15554      * @static
15555      * @since 0.1.0
15556      * @memberOf _
15557      * @category Math
15558      * @param {Array} array The array to iterate over.
15559      * @returns {*} Returns the maximum value.
15560      * @example
15561      *
15562      * _.max([4, 2, 8, 6]);
15563      * // => 8
15564      *
15565      * _.max([]);
15566      * // => undefined
15567      */
15568     function max(array) {
15569       return (array && array.length)
15570         ? baseExtremum(array, identity, baseGt)
15571         : undefined;
15572     }
15573
15574     /**
15575      * This method is like `_.max` except that it accepts `iteratee` which is
15576      * invoked for each element in `array` to generate the criterion by which
15577      * the value is ranked. The iteratee is invoked with one argument: (value).
15578      *
15579      * @static
15580      * @memberOf _
15581      * @since 4.0.0
15582      * @category Math
15583      * @param {Array} array The array to iterate over.
15584      * @param {Array|Function|Object|string} [iteratee=_.identity]
15585      *  The iteratee invoked per element.
15586      * @returns {*} Returns the maximum value.
15587      * @example
15588      *
15589      * var objects = [{ 'n': 1 }, { 'n': 2 }];
15590      *
15591      * _.maxBy(objects, function(o) { return o.n; });
15592      * // => { 'n': 2 }
15593      *
15594      * // The `_.property` iteratee shorthand.
15595      * _.maxBy(objects, 'n');
15596      * // => { 'n': 2 }
15597      */
15598     function maxBy(array, iteratee) {
15599       return (array && array.length)
15600         ? baseExtremum(array, getIteratee(iteratee), baseGt)
15601         : undefined;
15602     }
15603
15604     /**
15605      * Computes the mean of the values in `array`.
15606      *
15607      * @static
15608      * @memberOf _
15609      * @since 4.0.0
15610      * @category Math
15611      * @param {Array} array The array to iterate over.
15612      * @returns {number} Returns the mean.
15613      * @example
15614      *
15615      * _.mean([4, 2, 8, 6]);
15616      * // => 5
15617      */
15618     function mean(array) {
15619       return baseMean(array, identity);
15620     }
15621
15622     /**
15623      * This method is like `_.mean` except that it accepts `iteratee` which is
15624      * invoked for each element in `array` to generate the value to be averaged.
15625      * The iteratee is invoked with one argument: (value).
15626      *
15627      * @static
15628      * @memberOf _
15629      * @since 4.7.0
15630      * @category Math
15631      * @param {Array} array The array to iterate over.
15632      * @param {Array|Function|Object|string} [iteratee=_.identity]
15633      *  The iteratee invoked per element.
15634      * @returns {number} Returns the mean.
15635      * @example
15636      *
15637      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
15638      *
15639      * _.meanBy(objects, function(o) { return o.n; });
15640      * // => 5
15641      *
15642      * // The `_.property` iteratee shorthand.
15643      * _.meanBy(objects, 'n');
15644      * // => 5
15645      */
15646     function meanBy(array, iteratee) {
15647       return baseMean(array, getIteratee(iteratee));
15648     }
15649
15650     /**
15651      * Computes the minimum value of `array`. If `array` is empty or falsey,
15652      * `undefined` is returned.
15653      *
15654      * @static
15655      * @since 0.1.0
15656      * @memberOf _
15657      * @category Math
15658      * @param {Array} array The array to iterate over.
15659      * @returns {*} Returns the minimum value.
15660      * @example
15661      *
15662      * _.min([4, 2, 8, 6]);
15663      * // => 2
15664      *
15665      * _.min([]);
15666      * // => undefined
15667      */
15668     function min(array) {
15669       return (array && array.length)
15670         ? baseExtremum(array, identity, baseLt)
15671         : undefined;
15672     }
15673
15674     /**
15675      * This method is like `_.min` except that it accepts `iteratee` which is
15676      * invoked for each element in `array` to generate the criterion by which
15677      * the value is ranked. The iteratee is invoked with one argument: (value).
15678      *
15679      * @static
15680      * @memberOf _
15681      * @since 4.0.0
15682      * @category Math
15683      * @param {Array} array The array to iterate over.
15684      * @param {Array|Function|Object|string} [iteratee=_.identity]
15685      *  The iteratee invoked per element.
15686      * @returns {*} Returns the minimum value.
15687      * @example
15688      *
15689      * var objects = [{ 'n': 1 }, { 'n': 2 }];
15690      *
15691      * _.minBy(objects, function(o) { return o.n; });
15692      * // => { 'n': 1 }
15693      *
15694      * // The `_.property` iteratee shorthand.
15695      * _.minBy(objects, 'n');
15696      * // => { 'n': 1 }
15697      */
15698     function minBy(array, iteratee) {
15699       return (array && array.length)
15700         ? baseExtremum(array, getIteratee(iteratee), baseLt)
15701         : undefined;
15702     }
15703
15704     /**
15705      * Multiply two numbers.
15706      *
15707      * @static
15708      * @memberOf _
15709      * @since 4.7.0
15710      * @category Math
15711      * @param {number} multiplier The first number in a multiplication.
15712      * @param {number} multiplicand The second number in a multiplication.
15713      * @returns {number} Returns the product.
15714      * @example
15715      *
15716      * _.multiply(6, 4);
15717      * // => 24
15718      */
15719     var multiply = createMathOperation(function(multiplier, multiplicand) {
15720       return multiplier * multiplicand;
15721     });
15722
15723     /**
15724      * Computes `number` rounded to `precision`.
15725      *
15726      * @static
15727      * @memberOf _
15728      * @since 3.10.0
15729      * @category Math
15730      * @param {number} number The number to round.
15731      * @param {number} [precision=0] The precision to round to.
15732      * @returns {number} Returns the rounded number.
15733      * @example
15734      *
15735      * _.round(4.006);
15736      * // => 4
15737      *
15738      * _.round(4.006, 2);
15739      * // => 4.01
15740      *
15741      * _.round(4060, -2);
15742      * // => 4100
15743      */
15744     var round = createRound('round');
15745
15746     /**
15747      * Subtract two numbers.
15748      *
15749      * @static
15750      * @memberOf _
15751      * @since 4.0.0
15752      * @category Math
15753      * @param {number} minuend The first number in a subtraction.
15754      * @param {number} subtrahend The second number in a subtraction.
15755      * @returns {number} Returns the difference.
15756      * @example
15757      *
15758      * _.subtract(6, 4);
15759      * // => 2
15760      */
15761     var subtract = createMathOperation(function(minuend, subtrahend) {
15762       return minuend - subtrahend;
15763     });
15764
15765     /**
15766      * Computes the sum of the values in `array`.
15767      *
15768      * @static
15769      * @memberOf _
15770      * @since 3.4.0
15771      * @category Math
15772      * @param {Array} array The array to iterate over.
15773      * @returns {number} Returns the sum.
15774      * @example
15775      *
15776      * _.sum([4, 2, 8, 6]);
15777      * // => 20
15778      */
15779     function sum(array) {
15780       return (array && array.length)
15781         ? baseSum(array, identity)
15782         : 0;
15783     }
15784
15785     /**
15786      * This method is like `_.sum` except that it accepts `iteratee` which is
15787      * invoked for each element in `array` to generate the value to be summed.
15788      * The iteratee is invoked with one argument: (value).
15789      *
15790      * @static
15791      * @memberOf _
15792      * @since 4.0.0
15793      * @category Math
15794      * @param {Array} array The array to iterate over.
15795      * @param {Array|Function|Object|string} [iteratee=_.identity]
15796      *  The iteratee invoked per element.
15797      * @returns {number} Returns the sum.
15798      * @example
15799      *
15800      * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
15801      *
15802      * _.sumBy(objects, function(o) { return o.n; });
15803      * // => 20
15804      *
15805      * // The `_.property` iteratee shorthand.
15806      * _.sumBy(objects, 'n');
15807      * // => 20
15808      */
15809     function sumBy(array, iteratee) {
15810       return (array && array.length)
15811         ? baseSum(array, getIteratee(iteratee))
15812         : 0;
15813     }
15814
15815     /*------------------------------------------------------------------------*/
15816
15817     // Add methods that return wrapped values in chain sequences.
15818     lodash.after = after;
15819     lodash.ary = ary;
15820     lodash.assign = assign;
15821     lodash.assignIn = assignIn;
15822     lodash.assignInWith = assignInWith;
15823     lodash.assignWith = assignWith;
15824     lodash.at = at;
15825     lodash.before = before;
15826     lodash.bind = bind;
15827     lodash.bindAll = bindAll;
15828     lodash.bindKey = bindKey;
15829     lodash.castArray = castArray;
15830     lodash.chain = chain;
15831     lodash.chunk = chunk;
15832     lodash.compact = compact;
15833     lodash.concat = concat;
15834     lodash.cond = cond;
15835     lodash.conforms = conforms;
15836     lodash.constant = constant;
15837     lodash.countBy = countBy;
15838     lodash.create = create;
15839     lodash.curry = curry;
15840     lodash.curryRight = curryRight;
15841     lodash.debounce = debounce;
15842     lodash.defaults = defaults;
15843     lodash.defaultsDeep = defaultsDeep;
15844     lodash.defer = defer;
15845     lodash.delay = delay;
15846     lodash.difference = difference;
15847     lodash.differenceBy = differenceBy;
15848     lodash.differenceWith = differenceWith;
15849     lodash.drop = drop;
15850     lodash.dropRight = dropRight;
15851     lodash.dropRightWhile = dropRightWhile;
15852     lodash.dropWhile = dropWhile;
15853     lodash.fill = fill;
15854     lodash.filter = filter;
15855     lodash.flatMap = flatMap;
15856     lodash.flatMapDeep = flatMapDeep;
15857     lodash.flatMapDepth = flatMapDepth;
15858     lodash.flatten = flatten;
15859     lodash.flattenDeep = flattenDeep;
15860     lodash.flattenDepth = flattenDepth;
15861     lodash.flip = flip;
15862     lodash.flow = flow;
15863     lodash.flowRight = flowRight;
15864     lodash.fromPairs = fromPairs;
15865     lodash.functions = functions;
15866     lodash.functionsIn = functionsIn;
15867     lodash.groupBy = groupBy;
15868     lodash.initial = initial;
15869     lodash.intersection = intersection;
15870     lodash.intersectionBy = intersectionBy;
15871     lodash.intersectionWith = intersectionWith;
15872     lodash.invert = invert;
15873     lodash.invertBy = invertBy;
15874     lodash.invokeMap = invokeMap;
15875     lodash.iteratee = iteratee;
15876     lodash.keyBy = keyBy;
15877     lodash.keys = keys;
15878     lodash.keysIn = keysIn;
15879     lodash.map = map;
15880     lodash.mapKeys = mapKeys;
15881     lodash.mapValues = mapValues;
15882     lodash.matches = matches;
15883     lodash.matchesProperty = matchesProperty;
15884     lodash.memoize = memoize;
15885     lodash.merge = merge;
15886     lodash.mergeWith = mergeWith;
15887     lodash.method = method;
15888     lodash.methodOf = methodOf;
15889     lodash.mixin = mixin;
15890     lodash.negate = negate;
15891     lodash.nthArg = nthArg;
15892     lodash.omit = omit;
15893     lodash.omitBy = omitBy;
15894     lodash.once = once;
15895     lodash.orderBy = orderBy;
15896     lodash.over = over;
15897     lodash.overArgs = overArgs;
15898     lodash.overEvery = overEvery;
15899     lodash.overSome = overSome;
15900     lodash.partial = partial;
15901     lodash.partialRight = partialRight;
15902     lodash.partition = partition;
15903     lodash.pick = pick;
15904     lodash.pickBy = pickBy;
15905     lodash.property = property;
15906     lodash.propertyOf = propertyOf;
15907     lodash.pull = pull;
15908     lodash.pullAll = pullAll;
15909     lodash.pullAllBy = pullAllBy;
15910     lodash.pullAllWith = pullAllWith;
15911     lodash.pullAt = pullAt;
15912     lodash.range = range;
15913     lodash.rangeRight = rangeRight;
15914     lodash.rearg = rearg;
15915     lodash.reject = reject;
15916     lodash.remove = remove;
15917     lodash.rest = rest;
15918     lodash.reverse = reverse;
15919     lodash.sampleSize = sampleSize;
15920     lodash.set = set;
15921     lodash.setWith = setWith;
15922     lodash.shuffle = shuffle;
15923     lodash.slice = slice;
15924     lodash.sortBy = sortBy;
15925     lodash.sortedUniq = sortedUniq;
15926     lodash.sortedUniqBy = sortedUniqBy;
15927     lodash.split = split;
15928     lodash.spread = spread;
15929     lodash.tail = tail;
15930     lodash.take = take;
15931     lodash.takeRight = takeRight;
15932     lodash.takeRightWhile = takeRightWhile;
15933     lodash.takeWhile = takeWhile;
15934     lodash.tap = tap;
15935     lodash.throttle = throttle;
15936     lodash.thru = thru;
15937     lodash.toArray = toArray;
15938     lodash.toPairs = toPairs;
15939     lodash.toPairsIn = toPairsIn;
15940     lodash.toPath = toPath;
15941     lodash.toPlainObject = toPlainObject;
15942     lodash.transform = transform;
15943     lodash.unary = unary;
15944     lodash.union = union;
15945     lodash.unionBy = unionBy;
15946     lodash.unionWith = unionWith;
15947     lodash.uniq = uniq;
15948     lodash.uniqBy = uniqBy;
15949     lodash.uniqWith = uniqWith;
15950     lodash.unset = unset;
15951     lodash.unzip = unzip;
15952     lodash.unzipWith = unzipWith;
15953     lodash.update = update;
15954     lodash.updateWith = updateWith;
15955     lodash.values = values;
15956     lodash.valuesIn = valuesIn;
15957     lodash.without = without;
15958     lodash.words = words;
15959     lodash.wrap = wrap;
15960     lodash.xor = xor;
15961     lodash.xorBy = xorBy;
15962     lodash.xorWith = xorWith;
15963     lodash.zip = zip;
15964     lodash.zipObject = zipObject;
15965     lodash.zipObjectDeep = zipObjectDeep;
15966     lodash.zipWith = zipWith;
15967
15968     // Add aliases.
15969     lodash.entries = toPairs;
15970     lodash.entriesIn = toPairsIn;
15971     lodash.extend = assignIn;
15972     lodash.extendWith = assignInWith;
15973
15974     // Add methods to `lodash.prototype`.
15975     mixin(lodash, lodash);
15976
15977     /*------------------------------------------------------------------------*/
15978
15979     // Add methods that return unwrapped values in chain sequences.
15980     lodash.add = add;
15981     lodash.attempt = attempt;
15982     lodash.camelCase = camelCase;
15983     lodash.capitalize = capitalize;
15984     lodash.ceil = ceil;
15985     lodash.clamp = clamp;
15986     lodash.clone = clone;
15987     lodash.cloneDeep = cloneDeep;
15988     lodash.cloneDeepWith = cloneDeepWith;
15989     lodash.cloneWith = cloneWith;
15990     lodash.deburr = deburr;
15991     lodash.divide = divide;
15992     lodash.endsWith = endsWith;
15993     lodash.eq = eq;
15994     lodash.escape = escape;
15995     lodash.escapeRegExp = escapeRegExp;
15996     lodash.every = every;
15997     lodash.find = find;
15998     lodash.findIndex = findIndex;
15999     lodash.findKey = findKey;
16000     lodash.findLast = findLast;
16001     lodash.findLastIndex = findLastIndex;
16002     lodash.findLastKey = findLastKey;
16003     lodash.floor = floor;
16004     lodash.forEach = forEach;
16005     lodash.forEachRight = forEachRight;
16006     lodash.forIn = forIn;
16007     lodash.forInRight = forInRight;
16008     lodash.forOwn = forOwn;
16009     lodash.forOwnRight = forOwnRight;
16010     lodash.get = get;
16011     lodash.gt = gt;
16012     lodash.gte = gte;
16013     lodash.has = has;
16014     lodash.hasIn = hasIn;
16015     lodash.head = head;
16016     lodash.identity = identity;
16017     lodash.includes = includes;
16018     lodash.indexOf = indexOf;
16019     lodash.inRange = inRange;
16020     lodash.invoke = invoke;
16021     lodash.isArguments = isArguments;
16022     lodash.isArray = isArray;
16023     lodash.isArrayBuffer = isArrayBuffer;
16024     lodash.isArrayLike = isArrayLike;
16025     lodash.isArrayLikeObject = isArrayLikeObject;
16026     lodash.isBoolean = isBoolean;
16027     lodash.isBuffer = isBuffer;
16028     lodash.isDate = isDate;
16029     lodash.isElement = isElement;
16030     lodash.isEmpty = isEmpty;
16031     lodash.isEqual = isEqual;
16032     lodash.isEqualWith = isEqualWith;
16033     lodash.isError = isError;
16034     lodash.isFinite = isFinite;
16035     lodash.isFunction = isFunction;
16036     lodash.isInteger = isInteger;
16037     lodash.isLength = isLength;
16038     lodash.isMap = isMap;
16039     lodash.isMatch = isMatch;
16040     lodash.isMatchWith = isMatchWith;
16041     lodash.isNaN = isNaN;
16042     lodash.isNative = isNative;
16043     lodash.isNil = isNil;
16044     lodash.isNull = isNull;
16045     lodash.isNumber = isNumber;
16046     lodash.isObject = isObject;
16047     lodash.isObjectLike = isObjectLike;
16048     lodash.isPlainObject = isPlainObject;
16049     lodash.isRegExp = isRegExp;
16050     lodash.isSafeInteger = isSafeInteger;
16051     lodash.isSet = isSet;
16052     lodash.isString = isString;
16053     lodash.isSymbol = isSymbol;
16054     lodash.isTypedArray = isTypedArray;
16055     lodash.isUndefined = isUndefined;
16056     lodash.isWeakMap = isWeakMap;
16057     lodash.isWeakSet = isWeakSet;
16058     lodash.join = join;
16059     lodash.kebabCase = kebabCase;
16060     lodash.last = last;
16061     lodash.lastIndexOf = lastIndexOf;
16062     lodash.lowerCase = lowerCase;
16063     lodash.lowerFirst = lowerFirst;
16064     lodash.lt = lt;
16065     lodash.lte = lte;
16066     lodash.max = max;
16067     lodash.maxBy = maxBy;
16068     lodash.mean = mean;
16069     lodash.meanBy = meanBy;
16070     lodash.min = min;
16071     lodash.minBy = minBy;
16072     lodash.stubArray = stubArray;
16073     lodash.stubFalse = stubFalse;
16074     lodash.stubObject = stubObject;
16075     lodash.stubString = stubString;
16076     lodash.stubTrue = stubTrue;
16077     lodash.multiply = multiply;
16078     lodash.nth = nth;
16079     lodash.noConflict = noConflict;
16080     lodash.noop = noop;
16081     lodash.now = now;
16082     lodash.pad = pad;
16083     lodash.padEnd = padEnd;
16084     lodash.padStart = padStart;
16085     lodash.parseInt = parseInt;
16086     lodash.random = random;
16087     lodash.reduce = reduce;
16088     lodash.reduceRight = reduceRight;
16089     lodash.repeat = repeat;
16090     lodash.replace = replace;
16091     lodash.result = result;
16092     lodash.round = round;
16093     lodash.runInContext = runInContext;
16094     lodash.sample = sample;
16095     lodash.size = size;
16096     lodash.snakeCase = snakeCase;
16097     lodash.some = some;
16098     lodash.sortedIndex = sortedIndex;
16099     lodash.sortedIndexBy = sortedIndexBy;
16100     lodash.sortedIndexOf = sortedIndexOf;
16101     lodash.sortedLastIndex = sortedLastIndex;
16102     lodash.sortedLastIndexBy = sortedLastIndexBy;
16103     lodash.sortedLastIndexOf = sortedLastIndexOf;
16104     lodash.startCase = startCase;
16105     lodash.startsWith = startsWith;
16106     lodash.subtract = subtract;
16107     lodash.sum = sum;
16108     lodash.sumBy = sumBy;
16109     lodash.template = template;
16110     lodash.times = times;
16111     lodash.toFinite = toFinite;
16112     lodash.toInteger = toInteger;
16113     lodash.toLength = toLength;
16114     lodash.toLower = toLower;
16115     lodash.toNumber = toNumber;
16116     lodash.toSafeInteger = toSafeInteger;
16117     lodash.toString = toString;
16118     lodash.toUpper = toUpper;
16119     lodash.trim = trim;
16120     lodash.trimEnd = trimEnd;
16121     lodash.trimStart = trimStart;
16122     lodash.truncate = truncate;
16123     lodash.unescape = unescape;
16124     lodash.uniqueId = uniqueId;
16125     lodash.upperCase = upperCase;
16126     lodash.upperFirst = upperFirst;
16127
16128     // Add aliases.
16129     lodash.each = forEach;
16130     lodash.eachRight = forEachRight;
16131     lodash.first = head;
16132
16133     mixin(lodash, (function() {
16134       var source = {};
16135       baseForOwn(lodash, function(func, methodName) {
16136         if (!hasOwnProperty.call(lodash.prototype, methodName)) {
16137           source[methodName] = func;
16138         }
16139       });
16140       return source;
16141     }()), { 'chain': false });
16142
16143     /*------------------------------------------------------------------------*/
16144
16145     /**
16146      * The semantic version number.
16147      *
16148      * @static
16149      * @memberOf _
16150      * @type {string}
16151      */
16152     lodash.VERSION = VERSION;
16153
16154     // Assign default placeholders.
16155     arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
16156       lodash[methodName].placeholder = lodash;
16157     });
16158
16159     // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
16160     arrayEach(['drop', 'take'], function(methodName, index) {
16161       LazyWrapper.prototype[methodName] = function(n) {
16162         var filtered = this.__filtered__;
16163         if (filtered && !index) {
16164           return new LazyWrapper(this);
16165         }
16166         n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
16167
16168         var result = this.clone();
16169         if (filtered) {
16170           result.__takeCount__ = nativeMin(n, result.__takeCount__);
16171         } else {
16172           result.__views__.push({
16173             'size': nativeMin(n, MAX_ARRAY_LENGTH),
16174             'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
16175           });
16176         }
16177         return result;
16178       };
16179
16180       LazyWrapper.prototype[methodName + 'Right'] = function(n) {
16181         return this.reverse()[methodName](n).reverse();
16182       };
16183     });
16184
16185     // Add `LazyWrapper` methods that accept an `iteratee` value.
16186     arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
16187       var type = index + 1,
16188           isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
16189
16190       LazyWrapper.prototype[methodName] = function(iteratee) {
16191         var result = this.clone();
16192         result.__iteratees__.push({
16193           'iteratee': getIteratee(iteratee, 3),
16194           'type': type
16195         });
16196         result.__filtered__ = result.__filtered__ || isFilter;
16197         return result;
16198       };
16199     });
16200
16201     // Add `LazyWrapper` methods for `_.head` and `_.last`.
16202     arrayEach(['head', 'last'], function(methodName, index) {
16203       var takeName = 'take' + (index ? 'Right' : '');
16204
16205       LazyWrapper.prototype[methodName] = function() {
16206         return this[takeName](1).value()[0];
16207       };
16208     });
16209
16210     // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
16211     arrayEach(['initial', 'tail'], function(methodName, index) {
16212       var dropName = 'drop' + (index ? '' : 'Right');
16213
16214       LazyWrapper.prototype[methodName] = function() {
16215         return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
16216       };
16217     });
16218
16219     LazyWrapper.prototype.compact = function() {
16220       return this.filter(identity);
16221     };
16222
16223     LazyWrapper.prototype.find = function(predicate) {
16224       return this.filter(predicate).head();
16225     };
16226
16227     LazyWrapper.prototype.findLast = function(predicate) {
16228       return this.reverse().find(predicate);
16229     };
16230
16231     LazyWrapper.prototype.invokeMap = rest(function(path, args) {
16232       if (typeof path == 'function') {
16233         return new LazyWrapper(this);
16234       }
16235       return this.map(function(value) {
16236         return baseInvoke(value, path, args);
16237       });
16238     });
16239
16240     LazyWrapper.prototype.reject = function(predicate) {
16241       predicate = getIteratee(predicate, 3);
16242       return this.filter(function(value) {
16243         return !predicate(value);
16244       });
16245     };
16246
16247     LazyWrapper.prototype.slice = function(start, end) {
16248       start = toInteger(start);
16249
16250       var result = this;
16251       if (result.__filtered__ && (start > 0 || end < 0)) {
16252         return new LazyWrapper(result);
16253       }
16254       if (start < 0) {
16255         result = result.takeRight(-start);
16256       } else if (start) {
16257         result = result.drop(start);
16258       }
16259       if (end !== undefined) {
16260         end = toInteger(end);
16261         result = end < 0 ? result.dropRight(-end) : result.take(end - start);
16262       }
16263       return result;
16264     };
16265
16266     LazyWrapper.prototype.takeRightWhile = function(predicate) {
16267       return this.reverse().takeWhile(predicate).reverse();
16268     };
16269
16270     LazyWrapper.prototype.toArray = function() {
16271       return this.take(MAX_ARRAY_LENGTH);
16272     };
16273
16274     // Add `LazyWrapper` methods to `lodash.prototype`.
16275     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
16276       var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
16277           isTaker = /^(?:head|last)$/.test(methodName),
16278           lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
16279           retUnwrapped = isTaker || /^find/.test(methodName);
16280
16281       if (!lodashFunc) {
16282         return;
16283       }
16284       lodash.prototype[methodName] = function() {
16285         var value = this.__wrapped__,
16286             args = isTaker ? [1] : arguments,
16287             isLazy = value instanceof LazyWrapper,
16288             iteratee = args[0],
16289             useLazy = isLazy || isArray(value);
16290
16291         var interceptor = function(value) {
16292           var result = lodashFunc.apply(lodash, arrayPush([value], args));
16293           return (isTaker && chainAll) ? result[0] : result;
16294         };
16295
16296         if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
16297           // Avoid lazy use if the iteratee has a "length" value other than `1`.
16298           isLazy = useLazy = false;
16299         }
16300         var chainAll = this.__chain__,
16301             isHybrid = !!this.__actions__.length,
16302             isUnwrapped = retUnwrapped && !chainAll,
16303             onlyLazy = isLazy && !isHybrid;
16304
16305         if (!retUnwrapped && useLazy) {
16306           value = onlyLazy ? value : new LazyWrapper(this);
16307           var result = func.apply(value, args);
16308           result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
16309           return new LodashWrapper(result, chainAll);
16310         }
16311         if (isUnwrapped && onlyLazy) {
16312           return func.apply(this, args);
16313         }
16314         result = this.thru(interceptor);
16315         return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
16316       };
16317     });
16318
16319     // Add `Array` methods to `lodash.prototype`.
16320     arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
16321       var func = arrayProto[methodName],
16322           chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
16323           retUnwrapped = /^(?:pop|shift)$/.test(methodName);
16324
16325       lodash.prototype[methodName] = function() {
16326         var args = arguments;
16327         if (retUnwrapped && !this.__chain__) {
16328           var value = this.value();
16329           return func.apply(isArray(value) ? value : [], args);
16330         }
16331         return this[chainName](function(value) {
16332           return func.apply(isArray(value) ? value : [], args);
16333         });
16334       };
16335     });
16336
16337     // Map minified method names to their real names.
16338     baseForOwn(LazyWrapper.prototype, function(func, methodName) {
16339       var lodashFunc = lodash[methodName];
16340       if (lodashFunc) {
16341         var key = (lodashFunc.name + ''),
16342             names = realNames[key] || (realNames[key] = []);
16343
16344         names.push({ 'name': methodName, 'func': lodashFunc });
16345       }
16346     });
16347
16348     realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{
16349       'name': 'wrapper',
16350       'func': undefined
16351     }];
16352
16353     // Add methods to `LazyWrapper`.
16354     LazyWrapper.prototype.clone = lazyClone;
16355     LazyWrapper.prototype.reverse = lazyReverse;
16356     LazyWrapper.prototype.value = lazyValue;
16357
16358     // Add chain sequence methods to the `lodash` wrapper.
16359     lodash.prototype.at = wrapperAt;
16360     lodash.prototype.chain = wrapperChain;
16361     lodash.prototype.commit = wrapperCommit;
16362     lodash.prototype.next = wrapperNext;
16363     lodash.prototype.plant = wrapperPlant;
16364     lodash.prototype.reverse = wrapperReverse;
16365     lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
16366
16367     if (iteratorSymbol) {
16368       lodash.prototype[iteratorSymbol] = wrapperToIterator;
16369     }
16370     return lodash;
16371   }
16372
16373   /*--------------------------------------------------------------------------*/
16374
16375   // Export lodash.
16376   var _ = runInContext();
16377
16378   // Expose Lodash on the free variable `window` or `self` when available so it's
16379   // globally accessible, even when bundled with Browserify, Webpack, etc. This
16380   // also prevents errors in cases where Lodash is loaded by a script tag in the
16381   // presence of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch
16382   // for more details. Use `_.noConflict` to remove Lodash from the global object.
16383   (freeSelf || {})._ = _;
16384
16385   // Some AMD build optimizers like r.js check for condition patterns like the following:
16386   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
16387     // Define as an anonymous module so, through path mapping, it can be
16388     // referenced as the "underscore" module.
16389     define(function() {
16390       return _;
16391     });
16392   }
16393   // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
16394   else if (freeModule) {
16395     // Export for Node.js.
16396     (freeModule.exports = _)._ = _;
16397     // Export for CommonJS support.
16398     freeExports._ = _;
16399   }
16400   else {
16401     // Export to the global object.
16402     root._ = _;
16403   }
16404 }.call(this));