(window["webpackjsonp"] = window["webpackjsonp"] || []).push([[66],{
/***/ 406:
/***/ (function(module, exports, __webpack_require__) {
/* webpack var injection */(function(global, module) {var __webpack_amd_define_result__;/**
* @license
* lodash
* copyright openjs foundation and other contributors
* released under mit license
* based on underscore.js 1.8.3
* copyright jeremy ashkenas, documentcloud and investigative reporters & editors
*/
;(function() {
/** used as a safe reference for `undefined` in pre-es5 environments. */
var undefined;
/** used as the semantic version number. */
var version = '4.17.21';
/** used as the size to enable large array optimizations. */
var large_array_size = 200;
/** error message constants. */
var core_error_text = 'unsupported core-js use. try https://npms.io/search?q=ponyfill.',
func_error_text = 'expected a function',
invalid_templ_var_error_text = 'invalid `variable` option passed into `_.template`';
/** used to stand-in for `undefined` hash values. */
var hash_undefined = '__lodash_hash_undefined__';
/** used as the maximum memoize cache size. */
var max_memoize_size = 500;
/** used as the internal argument placeholder. */
var placeholder = '__lodash_placeholder__';
/** used to compose bitmasks for cloning. */
var clone_deep_flag = 1,
clone_flat_flag = 2,
clone_symbols_flag = 4;
/** used to compose bitmasks for value comparisons. */
var compare_partial_flag = 1,
compare_unordered_flag = 2;
/** used to compose bitmasks for function metadata. */
var wrap_bind_flag = 1,
wrap_bind_key_flag = 2,
wrap_curry_bound_flag = 4,
wrap_curry_flag = 8,
wrap_curry_right_flag = 16,
wrap_partial_flag = 32,
wrap_partial_right_flag = 64,
wrap_ary_flag = 128,
wrap_rearg_flag = 256,
wrap_flip_flag = 512;
/** used as default options for `_.truncate`. */
var default_trunc_length = 30,
default_trunc_omission = '...';
/** used to detect hot functions by number of calls within a span of milliseconds. */
var hot_count = 800,
hot_span = 16;
/** used to indicate the type of lazy iteratees. */
var lazy_filter_flag = 1,
lazy_map_flag = 2,
lazy_while_flag = 3;
/** used as references for various `number` constants. */
var infinity = 1 / 0,
max_safe_integer = 9007199254740991,
max_integer = 1.7976931348623157e+308,
nan = 0 / 0;
/** used as references for the maximum length and index of an array. */
var max_array_length = 4294967295,
max_array_index = max_array_length - 1,
half_max_array_length = max_array_length >>> 1;
/** used to associate wrap methods with their bit flags. */
var wrapflags = [
['ary', wrap_ary_flag],
['bind', wrap_bind_flag],
['bindkey', wrap_bind_key_flag],
['curry', wrap_curry_flag],
['curryright', wrap_curry_right_flag],
['flip', wrap_flip_flag],
['partial', wrap_partial_flag],
['partialright', wrap_partial_right_flag],
['rearg', wrap_rearg_flag]
];
/** `object#tostring` result references. */
var argstag = '[object arguments]',
arraytag = '[object array]',
asynctag = '[object asyncfunction]',
booltag = '[object boolean]',
datetag = '[object date]',
domexctag = '[object domexception]',
errortag = '[object error]',
functag = '[object function]',
gentag = '[object generatorfunction]',
maptag = '[object map]',
numbertag = '[object number]',
nulltag = '[object null]',
objecttag = '[object object]',
promisetag = '[object promise]',
proxytag = '[object proxy]',
regexptag = '[object regexp]',
settag = '[object set]',
stringtag = '[object string]',
symboltag = '[object symbol]',
undefinedtag = '[object undefined]',
weakmaptag = '[object weakmap]',
weaksettag = '[object weakset]';
var arraybuffertag = '[object arraybuffer]',
dataviewtag = '[object dataview]',
float32tag = '[object float32array]',
float64tag = '[object float64array]',
int8tag = '[object int8array]',
int16tag = '[object int16array]',
int32tag = '[object int32array]',
uint8tag = '[object uint8array]',
uint8clampedtag = '[object uint8clampedarray]',
uint16tag = '[object uint16array]',
uint32tag = '[object uint32array]';
/** used to match empty string literals in compiled template source. */
var reemptystringleading = /\b__p \+= '';/g,
reemptystringmiddle = /\b(__p \+=) '' \+/g,
reemptystringtrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
/** used to match html entities and html characters. */
var reescapedhtml = /&(?:amp|lt|gt|quot|#39);/g,
reunescapedhtml = /[&<>"']/g,
rehasescapedhtml = regexp(reescapedhtml.source),
rehasunescapedhtml = regexp(reunescapedhtml.source);
/** used to match template delimiters. */
var reescape = /<%-([\s\s]+?)%>/g,
reevaluate = /<%([\s\s]+?)%>/g,
reinterpolate = /<%=([\s\s]+?)%>/g;
/** used to match property names within property paths. */
var reisdeepprop = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
reisplainprop = /^\w*$/,
repropname = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
/**
* used to match `regexp`
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
*/
var reregexpchar = /[\\^$.*+?()[\]{}|]/g,
rehasregexpchar = regexp(reregexpchar.source);
/** used to match leading whitespace. */
var retrimstart = /^\s+/;
/** used to match a single whitespace character. */
var rewhitespace = /\s/;
/** used to match wrap detail comments. */
var rewrapcomment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
rewrapdetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
resplitdetails = /,? & /;
/** used to match words composed of alphanumeric characters. */
var reasciiword = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
/**
* used to validate the `validate` option in `_.template` variable.
*
* forbids characters which could potentially change the meaning of the function argument definition:
* - "()," (modification of function parameters)
* - "=" (default value)
* - "[]{}" (destructuring of function parameters)
* - "/" (beginning of a comment)
* - whitespace
*/
var reforbiddenidentifierchars = /[()=,{}\[\]\/\s]/;
/** used to match backslashes in property paths. */
var reescapechar = /\\(\\)?/g;
/**
* used to match
* [es template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
*/
var reestemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
/** used to match `regexp` flags from their coerced string values. */
var reflags = /\w*$/;
/** used to detect bad signed hexadecimal string values. */
var reisbadhex = /^[-+]0x[0-9a-f]+$/i;
/** used to detect binary string values. */
var reisbinary = /^0b[01]+$/i;
/** used to detect host constructors (safari). */
var reishostctor = /^\[object .+?constructor\]$/;
/** used to detect octal string values. */
var reisoctal = /^0o[0-7]+$/i;
/** used to detect unsigned integer values. */
var reisuint = /^(?:0|[1-9]\d*)$/;
/** used to match latin unicode letters (excluding mathematical operators). */
var relatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
/** used to ensure capturing order of template delimiters. */
var renomatch = /($^)/;
/** used to match unescaped characters in compiled string literals. */
var reunescapedstring = /['\n\r\u2028\u2029\\]/g;
/** used to compose unicode character classes. */
var rsastralrange = '\\ud800-\\udfff',
rscombomarksrange = '\\u0300-\\u036f',
recombohalfmarksrange = '\\ufe20-\\ufe2f',
rscombosymbolsrange = '\\u20d0-\\u20ff',
rscomborange = rscombomarksrange + recombohalfmarksrange + rscombosymbolsrange,
rsdingbatrange = '\\u2700-\\u27bf',
rslowerrange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
rsmathoprange = '\\xac\\xb1\\xd7\\xf7',
rsnoncharrange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
rspunctuationrange = '\\u2000-\\u206f',
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',
rsupperrange = 'a-z\\xc0-\\xd6\\xd8-\\xde',
rsvarrange = '\\ufe0e\\ufe0f',
rsbreakrange = rsmathoprange + rsnoncharrange + rspunctuationrange + rsspacerange;
/** used to compose unicode capture groups. */
var rsapos = "['\u2019]",
rsastral = '[' + rsastralrange + ']',
rsbreak = '[' + rsbreakrange + ']',
rscombo = '[' + rscomborange + ']',
rsdigits = '\\d+',
rsdingbat = '[' + rsdingbatrange + ']',
rslower = '[' + rslowerrange + ']',
rsmisc = '[^' + rsastralrange + rsbreakrange + rsdigits + rsdingbatrange + rslowerrange + rsupperrange + ']',
rsfitz = '\\ud83c[\\udffb-\\udfff]',
rsmodifier = '(?:' + rscombo + '|' + rsfitz + ')',
rsnonastral = '[^' + rsastralrange + ']',
rsregional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
rssurrpair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
rsupper = '[' + rsupperrange + ']',
rszwj = '\\u200d';
/** used to compose unicode regexes. */
var rsmisclower = '(?:' + rslower + '|' + rsmisc + ')',
rsmiscupper = '(?:' + rsupper + '|' + rsmisc + ')',
rsoptcontrlower = '(?:' + rsapos + '(?:d|ll|m|re|s|t|ve))?',
rsoptcontrupper = '(?:' + rsapos + '(?:d|ll|m|re|s|t|ve))?',
reoptmod = rsmodifier + '?',
rsoptvar = '[' + rsvarrange + ']?',
rsoptjoin = '(?:' + rszwj + '(?:' + [rsnonastral, rsregional, rssurrpair].join('|') + ')' + rsoptvar + reoptmod + ')*',
rsordlower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[a-z_])',
rsordupper = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[a-z_])',
rsseq = rsoptvar + reoptmod + rsoptjoin,
rsemoji = '(?:' + [rsdingbat, rsregional, rssurrpair].join('|') + ')' + rsseq,
rssymbol = '(?:' + [rsnonastral + rscombo + '?', rscombo, rsregional, rssurrpair, rsastral].join('|') + ')';
/** used to match apostrophes. */
var reapos = regexp(rsapos, 'g');
/**
* used to match [combining diacritical marks](https://en.wikipedia.org/wiki/combining_diacritical_marks) and
* [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/combining_diacritical_marks_for_symbols).
*/
var recombomark = regexp(rscombo, 'g');
/** used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
var reunicode = regexp(rsfitz + '(?=' + rsfitz + ')|' + rssymbol + rsseq, 'g');
/** used to match complex or compound words. */
var reunicodeword = regexp([
rsupper + '?' + rslower + '+' + rsoptcontrlower + '(?=' + [rsbreak, rsupper, '$'].join('|') + ')',
rsmiscupper + '+' + rsoptcontrupper + '(?=' + [rsbreak, rsupper + rsmisclower, '$'].join('|') + ')',
rsupper + '?' + rsmisclower + '+' + rsoptcontrlower,
rsupper + '+' + rsoptcontrupper,
rsordupper,
rsordlower,
rsdigits,
rsemoji
].join('|'), 'g');
/** 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/). */
var rehasunicode = regexp('[' + rszwj + rsastralrange + rscomborange + rsvarrange + ']');
/** used to detect strings that need a more robust regexp to match words. */
var rehasunicodeword = /[a-z][a-z]|[a-z]{2}[a-z]|[0-9][a-za-z]|[a-za-z][0-9]|[^a-za-z0-9 ]/;
/** used to assign default `context` object properties. */
var contextprops = [
'array', 'buffer', 'dataview', 'date', 'error', 'float32array', 'float64array',
'function', 'int8array', 'int16array', 'int32array', 'map', 'math', 'object',
'promise', 'regexp', 'set', 'string', 'symbol', 'typeerror', 'uint8array',
'uint8clampedarray', 'uint16array', 'uint32array', 'weakmap',
'_', 'cleartimeout', 'isfinite', 'parseint', 'settimeout'
];
/** used to make template sourceurls easier to identify. */
var templatecounter = -1;
/** used to identify `tostringtag` values of typed arrays. */
var typedarraytags = {};
typedarraytags[float32tag] = typedarraytags[float64tag] =
typedarraytags[int8tag] = typedarraytags[int16tag] =
typedarraytags[int32tag] = typedarraytags[uint8tag] =
typedarraytags[uint8clampedtag] = typedarraytags[uint16tag] =
typedarraytags[uint32tag] = true;
typedarraytags[argstag] = typedarraytags[arraytag] =
typedarraytags[arraybuffertag] = typedarraytags[booltag] =
typedarraytags[dataviewtag] = typedarraytags[datetag] =
typedarraytags[errortag] = typedarraytags[functag] =
typedarraytags[maptag] = typedarraytags[numbertag] =
typedarraytags[objecttag] = typedarraytags[regexptag] =
typedarraytags[settag] = typedarraytags[stringtag] =
typedarraytags[weakmaptag] = false;
/** used to identify `tostringtag` values supported by `_.clone`. */
var cloneabletags = {};
cloneabletags[argstag] = cloneabletags[arraytag] =
cloneabletags[arraybuffertag] = cloneabletags[dataviewtag] =
cloneabletags[booltag] = cloneabletags[datetag] =
cloneabletags[float32tag] = cloneabletags[float64tag] =
cloneabletags[int8tag] = cloneabletags[int16tag] =
cloneabletags[int32tag] = cloneabletags[maptag] =
cloneabletags[numbertag] = cloneabletags[objecttag] =
cloneabletags[regexptag] = cloneabletags[settag] =
cloneabletags[stringtag] = cloneabletags[symboltag] =
cloneabletags[uint8tag] = cloneabletags[uint8clampedtag] =
cloneabletags[uint16tag] = cloneabletags[uint32tag] = true;
cloneabletags[errortag] = cloneabletags[functag] =
cloneabletags[weakmaptag] = false;
/** used to map latin unicode letters to basic latin letters. */
var deburredletters = {
// latin-1 supplement block.
'\xc0': 'a', '\xc1': 'a', '\xc2': 'a', '\xc3': 'a', '\xc4': 'a', '\xc5': 'a',
'\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
'\xc7': 'c', '\xe7': 'c',
'\xd0': 'd', '\xf0': 'd',
'\xc8': 'e', '\xc9': 'e', '\xca': 'e', '\xcb': 'e',
'\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
'\xcc': 'i', '\xcd': 'i', '\xce': 'i', '\xcf': 'i',
'\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
'\xd1': 'n', '\xf1': 'n',
'\xd2': 'o', '\xd3': 'o', '\xd4': 'o', '\xd5': 'o', '\xd6': 'o', '\xd8': 'o',
'\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
'\xd9': 'u', '\xda': 'u', '\xdb': 'u', '\xdc': 'u',
'\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
'\xdd': 'y', '\xfd': 'y', '\xff': 'y',
'\xc6': 'ae', '\xe6': 'ae',
'\xde': 'th', '\xfe': 'th',
'\xdf': 'ss',
// latin extended-a block.
'\u0100': 'a', '\u0102': 'a', '\u0104': 'a',
'\u0101': 'a', '\u0103': 'a', '\u0105': 'a',
'\u0106': 'c', '\u0108': 'c', '\u010a': 'c', '\u010c': 'c',
'\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
'\u010e': 'd', '\u0110': 'd', '\u010f': 'd', '\u0111': 'd',
'\u0112': 'e', '\u0114': 'e', '\u0116': 'e', '\u0118': 'e', '\u011a': 'e',
'\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
'\u011c': 'g', '\u011e': 'g', '\u0120': 'g', '\u0122': 'g',
'\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
'\u0124': 'h', '\u0126': 'h', '\u0125': 'h', '\u0127': 'h',
'\u0128': 'i', '\u012a': 'i', '\u012c': 'i', '\u012e': 'i', '\u0130': 'i',
'\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
'\u0134': 'j', '\u0135': 'j',
'\u0136': 'k', '\u0137': 'k', '\u0138': 'k',
'\u0139': 'l', '\u013b': 'l', '\u013d': 'l', '\u013f': 'l', '\u0141': 'l',
'\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
'\u0143': 'n', '\u0145': 'n', '\u0147': 'n', '\u014a': 'n',
'\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
'\u014c': 'o', '\u014e': 'o', '\u0150': 'o',
'\u014d': 'o', '\u014f': 'o', '\u0151': 'o',
'\u0154': 'r', '\u0156': 'r', '\u0158': 'r',
'\u0155': 'r', '\u0157': 'r', '\u0159': 'r',
'\u015a': 's', '\u015c': 's', '\u015e': 's', '\u0160': 's',
'\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's',
'\u0162': 't', '\u0164': 't', '\u0166': 't',
'\u0163': 't', '\u0165': 't', '\u0167': 't',
'\u0168': 'u', '\u016a': 'u', '\u016c': 'u', '\u016e': 'u', '\u0170': 'u', '\u0172': 'u',
'\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
'\u0174': 'w', '\u0175': 'w',
'\u0176': 'y', '\u0177': 'y', '\u0178': 'y',
'\u0179': 'z', '\u017b': 'z', '\u017d': 'z',
'\u017a': 'z', '\u017c': 'z', '\u017e': 'z',
'\u0132': 'ij', '\u0133': 'ij',
'\u0152': 'oe', '\u0153': 'oe',
'\u0149': "'n", '\u017f': 's'
};
/** used to map characters to html entities. */
var htmlescapes = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
/** used to map html entities to characters. */
var htmlunescapes = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
''': "'"
};
/** used to escape characters for inclusion in compiled string literals. */
var stringescapes = {
'\\': '\\',
"'": "'",
'\n': 'n',
'\r': 'r',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
/** built-in method references without a dependency on `root`. */
var freeparsefloat = parsefloat,
freeparseint = parseint;
/** detect free variable `global` from node.js. */
var freeglobal = typeof global == 'object' && global && global.object === object && global;
/** detect free variable `self`. */
var freeself = typeof self == 'object' && self && self.object === object && self;
/** used as a reference to the global object. */
var root = freeglobal || freeself || function('return this')();
/** detect free variable `exports`. */
var freeexports = true && exports && !exports.nodetype && exports;
/** detect free variable `module`. */
var freemodule = freeexports && typeof module == 'object' && module && !module.nodetype && module;
/** detect the popular commonjs extension `module.exports`. */
var moduleexports = freemodule && freemodule.exports === freeexports;
/** detect free variable `process` from node.js. */
var freeprocess = moduleexports && freeglobal.process;
/** used to access faster node.js helpers. */
var nodeutil = (function() {
try {
// use `util.types` for node.js 10+.
var types = freemodule && freemodule.require && freemodule.require('util').types;
if (types) {
return types;
}
// legacy `process.binding('util')` for node.js < 10.
return freeprocess && freeprocess.binding && freeprocess.binding('util');
} catch (e) {}
}());
/* node.js helper references. */
var nodeisarraybuffer = nodeutil && nodeutil.isarraybuffer,
nodeisdate = nodeutil && nodeutil.isdate,
nodeismap = nodeutil && nodeutil.ismap,
nodeisregexp = nodeutil && nodeutil.isregexp,
nodeisset = nodeutil && nodeutil.isset,
nodeistypedarray = nodeutil && nodeutil.istypedarray;
/*--------------------------------------------------------------------------*/
/**
* a faster alternative to `function#apply`, this function invokes `func`
* with the `this` binding of `thisarg` and the arguments of `args`.
*
* @private
* @param {function} func the function to invoke.
* @param {*} thisarg the `this` binding of `func`.
* @param {array} args the arguments to invoke `func` with.
* @returns {*} returns the result of `func`.
*/
function apply(func, thisarg, args) {
switch (args.length) {
case 0: return func.call(thisarg);
case 1: return func.call(thisarg, args[0]);
case 2: return func.call(thisarg, args[0], args[1]);
case 3: return func.call(thisarg, args[0], args[1], args[2]);
}
return func.apply(thisarg, args);
}
/**
* a specialized version of `baseaggregator` for arrays.
*
* @private
* @param {array} [array] the array to iterate over.
* @param {function} setter the function to set `accumulator` values.
* @param {function} iteratee the iteratee to transform keys.
* @param {object} accumulator the initial aggregated object.
* @returns {function} returns `accumulator`.
*/
function arrayaggregator(array, setter, iteratee, accumulator) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
var value = array[index];
setter(accumulator, value, iteratee(value), array);
}
return accumulator;
}
/**
* a specialized version of `_.foreach` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {array} [array] the array to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @returns {array} returns `array`.
*/
function arrayeach(array, iteratee) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
if (iteratee(array[index], index, array) === false) {
break;
}
}
return array;
}
/**
* a specialized version of `_.foreachright` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {array} [array] the array to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @returns {array} returns `array`.
*/
function arrayeachright(array, iteratee) {
var length = array == null ? 0 : array.length;
while (length--) {
if (iteratee(array[length], length, array) === false) {
break;
}
}
return array;
}
/**
* a specialized version of `_.every` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {array} [array] the array to iterate over.
* @param {function} predicate the function invoked per iteration.
* @returns {boolean} returns `true` if all elements pass the predicate check,
* else `false`.
*/
function arrayevery(array, predicate) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
if (!predicate(array[index], index, array)) {
return false;
}
}
return true;
}
/**
* a specialized version of `_.filter` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {array} [array] the array to iterate over.
* @param {function} predicate the function invoked per iteration.
* @returns {array} returns the new filtered array.
*/
function arrayfilter(array, predicate) {
var index = -1,
length = array == null ? 0 : array.length,
resindex = 0,
result = [];
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
result[resindex++] = value;
}
}
return result;
}
/**
* a specialized version of `_.includes` for arrays without support for
* specifying an index to search from.
*
* @private
* @param {array} [array] the array to inspect.
* @param {*} target the value to search for.
* @returns {boolean} returns `true` if `target` is found, else `false`.
*/
function arrayincludes(array, value) {
var length = array == null ? 0 : array.length;
return !!length && baseindexof(array, value, 0) > -1;
}
/**
* this function is like `arrayincludes` except that it accepts a comparator.
*
* @private
* @param {array} [array] the array to inspect.
* @param {*} target the value to search for.
* @param {function} comparator the comparator invoked per element.
* @returns {boolean} returns `true` if `target` is found, else `false`.
*/
function arrayincludeswith(array, value, comparator) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
if (comparator(value, array[index])) {
return true;
}
}
return false;
}
/**
* a specialized version of `_.map` for arrays without support for iteratee
* shorthands.
*
* @private
* @param {array} [array] the array to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @returns {array} returns the new mapped array.
*/
function arraymap(array, iteratee) {
var index = -1,
length = array == null ? 0 : array.length,
result = array(length);
while (++index < length) {
result[index] = iteratee(array[index], index, array);
}
return result;
}
/**
* appends the elements of `values` to `array`.
*
* @private
* @param {array} array the array to modify.
* @param {array} values the values to append.
* @returns {array} returns `array`.
*/
function arraypush(array, values) {
var index = -1,
length = values.length,
offset = array.length;
while (++index < length) {
array[offset + index] = values[index];
}
return array;
}
/**
* a specialized version of `_.reduce` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {array} [array] the array to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @param {*} [accumulator] the initial value.
* @param {boolean} [initaccum] specify using the first element of `array` as
* the initial value.
* @returns {*} returns the accumulated value.
*/
function arrayreduce(array, iteratee, accumulator, initaccum) {
var index = -1,
length = array == null ? 0 : array.length;
if (initaccum && length) {
accumulator = array[++index];
}
while (++index < length) {
accumulator = iteratee(accumulator, array[index], index, array);
}
return accumulator;
}
/**
* a specialized version of `_.reduceright` for arrays without support for
* iteratee shorthands.
*
* @private
* @param {array} [array] the array to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @param {*} [accumulator] the initial value.
* @param {boolean} [initaccum] specify using the last element of `array` as
* the initial value.
* @returns {*} returns the accumulated value.
*/
function arrayreduceright(array, iteratee, accumulator, initaccum) {
var length = array == null ? 0 : array.length;
if (initaccum && length) {
accumulator = array[--length];
}
while (length--) {
accumulator = iteratee(accumulator, array[length], length, array);
}
return accumulator;
}
/**
* a specialized version of `_.some` for arrays without support for iteratee
* shorthands.
*
* @private
* @param {array} [array] the array to iterate over.
* @param {function} predicate the function invoked per iteration.
* @returns {boolean} returns `true` if any element passes the predicate check,
* else `false`.
*/
function arraysome(array, predicate) {
var index = -1,
length = array == null ? 0 : array.length;
while (++index < length) {
if (predicate(array[index], index, array)) {
return true;
}
}
return false;
}
/**
* gets the size of an ascii `string`.
*
* @private
* @param {string} string the string inspect.
* @returns {number} returns the string size.
*/
var asciisize = baseproperty('length');
/**
* converts an ascii `string` to an array.
*
* @private
* @param {string} string the string to convert.
* @returns {array} returns the converted array.
*/
function asciitoarray(string) {
return string.split('');
}
/**
* splits an ascii `string` into an array of its words.
*
* @private
* @param {string} the string to inspect.
* @returns {array} returns the words of `string`.
*/
function asciiwords(string) {
return string.match(reasciiword) || [];
}
/**
* the base implementation of methods like `_.findkey` and `_.findlastkey`,
* without support for iteratee shorthands, which iterates over `collection`
* using `eachfunc`.
*
* @private
* @param {array|object} collection the collection to inspect.
* @param {function} predicate the function invoked per iteration.
* @param {function} eachfunc the function to iterate over `collection`.
* @returns {*} returns the found element or its key, else `undefined`.
*/
function basefindkey(collection, predicate, eachfunc) {
var result;
eachfunc(collection, function(value, key, collection) {
if (predicate(value, key, collection)) {
result = key;
return false;
}
});
return result;
}
/**
* the base implementation of `_.findindex` and `_.findlastindex` without
* support for iteratee shorthands.
*
* @private
* @param {array} array the array to inspect.
* @param {function} predicate the function invoked per iteration.
* @param {number} fromindex the index to search from.
* @param {boolean} [fromright] specify iterating from right to left.
* @returns {number} returns the index of the matched value, else `-1`.
*/
function basefindindex(array, predicate, fromindex, fromright) {
var length = array.length,
index = fromindex + (fromright ? 1 : -1);
while ((fromright ? index-- : ++index < length)) {
if (predicate(array[index], index, array)) {
return index;
}
}
return -1;
}
/**
* the base implementation of `_.indexof` without `fromindex` bounds checks.
*
* @private
* @param {array} array the array to inspect.
* @param {*} value the value to search for.
* @param {number} fromindex the index to search from.
* @returns {number} returns the index of the matched value, else `-1`.
*/
function baseindexof(array, value, fromindex) {
return value === value
? strictindexof(array, value, fromindex)
: basefindindex(array, baseisnan, fromindex);
}
/**
* this function is like `baseindexof` except that it accepts a comparator.
*
* @private
* @param {array} array the array to inspect.
* @param {*} value the value to search for.
* @param {number} fromindex the index to search from.
* @param {function} comparator the comparator invoked per element.
* @returns {number} returns the index of the matched value, else `-1`.
*/
function baseindexofwith(array, value, fromindex, comparator) {
var index = fromindex - 1,
length = array.length;
while (++index < length) {
if (comparator(array[index], value)) {
return index;
}
}
return -1;
}
/**
* the base implementation of `_.isnan` without support for number objects.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is `nan`, else `false`.
*/
function baseisnan(value) {
return value !== value;
}
/**
* the base implementation of `_.mean` and `_.meanby` without support for
* iteratee shorthands.
*
* @private
* @param {array} array the array to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @returns {number} returns the mean.
*/
function basemean(array, iteratee) {
var length = array == null ? 0 : array.length;
return length ? (basesum(array, iteratee) / length) : nan;
}
/**
* the base implementation of `_.property` without support for deep paths.
*
* @private
* @param {string} key the key of the property to get.
* @returns {function} returns the new accessor function.
*/
function baseproperty(key) {
return function(object) {
return object == null ? undefined : object[key];
};
}
/**
* the base implementation of `_.propertyof` without support for deep paths.
*
* @private
* @param {object} object the object to query.
* @returns {function} returns the new accessor function.
*/
function basepropertyof(object) {
return function(key) {
return object == null ? undefined : object[key];
};
}
/**
* the base implementation of `_.reduce` and `_.reduceright`, without support
* for iteratee shorthands, which iterates over `collection` using `eachfunc`.
*
* @private
* @param {array|object} collection the collection to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @param {*} accumulator the initial value.
* @param {boolean} initaccum specify using the first or last element of
* `collection` as the initial value.
* @param {function} eachfunc the function to iterate over `collection`.
* @returns {*} returns the accumulated value.
*/
function basereduce(collection, iteratee, accumulator, initaccum, eachfunc) {
eachfunc(collection, function(value, index, collection) {
accumulator = initaccum
? (initaccum = false, value)
: iteratee(accumulator, value, index, collection);
});
return accumulator;
}
/**
* the base implementation of `_.sortby` which uses `comparer` to define the
* sort order of `array` and replaces criteria objects with their corresponding
* values.
*
* @private
* @param {array} array the array to sort.
* @param {function} comparer the function to define sort order.
* @returns {array} returns `array`.
*/
function basesortby(array, comparer) {
var length = array.length;
array.sort(comparer);
while (length--) {
array[length] = array[length].value;
}
return array;
}
/**
* the base implementation of `_.sum` and `_.sumby` without support for
* iteratee shorthands.
*
* @private
* @param {array} array the array to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @returns {number} returns the sum.
*/
function basesum(array, iteratee) {
var result,
index = -1,
length = array.length;
while (++index < length) {
var current = iteratee(array[index]);
if (current !== undefined) {
result = result === undefined ? current : (result + current);
}
}
return result;
}
/**
* the base implementation of `_.times` without support for iteratee shorthands
* or max array length checks.
*
* @private
* @param {number} n the number of times to invoke `iteratee`.
* @param {function} iteratee the function invoked per iteration.
* @returns {array} returns the array of results.
*/
function basetimes(n, iteratee) {
var index = -1,
result = array(n);
while (++index < n) {
result[index] = iteratee(index);
}
return result;
}
/**
* the base implementation of `_.topairs` and `_.topairsin` which creates an array
* of key-value pairs for `object` corresponding to the property names of `props`.
*
* @private
* @param {object} object the object to query.
* @param {array} props the property names to get values for.
* @returns {object} returns the key-value pairs.
*/
function basetopairs(object, props) {
return arraymap(props, function(key) {
return [key, object[key]];
});
}
/**
* the base implementation of `_.trim`.
*
* @private
* @param {string} string the string to trim.
* @returns {string} returns the trimmed string.
*/
function basetrim(string) {
return string
? string.slice(0, trimmedendindex(string) + 1).replace(retrimstart, '')
: string;
}
/**
* the base implementation of `_.unary` without support for storing metadata.
*
* @private
* @param {function} func the function to cap arguments for.
* @returns {function} returns the new capped function.
*/
function baseunary(func) {
return function(value) {
return func(value);
};
}
/**
* the base implementation of `_.values` and `_.valuesin` which creates an
* array of `object` property values corresponding to the property names
* of `props`.
*
* @private
* @param {object} object the object to query.
* @param {array} props the property names to get values for.
* @returns {object} returns the array of property values.
*/
function basevalues(object, props) {
return arraymap(props, function(key) {
return object[key];
});
}
/**
* checks if a `cache` value for `key` exists.
*
* @private
* @param {object} cache the cache to query.
* @param {string} key the key of the entry to check.
* @returns {boolean} returns `true` if an entry for `key` exists, else `false`.
*/
function cachehas(cache, key) {
return cache.has(key);
}
/**
* used by `_.trim` and `_.trimstart` to get the index of the first string symbol
* that is not found in the character symbols.
*
* @private
* @param {array} strsymbols the string symbols to inspect.
* @param {array} chrsymbols the character symbols to find.
* @returns {number} returns the index of the first unmatched string symbol.
*/
function charsstartindex(strsymbols, chrsymbols) {
var index = -1,
length = strsymbols.length;
while (++index < length && baseindexof(chrsymbols, strsymbols[index], 0) > -1) {}
return index;
}
/**
* used by `_.trim` and `_.trimend` to get the index of the last string symbol
* that is not found in the character symbols.
*
* @private
* @param {array} strsymbols the string symbols to inspect.
* @param {array} chrsymbols the character symbols to find.
* @returns {number} returns the index of the last unmatched string symbol.
*/
function charsendindex(strsymbols, chrsymbols) {
var index = strsymbols.length;
while (index-- && baseindexof(chrsymbols, strsymbols[index], 0) > -1) {}
return index;
}
/**
* gets the number of `placeholder` occurrences in `array`.
*
* @private
* @param {array} array the array to inspect.
* @param {*} placeholder the placeholder to search for.
* @returns {number} returns the placeholder count.
*/
function countholders(array, placeholder) {
var length = array.length,
result = 0;
while (length--) {
if (array[length] === placeholder) {
++result;
}
}
return result;
}
/**
* used by `_.deburr` to convert latin-1 supplement and latin extended-a
* letters to basic latin letters.
*
* @private
* @param {string} letter the matched letter to deburr.
* @returns {string} returns the deburred letter.
*/
var deburrletter = basepropertyof(deburredletters);
/**
* used by `_.escape` to convert characters to html entities.
*
* @private
* @param {string} chr the matched character to escape.
* @returns {string} returns the escaped character.
*/
var escapehtmlchar = basepropertyof(htmlescapes);
/**
* used by `_.template` to escape characters for inclusion in compiled string literals.
*
* @private
* @param {string} chr the matched character to escape.
* @returns {string} returns the escaped character.
*/
function escapestringchar(chr) {
return '\\' + stringescapes[chr];
}
/**
* gets the value at `key` of `object`.
*
* @private
* @param {object} [object] the object to query.
* @param {string} key the key of the property to get.
* @returns {*} returns the property value.
*/
function getvalue(object, key) {
return object == null ? undefined : object[key];
}
/**
* checks if `string` contains unicode symbols.
*
* @private
* @param {string} string the string to inspect.
* @returns {boolean} returns `true` if a symbol is found, else `false`.
*/
function hasunicode(string) {
return rehasunicode.test(string);
}
/**
* checks if `string` contains a word composed of unicode symbols.
*
* @private
* @param {string} string the string to inspect.
* @returns {boolean} returns `true` if a word is found, else `false`.
*/
function hasunicodeword(string) {
return rehasunicodeword.test(string);
}
/**
* converts `iterator` to an array.
*
* @private
* @param {object} iterator the iterator to convert.
* @returns {array} returns the converted array.
*/
function iteratortoarray(iterator) {
var data,
result = [];
while (!(data = iterator.next()).done) {
result.push(data.value);
}
return result;
}
/**
* converts `map` to its key-value pairs.
*
* @private
* @param {object} map the map to convert.
* @returns {array} returns the key-value pairs.
*/
function maptoarray(map) {
var index = -1,
result = array(map.size);
map.foreach(function(value, key) {
result[++index] = [key, value];
});
return result;
}
/**
* creates a unary function that invokes `func` with its argument transformed.
*
* @private
* @param {function} func the function to wrap.
* @param {function} transform the argument transform.
* @returns {function} returns the new function.
*/
function overarg(func, transform) {
return function(arg) {
return func(transform(arg));
};
}
/**
* replaces all `placeholder` elements in `array` with an internal placeholder
* and returns an array of their indexes.
*
* @private
* @param {array} array the array to modify.
* @param {*} placeholder the placeholder to replace.
* @returns {array} returns the new array of placeholder indexes.
*/
function replaceholders(array, placeholder) {
var index = -1,
length = array.length,
resindex = 0,
result = [];
while (++index < length) {
var value = array[index];
if (value === placeholder || value === placeholder) {
array[index] = placeholder;
result[resindex++] = index;
}
}
return result;
}
/**
* converts `set` to an array of its values.
*
* @private
* @param {object} set the set to convert.
* @returns {array} returns the values.
*/
function settoarray(set) {
var index = -1,
result = array(set.size);
set.foreach(function(value) {
result[++index] = value;
});
return result;
}
/**
* converts `set` to its value-value pairs.
*
* @private
* @param {object} set the set to convert.
* @returns {array} returns the value-value pairs.
*/
function settopairs(set) {
var index = -1,
result = array(set.size);
set.foreach(function(value) {
result[++index] = [value, value];
});
return result;
}
/**
* a specialized version of `_.indexof` which performs strict equality
* comparisons of values, i.e. `===`.
*
* @private
* @param {array} array the array to inspect.
* @param {*} value the value to search for.
* @param {number} fromindex the index to search from.
* @returns {number} returns the index of the matched value, else `-1`.
*/
function strictindexof(array, value, fromindex) {
var index = fromindex - 1,
length = array.length;
while (++index < length) {
if (array[index] === value) {
return index;
}
}
return -1;
}
/**
* a specialized version of `_.lastindexof` which performs strict equality
* comparisons of values, i.e. `===`.
*
* @private
* @param {array} array the array to inspect.
* @param {*} value the value to search for.
* @param {number} fromindex the index to search from.
* @returns {number} returns the index of the matched value, else `-1`.
*/
function strictlastindexof(array, value, fromindex) {
var index = fromindex + 1;
while (index--) {
if (array[index] === value) {
return index;
}
}
return index;
}
/**
* gets the number of symbols in `string`.
*
* @private
* @param {string} string the string to inspect.
* @returns {number} returns the string size.
*/
function stringsize(string) {
return hasunicode(string)
? unicodesize(string)
: asciisize(string);
}
/**
* converts `string` to an array.
*
* @private
* @param {string} string the string to convert.
* @returns {array} returns the converted array.
*/
function stringtoarray(string) {
return hasunicode(string)
? unicodetoarray(string)
: asciitoarray(string);
}
/**
* used by `_.trim` and `_.trimend` to get the index of the last non-whitespace
* character of `string`.
*
* @private
* @param {string} string the string to inspect.
* @returns {number} returns the index of the last non-whitespace character.
*/
function trimmedendindex(string) {
var index = string.length;
while (index-- && rewhitespace.test(string.charat(index))) {}
return index;
}
/**
* used by `_.unescape` to convert html entities to characters.
*
* @private
* @param {string} chr the matched character to unescape.
* @returns {string} returns the unescaped character.
*/
var unescapehtmlchar = basepropertyof(htmlunescapes);
/**
* gets the size of a unicode `string`.
*
* @private
* @param {string} string the string inspect.
* @returns {number} returns the string size.
*/
function unicodesize(string) {
var result = reunicode.lastindex = 0;
while (reunicode.test(string)) {
++result;
}
return result;
}
/**
* converts a unicode `string` to an array.
*
* @private
* @param {string} string the string to convert.
* @returns {array} returns the converted array.
*/
function unicodetoarray(string) {
return string.match(reunicode) || [];
}
/**
* splits a unicode `string` into an array of its words.
*
* @private
* @param {string} the string to inspect.
* @returns {array} returns the words of `string`.
*/
function unicodewords(string) {
return string.match(reunicodeword) || [];
}
/*--------------------------------------------------------------------------*/
/**
* create a new pristine `lodash` function using the `context` object.
*
* @static
* @memberof _
* @since 1.1.0
* @category util
* @param {object} [context=root] the context object.
* @returns {function} returns a new `lodash` function.
* @example
*
* _.mixin({ 'foo': _.constant('foo') });
*
* var lodash = _.runincontext();
* lodash.mixin({ 'bar': lodash.constant('bar') });
*
* _.isfunction(_.foo);
* // => true
* _.isfunction(_.bar);
* // => false
*
* lodash.isfunction(lodash.foo);
* // => false
* lodash.isfunction(lodash.bar);
* // => true
*
* // create a suped-up `defer` in node.js.
* var defer = _.runincontext({ 'settimeout': setimmediate }).defer;
*/
var runincontext = (function runincontext(context) {
context = context == null ? root : _.defaults(root.object(), context, _.pick(root, contextprops));
/** built-in constructor references. */
var array = context.array,
date = context.date,
error = context.error,
function = context.function,
math = context.math,
object = context.object,
regexp = context.regexp,
string = context.string,
typeerror = context.typeerror;
/** used for built-in method references. */
var arrayproto = array.prototype,
funcproto = function.prototype,
objectproto = object.prototype;
/** used to detect overreaching core-js shims. */
var corejsdata = context['__core-js_shared__'];
/** used to resolve the decompiled source of functions. */
var functostring = funcproto.tostring;
/** used to check objects for own properties. */
var hasownproperty = objectproto.hasownproperty;
/** used to generate unique ids. */
var idcounter = 0;
/** used to detect methods masquerading as native. */
var masksrckey = (function() {
var uid = /[^.]+$/.exec(corejsdata && corejsdata.keys && corejsdata.keys.ie_proto || '');
return uid ? ('symbol(src)_1.' + uid) : '';
}());
/**
* used to resolve the
* [`tostringtag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeobjecttostring = objectproto.tostring;
/** used to infer the `object` constructor. */
var objectctorstring = functostring.call(object);
/** used to restore the original `_` reference in `_.noconflict`. */
var olddash = root._;
/** used to detect if a method is native. */
var reisnative = regexp('^' +
functostring.call(hasownproperty).replace(reregexpchar, '\\$&')
.replace(/hasownproperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
/** built-in value references. */
var buffer = moduleexports ? context.buffer : undefined,
symbol = context.symbol,
uint8array = context.uint8array,
allocunsafe = buffer ? buffer.allocunsafe : undefined,
getprototype = overarg(object.getprototypeof, object),
objectcreate = object.create,
propertyisenumerable = objectproto.propertyisenumerable,
splice = arrayproto.splice,
spreadablesymbol = symbol ? symbol.isconcatspreadable : undefined,
symiterator = symbol ? symbol.iterator : undefined,
symtostringtag = symbol ? symbol.tostringtag : undefined;
var defineproperty = (function() {
try {
var func = getnative(object, 'defineproperty');
func({}, '', {});
return func;
} catch (e) {}
}());
/** mocked built-ins. */
var ctxcleartimeout = context.cleartimeout !== root.cleartimeout && context.cleartimeout,
ctxnow = date && date.now !== root.date.now && date.now,
ctxsettimeout = context.settimeout !== root.settimeout && context.settimeout;
/* built-in method references for those with the same name as other `lodash` methods. */
var nativeceil = math.ceil,
nativefloor = math.floor,
nativegetsymbols = object.getownpropertysymbols,
nativeisbuffer = buffer ? buffer.isbuffer : undefined,
nativeisfinite = context.isfinite,
nativejoin = arrayproto.join,
nativekeys = overarg(object.keys, object),
nativemax = math.max,
nativemin = math.min,
nativenow = date.now,
nativeparseint = context.parseint,
nativerandom = math.random,
nativereverse = arrayproto.reverse;
/* built-in method references that are verified to be native. */
var dataview = getnative(context, 'dataview'),
map = getnative(context, 'map'),
promise = getnative(context, 'promise'),
set = getnative(context, 'set'),
weakmap = getnative(context, 'weakmap'),
nativecreate = getnative(object, 'create');
/** used to store function metadata. */
var metamap = weakmap && new weakmap;
/** used to lookup unminified function names. */
var realnames = {};
/** used to detect maps, sets, and weakmaps. */
var dataviewctorstring = tosource(dataview),
mapctorstring = tosource(map),
promisectorstring = tosource(promise),
setctorstring = tosource(set),
weakmapctorstring = tosource(weakmap);
/** used to convert symbols to primitives and strings. */
var symbolproto = symbol ? symbol.prototype : undefined,
symbolvalueof = symbolproto ? symbolproto.valueof : undefined,
symboltostring = symbolproto ? symbolproto.tostring : undefined;
/*------------------------------------------------------------------------*/
/**
* creates a `lodash` object which wraps `value` to enable implicit method
* chain sequences. methods that operate on and return arrays, collections,
* and functions can be chained together. methods that retrieve a single value
* or may return a primitive value will automatically end the chain sequence
* and return the unwrapped value. otherwise, the value must be unwrapped
* with `_#value`.
*
* explicit chain sequences, which must be unwrapped with `_#value`, may be
* enabled using `_.chain`.
*
* the execution of chained methods is lazy, that is, it's deferred until
* `_#value` is implicitly or explicitly called.
*
* lazy evaluation allows several methods to support shortcut fusion.
* shortcut fusion is an optimization to merge iteratee calls; this avoids
* the creation of intermediate arrays and can greatly reduce the number of
* iteratee executions. sections of a chain sequence qualify for shortcut
* fusion if the section is applied to an array and iteratees accept only
* one argument. the heuristic for whether a section qualifies for shortcut
* fusion is subject to change.
*
* chaining is supported in custom builds as long as the `_#value` method is
* directly or indirectly included in the build.
*
* in addition to lodash methods, wrappers have `array` and `string` methods.
*
* the wrapper `array` methods are:
* `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
*
* the wrapper `string` methods are:
* `replace` and `split`
*
* the wrapper methods that support shortcut fusion are:
* `at`, `compact`, `drop`, `dropright`, `dropwhile`, `filter`, `find`,
* `findlast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
* `tail`, `take`, `takeright`, `takerightwhile`, `takewhile`, and `toarray`
*
* the chainable wrapper methods are:
* `after`, `ary`, `assign`, `assignin`, `assigninwith`, `assignwith`, `at`,
* `before`, `bind`, `bindall`, `bindkey`, `castarray`, `chain`, `chunk`,
* `commit`, `compact`, `concat`, `conforms`, `constant`, `countby`, `create`,
* `curry`, `debounce`, `defaults`, `defaultsdeep`, `defer`, `delay`,
* `difference`, `differenceby`, `differencewith`, `drop`, `dropright`,
* `droprightwhile`, `dropwhile`, `extend`, `extendwith`, `fill`, `filter`,
* `flatmap`, `flatmapdeep`, `flatmapdepth`, `flatten`, `flattendeep`,
* `flattendepth`, `flip`, `flow`, `flowright`, `frompairs`, `functions`,
* `functionsin`, `groupby`, `initial`, `intersection`, `intersectionby`,
* `intersectionwith`, `invert`, `invertby`, `invokemap`, `iteratee`, `keyby`,
* `keys`, `keysin`, `map`, `mapkeys`, `mapvalues`, `matches`, `matchesproperty`,
* `memoize`, `merge`, `mergewith`, `method`, `methodof`, `mixin`, `negate`,
* `ntharg`, `omit`, `omitby`, `once`, `orderby`, `over`, `overargs`,
* `overevery`, `oversome`, `partial`, `partialright`, `partition`, `pick`,
* `pickby`, `plant`, `property`, `propertyof`, `pull`, `pullall`, `pullallby`,
* `pullallwith`, `pullat`, `push`, `range`, `rangeright`, `rearg`, `reject`,
* `remove`, `rest`, `reverse`, `samplesize`, `set`, `setwith`, `shuffle`,
* `slice`, `sort`, `sortby`, `splice`, `spread`, `tail`, `take`, `takeright`,
* `takerightwhile`, `takewhile`, `tap`, `throttle`, `thru`, `toarray`,
* `topairs`, `topairsin`, `topath`, `toplainobject`, `transform`, `unary`,
* `union`, `unionby`, `unionwith`, `uniq`, `uniqby`, `uniqwith`, `unset`,
* `unshift`, `unzip`, `unzipwith`, `update`, `updatewith`, `values`,
* `valuesin`, `without`, `wrap`, `xor`, `xorby`, `xorwith`, `zip`,
* `zipobject`, `zipobjectdeep`, and `zipwith`
*
* the wrapper methods that are **not** chainable by default are:
* `add`, `attempt`, `camelcase`, `capitalize`, `ceil`, `clamp`, `clone`,
* `clonedeep`, `clonedeepwith`, `clonewith`, `conformsto`, `deburr`,
* `defaultto`, `divide`, `each`, `eachright`, `endswith`, `eq`, `escape`,
* `escaperegexp`, `every`, `find`, `findindex`, `findkey`, `findlast`,
* `findlastindex`, `findlastkey`, `first`, `floor`, `foreach`, `foreachright`,
* `forin`, `forinright`, `forown`, `forownright`, `get`, `gt`, `gte`, `has`,
* `hasin`, `head`, `identity`, `includes`, `indexof`, `inrange`, `invoke`,
* `isarguments`, `isarray`, `isarraybuffer`, `isarraylike`, `isarraylikeobject`,
* `isboolean`, `isbuffer`, `isdate`, `iselement`, `isempty`, `isequal`,
* `isequalwith`, `iserror`, `isfinite`, `isfunction`, `isinteger`, `islength`,
* `ismap`, `ismatch`, `ismatchwith`, `isnan`, `isnative`, `isnil`, `isnull`,
* `isnumber`, `isobject`, `isobjectlike`, `isplainobject`, `isregexp`,
* `issafeinteger`, `isset`, `isstring`, `isundefined`, `istypedarray`,
* `isweakmap`, `isweakset`, `join`, `kebabcase`, `last`, `lastindexof`,
* `lowercase`, `lowerfirst`, `lt`, `lte`, `max`, `maxby`, `mean`, `meanby`,
* `min`, `minby`, `multiply`, `noconflict`, `noop`, `now`, `nth`, `pad`,
* `padend`, `padstart`, `parseint`, `pop`, `random`, `reduce`, `reduceright`,
* `repeat`, `result`, `round`, `runincontext`, `sample`, `shift`, `size`,
* `snakecase`, `some`, `sortedindex`, `sortedindexby`, `sortedlastindex`,
* `sortedlastindexby`, `startcase`, `startswith`, `stubarray`, `stubfalse`,
* `stubobject`, `stubstring`, `stubtrue`, `subtract`, `sum`, `sumby`,
* `template`, `times`, `tofinite`, `tointeger`, `tojson`, `tolength`,
* `tolower`, `tonumber`, `tosafeinteger`, `tostring`, `toupper`, `trim`,
* `trimend`, `trimstart`, `truncate`, `unescape`, `uniqueid`, `uppercase`,
* `upperfirst`, `value`, and `words`
*
* @name _
* @constructor
* @category seq
* @param {*} value the value to wrap in a `lodash` instance.
* @returns {object} returns the new `lodash` wrapper instance.
* @example
*
* function square(n) {
* return n * n;
* }
*
* var wrapped = _([1, 2, 3]);
*
* // returns an unwrapped value.
* wrapped.reduce(_.add);
* // => 6
*
* // returns a wrapped value.
* var squares = wrapped.map(square);
*
* _.isarray(squares);
* // => false
*
* _.isarray(squares.value());
* // => true
*/
function lodash(value) {
if (isobjectlike(value) && !isarray(value) && !(value instanceof lazywrapper)) {
if (value instanceof lodashwrapper) {
return value;
}
if (hasownproperty.call(value, '__wrapped__')) {
return wrapperclone(value);
}
}
return new lodashwrapper(value);
}
/**
* the base implementation of `_.create` without support for assigning
* properties to the created object.
*
* @private
* @param {object} proto the object to inherit from.
* @returns {object} returns the new object.
*/
var basecreate = (function() {
function object() {}
return function(proto) {
if (!isobject(proto)) {
return {};
}
if (objectcreate) {
return objectcreate(proto);
}
object.prototype = proto;
var result = new object;
object.prototype = undefined;
return result;
};
}());
/**
* the function whose prototype chain sequence wrappers inherit from.
*
* @private
*/
function baselodash() {
// no operation performed.
}
/**
* the base constructor for creating `lodash` wrapper objects.
*
* @private
* @param {*} value the value to wrap.
* @param {boolean} [chainall] enable explicit method chain sequences.
*/
function lodashwrapper(value, chainall) {
this.__wrapped__ = value;
this.__actions__ = [];
this.__chain__ = !!chainall;
this.__index__ = 0;
this.__values__ = undefined;
}
/**
* by default, the template delimiters used by lodash are like those in
* embedded ruby (erb) as well as es2015 template strings. change the
* following template settings to use alternative delimiters.
*
* @static
* @memberof _
* @type {object}
*/
lodash.templatesettings = {
/**
* used to detect `data` property values to be html-escaped.
*
* @memberof _.templatesettings
* @type {regexp}
*/
'escape': reescape,
/**
* used to detect code to be evaluated.
*
* @memberof _.templatesettings
* @type {regexp}
*/
'evaluate': reevaluate,
/**
* used to detect `data` property values to inject.
*
* @memberof _.templatesettings
* @type {regexp}
*/
'interpolate': reinterpolate,
/**
* used to reference the data object in the template text.
*
* @memberof _.templatesettings
* @type {string}
*/
'variable': '',
/**
* used to import variables into the compiled template.
*
* @memberof _.templatesettings
* @type {object}
*/
'imports': {
/**
* a reference to the `lodash` function.
*
* @memberof _.templatesettings.imports
* @type {function}
*/
'_': lodash
}
};
// ensure wrappers are instances of `baselodash`.
lodash.prototype = baselodash.prototype;
lodash.prototype.constructor = lodash;
lodashwrapper.prototype = basecreate(baselodash.prototype);
lodashwrapper.prototype.constructor = lodashwrapper;
/*------------------------------------------------------------------------*/
/**
* creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
*
* @private
* @constructor
* @param {*} value the value to wrap.
*/
function lazywrapper(value) {
this.__wrapped__ = value;
this.__actions__ = [];
this.__dir__ = 1;
this.__filtered__ = false;
this.__iteratees__ = [];
this.__takecount__ = max_array_length;
this.__views__ = [];
}
/**
* creates a clone of the lazy wrapper object.
*
* @private
* @name clone
* @memberof lazywrapper
* @returns {object} returns the cloned `lazywrapper` object.
*/
function lazyclone() {
var result = new lazywrapper(this.__wrapped__);
result.__actions__ = copyarray(this.__actions__);
result.__dir__ = this.__dir__;
result.__filtered__ = this.__filtered__;
result.__iteratees__ = copyarray(this.__iteratees__);
result.__takecount__ = this.__takecount__;
result.__views__ = copyarray(this.__views__);
return result;
}
/**
* reverses the direction of lazy iteration.
*
* @private
* @name reverse
* @memberof lazywrapper
* @returns {object} returns the new reversed `lazywrapper` object.
*/
function lazyreverse() {
if (this.__filtered__) {
var result = new lazywrapper(this);
result.__dir__ = -1;
result.__filtered__ = true;
} else {
result = this.clone();
result.__dir__ *= -1;
}
return result;
}
/**
* extracts the unwrapped value from its lazy wrapper.
*
* @private
* @name value
* @memberof lazywrapper
* @returns {*} returns the unwrapped value.
*/
function lazyvalue() {
var array = this.__wrapped__.value(),
dir = this.__dir__,
isarr = isarray(array),
isright = dir < 0,
arrlength = isarr ? array.length : 0,
view = getview(0, arrlength, this.__views__),
start = view.start,
end = view.end,
length = end - start,
index = isright ? end : (start - 1),
iteratees = this.__iteratees__,
iterlength = iteratees.length,
resindex = 0,
takecount = nativemin(length, this.__takecount__);
if (!isarr || (!isright && arrlength == length && takecount == length)) {
return basewrappervalue(array, this.__actions__);
}
var result = [];
outer:
while (length-- && resindex < takecount) {
index += dir;
var iterindex = -1,
value = array[index];
while (++iterindex < iterlength) {
var data = iteratees[iterindex],
iteratee = data.iteratee,
type = data.type,
computed = iteratee(value);
if (type == lazy_map_flag) {
value = computed;
} else if (!computed) {
if (type == lazy_filter_flag) {
continue outer;
} else {
break outer;
}
}
}
result[resindex++] = value;
}
return result;
}
// ensure `lazywrapper` is an instance of `baselodash`.
lazywrapper.prototype = basecreate(baselodash.prototype);
lazywrapper.prototype.constructor = lazywrapper;
/*------------------------------------------------------------------------*/
/**
* creates a hash object.
*
* @private
* @constructor
* @param {array} [entries] the key-value pairs to cache.
*/
function hash(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* removes all key-value entries from the hash.
*
* @private
* @name clear
* @memberof hash
*/
function hashclear() {
this.__data__ = nativecreate ? nativecreate(null) : {};
this.size = 0;
}
/**
* removes `key` and its value from the hash.
*
* @private
* @name delete
* @memberof hash
* @param {object} hash the hash to modify.
* @param {string} key the key of the value to remove.
* @returns {boolean} returns `true` if the entry was removed, else `false`.
*/
function hashdelete(key) {
var result = this.has(key) && delete this.__data__[key];
this.size -= result ? 1 : 0;
return result;
}
/**
* gets the hash value for `key`.
*
* @private
* @name get
* @memberof hash
* @param {string} key the key of the value to get.
* @returns {*} returns the entry value.
*/
function hashget(key) {
var data = this.__data__;
if (nativecreate) {
var result = data[key];
return result === hash_undefined ? undefined : result;
}
return hasownproperty.call(data, key) ? data[key] : undefined;
}
/**
* checks if a hash value for `key` exists.
*
* @private
* @name has
* @memberof hash
* @param {string} key the key of the entry to check.
* @returns {boolean} returns `true` if an entry for `key` exists, else `false`.
*/
function hashhas(key) {
var data = this.__data__;
return nativecreate ? (data[key] !== undefined) : hasownproperty.call(data, key);
}
/**
* sets the hash `key` to `value`.
*
* @private
* @name set
* @memberof hash
* @param {string} key the key of the value to set.
* @param {*} value the value to set.
* @returns {object} returns the hash instance.
*/
function hashset(key, value) {
var data = this.__data__;
this.size += this.has(key) ? 0 : 1;
data[key] = (nativecreate && value === undefined) ? hash_undefined : value;
return this;
}
// add methods to `hash`.
hash.prototype.clear = hashclear;
hash.prototype['delete'] = hashdelete;
hash.prototype.get = hashget;
hash.prototype.has = hashhas;
hash.prototype.set = hashset;
/*------------------------------------------------------------------------*/
/**
* creates an list cache object.
*
* @private
* @constructor
* @param {array} [entries] the key-value pairs to cache.
*/
function listcache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* removes all key-value entries from the list cache.
*
* @private
* @name clear
* @memberof listcache
*/
function listcacheclear() {
this.__data__ = [];
this.size = 0;
}
/**
* removes `key` and its value from the list cache.
*
* @private
* @name delete
* @memberof listcache
* @param {string} key the key of the value to remove.
* @returns {boolean} returns `true` if the entry was removed, else `false`.
*/
function listcachedelete(key) {
var data = this.__data__,
index = associndexof(data, key);
if (index < 0) {
return false;
}
var lastindex = data.length - 1;
if (index == lastindex) {
data.pop();
} else {
splice.call(data, index, 1);
}
--this.size;
return true;
}
/**
* gets the list cache value for `key`.
*
* @private
* @name get
* @memberof listcache
* @param {string} key the key of the value to get.
* @returns {*} returns the entry value.
*/
function listcacheget(key) {
var data = this.__data__,
index = associndexof(data, key);
return index < 0 ? undefined : data[index][1];
}
/**
* checks if a list cache value for `key` exists.
*
* @private
* @name has
* @memberof listcache
* @param {string} key the key of the entry to check.
* @returns {boolean} returns `true` if an entry for `key` exists, else `false`.
*/
function listcachehas(key) {
return associndexof(this.__data__, key) > -1;
}
/**
* sets the list cache `key` to `value`.
*
* @private
* @name set
* @memberof listcache
* @param {string} key the key of the value to set.
* @param {*} value the value to set.
* @returns {object} returns the list cache instance.
*/
function listcacheset(key, value) {
var data = this.__data__,
index = associndexof(data, key);
if (index < 0) {
++this.size;
data.push([key, value]);
} else {
data[index][1] = value;
}
return this;
}
// add methods to `listcache`.
listcache.prototype.clear = listcacheclear;
listcache.prototype['delete'] = listcachedelete;
listcache.prototype.get = listcacheget;
listcache.prototype.has = listcachehas;
listcache.prototype.set = listcacheset;
/*------------------------------------------------------------------------*/
/**
* creates a map cache object to store key-value pairs.
*
* @private
* @constructor
* @param {array} [entries] the key-value pairs to cache.
*/
function mapcache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
/**
* removes all key-value entries from the map.
*
* @private
* @name clear
* @memberof mapcache
*/
function mapcacheclear() {
this.size = 0;
this.__data__ = {
'hash': new hash,
'map': new (map || listcache),
'string': new hash
};
}
/**
* removes `key` and its value from the map.
*
* @private
* @name delete
* @memberof mapcache
* @param {string} key the key of the value to remove.
* @returns {boolean} returns `true` if the entry was removed, else `false`.
*/
function mapcachedelete(key) {
var result = getmapdata(this, key)['delete'](key);
this.size -= result ? 1 : 0;
return result;
}
/**
* gets the map value for `key`.
*
* @private
* @name get
* @memberof mapcache
* @param {string} key the key of the value to get.
* @returns {*} returns the entry value.
*/
function mapcacheget(key) {
return getmapdata(this, key).get(key);
}
/**
* checks if a map value for `key` exists.
*
* @private
* @name has
* @memberof mapcache
* @param {string} key the key of the entry to check.
* @returns {boolean} returns `true` if an entry for `key` exists, else `false`.
*/
function mapcachehas(key) {
return getmapdata(this, key).has(key);
}
/**
* sets the map `key` to `value`.
*
* @private
* @name set
* @memberof mapcache
* @param {string} key the key of the value to set.
* @param {*} value the value to set.
* @returns {object} returns the map cache instance.
*/
function mapcacheset(key, value) {
var data = getmapdata(this, key),
size = data.size;
data.set(key, value);
this.size += data.size == size ? 0 : 1;
return this;
}
// add methods to `mapcache`.
mapcache.prototype.clear = mapcacheclear;
mapcache.prototype['delete'] = mapcachedelete;
mapcache.prototype.get = mapcacheget;
mapcache.prototype.has = mapcachehas;
mapcache.prototype.set = mapcacheset;
/*------------------------------------------------------------------------*/
/**
*
* creates an array cache object to store unique values.
*
* @private
* @constructor
* @param {array} [values] the values to cache.
*/
function setcache(values) {
var index = -1,
length = values == null ? 0 : values.length;
this.__data__ = new mapcache;
while (++index < length) {
this.add(values[index]);
}
}
/**
* adds `value` to the array cache.
*
* @private
* @name add
* @memberof setcache
* @alias push
* @param {*} value the value to cache.
* @returns {object} returns the cache instance.
*/
function setcacheadd(value) {
this.__data__.set(value, hash_undefined);
return this;
}
/**
* checks if `value` is in the array cache.
*
* @private
* @name has
* @memberof setcache
* @param {*} value the value to search for.
* @returns {number} returns `true` if `value` is found, else `false`.
*/
function setcachehas(value) {
return this.__data__.has(value);
}
// add methods to `setcache`.
setcache.prototype.add = setcache.prototype.push = setcacheadd;
setcache.prototype.has = setcachehas;
/*------------------------------------------------------------------------*/
/**
* creates a stack cache object to store key-value pairs.
*
* @private
* @constructor
* @param {array} [entries] the key-value pairs to cache.
*/
function stack(entries) {
var data = this.__data__ = new listcache(entries);
this.size = data.size;
}
/**
* removes all key-value entries from the stack.
*
* @private
* @name clear
* @memberof stack
*/
function stackclear() {
this.__data__ = new listcache;
this.size = 0;
}
/**
* removes `key` and its value from the stack.
*
* @private
* @name delete
* @memberof stack
* @param {string} key the key of the value to remove.
* @returns {boolean} returns `true` if the entry was removed, else `false`.
*/
function stackdelete(key) {
var data = this.__data__,
result = data['delete'](key);
this.size = data.size;
return result;
}
/**
* gets the stack value for `key`.
*
* @private
* @name get
* @memberof stack
* @param {string} key the key of the value to get.
* @returns {*} returns the entry value.
*/
function stackget(key) {
return this.__data__.get(key);
}
/**
* checks if a stack value for `key` exists.
*
* @private
* @name has
* @memberof stack
* @param {string} key the key of the entry to check.
* @returns {boolean} returns `true` if an entry for `key` exists, else `false`.
*/
function stackhas(key) {
return this.__data__.has(key);
}
/**
* sets the stack `key` to `value`.
*
* @private
* @name set
* @memberof stack
* @param {string} key the key of the value to set.
* @param {*} value the value to set.
* @returns {object} returns the stack cache instance.
*/
function stackset(key, value) {
var data = this.__data__;
if (data instanceof listcache) {
var pairs = data.__data__;
if (!map || (pairs.length < large_array_size - 1)) {
pairs.push([key, value]);
this.size = ++data.size;
return this;
}
data = this.__data__ = new mapcache(pairs);
}
data.set(key, value);
this.size = data.size;
return this;
}
// add methods to `stack`.
stack.prototype.clear = stackclear;
stack.prototype['delete'] = stackdelete;
stack.prototype.get = stackget;
stack.prototype.has = stackhas;
stack.prototype.set = stackset;
/*------------------------------------------------------------------------*/
/**
* creates an array of the enumerable property names of the array-like `value`.
*
* @private
* @param {*} value the value to query.
* @param {boolean} inherited specify returning inherited property names.
* @returns {array} returns the array of property names.
*/
function arraylikekeys(value, inherited) {
var isarr = isarray(value),
isarg = !isarr && isarguments(value),
isbuff = !isarr && !isarg && isbuffer(value),
istype = !isarr && !isarg && !isbuff && istypedarray(value),
skipindexes = isarr || isarg || isbuff || istype,
result = skipindexes ? basetimes(value.length, string) : [],
length = result.length;
for (var key in value) {
if ((inherited || hasownproperty.call(value, key)) &&
!(skipindexes && (
// safari 9 has enumerable `arguments.length` in strict mode.
key == 'length' ||
// node.js 0.10 has enumerable non-index properties on buffers.
(isbuff && (key == 'offset' || key == 'parent')) ||
// phantomjs 2 has enumerable non-index properties on typed arrays.
(istype && (key == 'buffer' || key == 'bytelength' || key == 'byteoffset')) ||
// skip index properties.
isindex(key, length)
))) {
result.push(key);
}
}
return result;
}
/**
* a specialized version of `_.sample` for arrays.
*
* @private
* @param {array} array the array to sample.
* @returns {*} returns the random element.
*/
function arraysample(array) {
var length = array.length;
return length ? array[baserandom(0, length - 1)] : undefined;
}
/**
* a specialized version of `_.samplesize` for arrays.
*
* @private
* @param {array} array the array to sample.
* @param {number} n the number of elements to sample.
* @returns {array} returns the random elements.
*/
function arraysamplesize(array, n) {
return shuffleself(copyarray(array), baseclamp(n, 0, array.length));
}
/**
* a specialized version of `_.shuffle` for arrays.
*
* @private
* @param {array} array the array to shuffle.
* @returns {array} returns the new shuffled array.
*/
function arrayshuffle(array) {
return shuffleself(copyarray(array));
}
/**
* this function is like `assignvalue` except that it doesn't assign
* `undefined` values.
*
* @private
* @param {object} object the object to modify.
* @param {string} key the key of the property to assign.
* @param {*} value the value to assign.
*/
function assignmergevalue(object, key, value) {
if ((value !== undefined && !eq(object[key], value)) ||
(value === undefined && !(key in object))) {
baseassignvalue(object, key, value);
}
}
/**
* assigns `value` to `key` of `object` if the existing value is not equivalent
* using [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons.
*
* @private
* @param {object} object the object to modify.
* @param {string} key the key of the property to assign.
* @param {*} value the value to assign.
*/
function assignvalue(object, key, value) {
var objvalue = object[key];
if (!(hasownproperty.call(object, key) && eq(objvalue, value)) ||
(value === undefined && !(key in object))) {
baseassignvalue(object, key, value);
}
}
/**
* gets the index at which the `key` is found in `array` of key-value pairs.
*
* @private
* @param {array} array the array to inspect.
* @param {*} key the key to search for.
* @returns {number} returns the index of the matched value, else `-1`.
*/
function associndexof(array, key) {
var length = array.length;
while (length--) {
if (eq(array[length][0], key)) {
return length;
}
}
return -1;
}
/**
* aggregates elements of `collection` on `accumulator` with keys transformed
* by `iteratee` and values set by `setter`.
*
* @private
* @param {array|object} collection the collection to iterate over.
* @param {function} setter the function to set `accumulator` values.
* @param {function} iteratee the iteratee to transform keys.
* @param {object} accumulator the initial aggregated object.
* @returns {function} returns `accumulator`.
*/
function baseaggregator(collection, setter, iteratee, accumulator) {
baseeach(collection, function(value, key, collection) {
setter(accumulator, value, iteratee(value), collection);
});
return accumulator;
}
/**
* the base implementation of `_.assign` without support for multiple sources
* or `customizer` functions.
*
* @private
* @param {object} object the destination object.
* @param {object} source the source object.
* @returns {object} returns `object`.
*/
function baseassign(object, source) {
return object && copyobject(source, keys(source), object);
}
/**
* the base implementation of `_.assignin` without support for multiple sources
* or `customizer` functions.
*
* @private
* @param {object} object the destination object.
* @param {object} source the source object.
* @returns {object} returns `object`.
*/
function baseassignin(object, source) {
return object && copyobject(source, keysin(source), object);
}
/**
* the base implementation of `assignvalue` and `assignmergevalue` without
* value checks.
*
* @private
* @param {object} object the object to modify.
* @param {string} key the key of the property to assign.
* @param {*} value the value to assign.
*/
function baseassignvalue(object, key, value) {
if (key == '__proto__' && defineproperty) {
defineproperty(object, key, {
'configurable': true,
'enumerable': true,
'value': value,
'writable': true
});
} else {
object[key] = value;
}
}
/**
* the base implementation of `_.at` without support for individual paths.
*
* @private
* @param {object} object the object to iterate over.
* @param {string[]} paths the property paths to pick.
* @returns {array} returns the picked elements.
*/
function baseat(object, paths) {
var index = -1,
length = paths.length,
result = array(length),
skip = object == null;
while (++index < length) {
result[index] = skip ? undefined : get(object, paths[index]);
}
return result;
}
/**
* the base implementation of `_.clamp` which doesn't coerce arguments.
*
* @private
* @param {number} number the number to clamp.
* @param {number} [lower] the lower bound.
* @param {number} upper the upper bound.
* @returns {number} returns the clamped number.
*/
function baseclamp(number, lower, upper) {
if (number === number) {
if (upper !== undefined) {
number = number <= upper ? number : upper;
}
if (lower !== undefined) {
number = number >= lower ? number : lower;
}
}
return number;
}
/**
* the base implementation of `_.clone` and `_.clonedeep` which tracks
* traversed objects.
*
* @private
* @param {*} value the value to clone.
* @param {boolean} bitmask the bitmask flags.
* 1 - deep clone
* 2 - flatten inherited properties
* 4 - clone symbols
* @param {function} [customizer] the function to customize cloning.
* @param {string} [key] the key of `value`.
* @param {object} [object] the parent object of `value`.
* @param {object} [stack] tracks traversed objects and their clone counterparts.
* @returns {*} returns the cloned value.
*/
function baseclone(value, bitmask, customizer, key, object, stack) {
var result,
isdeep = bitmask & clone_deep_flag,
isflat = bitmask & clone_flat_flag,
isfull = bitmask & clone_symbols_flag;
if (customizer) {
result = object ? customizer(value, key, object, stack) : customizer(value);
}
if (result !== undefined) {
return result;
}
if (!isobject(value)) {
return value;
}
var isarr = isarray(value);
if (isarr) {
result = initclonearray(value);
if (!isdeep) {
return copyarray(value, result);
}
} else {
var tag = gettag(value),
isfunc = tag == functag || tag == gentag;
if (isbuffer(value)) {
return clonebuffer(value, isdeep);
}
if (tag == objecttag || tag == argstag || (isfunc && !object)) {
result = (isflat || isfunc) ? {} : initcloneobject(value);
if (!isdeep) {
return isflat
? copysymbolsin(value, baseassignin(result, value))
: copysymbols(value, baseassign(result, value));
}
} else {
if (!cloneabletags[tag]) {
return object ? value : {};
}
result = initclonebytag(value, tag, isdeep);
}
}
// check for circular references and return its corresponding clone.
stack || (stack = new stack);
var stacked = stack.get(value);
if (stacked) {
return stacked;
}
stack.set(value, result);
if (isset(value)) {
value.foreach(function(subvalue) {
result.add(baseclone(subvalue, bitmask, customizer, subvalue, value, stack));
});
} else if (ismap(value)) {
value.foreach(function(subvalue, key) {
result.set(key, baseclone(subvalue, bitmask, customizer, key, value, stack));
});
}
var keysfunc = isfull
? (isflat ? getallkeysin : getallkeys)
: (isflat ? keysin : keys);
var props = isarr ? undefined : keysfunc(value);
arrayeach(props || value, function(subvalue, key) {
if (props) {
key = subvalue;
subvalue = value[key];
}
// recursively populate clone (susceptible to call stack limits).
assignvalue(result, key, baseclone(subvalue, bitmask, customizer, key, value, stack));
});
return result;
}
/**
* the base implementation of `_.conforms` which doesn't clone `source`.
*
* @private
* @param {object} source the object of property predicates to conform to.
* @returns {function} returns the new spec function.
*/
function baseconforms(source) {
var props = keys(source);
return function(object) {
return baseconformsto(object, source, props);
};
}
/**
* the base implementation of `_.conformsto` which accepts `props` to check.
*
* @private
* @param {object} object the object to inspect.
* @param {object} source the object of property predicates to conform to.
* @returns {boolean} returns `true` if `object` conforms, else `false`.
*/
function baseconformsto(object, source, props) {
var length = props.length;
if (object == null) {
return !length;
}
object = object(object);
while (length--) {
var key = props[length],
predicate = source[key],
value = object[key];
if ((value === undefined && !(key in object)) || !predicate(value)) {
return false;
}
}
return true;
}
/**
* the base implementation of `_.delay` and `_.defer` which accepts `args`
* to provide to `func`.
*
* @private
* @param {function} func the function to delay.
* @param {number} wait the number of milliseconds to delay invocation.
* @param {array} args the arguments to provide to `func`.
* @returns {number|object} returns the timer id or timeout object.
*/
function basedelay(func, wait, args) {
if (typeof func != 'function') {
throw new typeerror(func_error_text);
}
return settimeout(function() { func.apply(undefined, args); }, wait);
}
/**
* the base implementation of methods like `_.difference` without support
* for excluding multiple arrays or iteratee shorthands.
*
* @private
* @param {array} array the array to inspect.
* @param {array} values the values to exclude.
* @param {function} [iteratee] the iteratee invoked per element.
* @param {function} [comparator] the comparator invoked per element.
* @returns {array} returns the new array of filtered values.
*/
function basedifference(array, values, iteratee, comparator) {
var index = -1,
includes = arrayincludes,
iscommon = true,
length = array.length,
result = [],
valueslength = values.length;
if (!length) {
return result;
}
if (iteratee) {
values = arraymap(values, baseunary(iteratee));
}
if (comparator) {
includes = arrayincludeswith;
iscommon = false;
}
else if (values.length >= large_array_size) {
includes = cachehas;
iscommon = false;
values = new setcache(values);
}
outer:
while (++index < length) {
var value = array[index],
computed = iteratee == null ? value : iteratee(value);
value = (comparator || value !== 0) ? value : 0;
if (iscommon && computed === computed) {
var valuesindex = valueslength;
while (valuesindex--) {
if (values[valuesindex] === computed) {
continue outer;
}
}
result.push(value);
}
else if (!includes(values, computed, comparator)) {
result.push(value);
}
}
return result;
}
/**
* the base implementation of `_.foreach` without support for iteratee shorthands.
*
* @private
* @param {array|object} collection the collection to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @returns {array|object} returns `collection`.
*/
var baseeach = createbaseeach(baseforown);
/**
* the base implementation of `_.foreachright` without support for iteratee shorthands.
*
* @private
* @param {array|object} collection the collection to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @returns {array|object} returns `collection`.
*/
var baseeachright = createbaseeach(baseforownright, true);
/**
* the base implementation of `_.every` without support for iteratee shorthands.
*
* @private
* @param {array|object} collection the collection to iterate over.
* @param {function} predicate the function invoked per iteration.
* @returns {boolean} returns `true` if all elements pass the predicate check,
* else `false`
*/
function baseevery(collection, predicate) {
var result = true;
baseeach(collection, function(value, index, collection) {
result = !!predicate(value, index, collection);
return result;
});
return result;
}
/**
* the base implementation of methods like `_.max` and `_.min` which accepts a
* `comparator` to determine the extremum value.
*
* @private
* @param {array} array the array to iterate over.
* @param {function} iteratee the iteratee invoked per iteration.
* @param {function} comparator the comparator used to compare values.
* @returns {*} returns the extremum value.
*/
function baseextremum(array, iteratee, comparator) {
var index = -1,
length = array.length;
while (++index < length) {
var value = array[index],
current = iteratee(value);
if (current != null && (computed === undefined
? (current === current && !issymbol(current))
: comparator(current, computed)
)) {
var computed = current,
result = value;
}
}
return result;
}
/**
* the base implementation of `_.fill` without an iteratee call guard.
*
* @private
* @param {array} array the array to fill.
* @param {*} value the value to fill `array` with.
* @param {number} [start=0] the start position.
* @param {number} [end=array.length] the end position.
* @returns {array} returns `array`.
*/
function basefill(array, value, start, end) {
var length = array.length;
start = tointeger(start);
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
end = (end === undefined || end > length) ? length : tointeger(end);
if (end < 0) {
end += length;
}
end = start > end ? 0 : tolength(end);
while (start < end) {
array[start++] = value;
}
return array;
}
/**
* the base implementation of `_.filter` without support for iteratee shorthands.
*
* @private
* @param {array|object} collection the collection to iterate over.
* @param {function} predicate the function invoked per iteration.
* @returns {array} returns the new filtered array.
*/
function basefilter(collection, predicate) {
var result = [];
baseeach(collection, function(value, index, collection) {
if (predicate(value, index, collection)) {
result.push(value);
}
});
return result;
}
/**
* the base implementation of `_.flatten` with support for restricting flattening.
*
* @private
* @param {array} array the array to flatten.
* @param {number} depth the maximum recursion depth.
* @param {boolean} [predicate=isflattenable] the function invoked per iteration.
* @param {boolean} [isstrict] restrict to values that pass `predicate` checks.
* @param {array} [result=[]] the initial result value.
* @returns {array} returns the new flattened array.
*/
function baseflatten(array, depth, predicate, isstrict, result) {
var index = -1,
length = array.length;
predicate || (predicate = isflattenable);
result || (result = []);
while (++index < length) {
var value = array[index];
if (depth > 0 && predicate(value)) {
if (depth > 1) {
// recursively flatten arrays (susceptible to call stack limits).
baseflatten(value, depth - 1, predicate, isstrict, result);
} else {
arraypush(result, value);
}
} else if (!isstrict) {
result[result.length] = value;
}
}
return result;
}
/**
* the base implementation of `baseforown` which iterates over `object`
* properties returned by `keysfunc` and invokes `iteratee` for each property.
* iteratee functions may exit iteration early by explicitly returning `false`.
*
* @private
* @param {object} object the object to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @param {function} keysfunc the function to get the keys of `object`.
* @returns {object} returns `object`.
*/
var basefor = createbasefor();
/**
* this function is like `basefor` except that it iterates over properties
* in the opposite order.
*
* @private
* @param {object} object the object to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @param {function} keysfunc the function to get the keys of `object`.
* @returns {object} returns `object`.
*/
var baseforright = createbasefor(true);
/**
* the base implementation of `_.forown` without support for iteratee shorthands.
*
* @private
* @param {object} object the object to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @returns {object} returns `object`.
*/
function baseforown(object, iteratee) {
return object && basefor(object, iteratee, keys);
}
/**
* the base implementation of `_.forownright` without support for iteratee shorthands.
*
* @private
* @param {object} object the object to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @returns {object} returns `object`.
*/
function baseforownright(object, iteratee) {
return object && baseforright(object, iteratee, keys);
}
/**
* the base implementation of `_.functions` which creates an array of
* `object` function property names filtered from `props`.
*
* @private
* @param {object} object the object to inspect.
* @param {array} props the property names to filter.
* @returns {array} returns the function names.
*/
function basefunctions(object, props) {
return arrayfilter(props, function(key) {
return isfunction(object[key]);
});
}
/**
* the base implementation of `_.get` without support for default values.
*
* @private
* @param {object} object the object to query.
* @param {array|string} path the path of the property to get.
* @returns {*} returns the resolved value.
*/
function baseget(object, path) {
path = castpath(path, object);
var index = 0,
length = path.length;
while (object != null && index < length) {
object = object[tokey(path[index++])];
}
return (index && index == length) ? object : undefined;
}
/**
* the base implementation of `getallkeys` and `getallkeysin` which uses
* `keysfunc` and `symbolsfunc` to get the enumerable property names and
* symbols of `object`.
*
* @private
* @param {object} object the object to query.
* @param {function} keysfunc the function to get the keys of `object`.
* @param {function} symbolsfunc the function to get the symbols of `object`.
* @returns {array} returns the array of property names and symbols.
*/
function basegetallkeys(object, keysfunc, symbolsfunc) {
var result = keysfunc(object);
return isarray(object) ? result : arraypush(result, symbolsfunc(object));
}
/**
* the base implementation of `gettag` without fallbacks for buggy environments.
*
* @private
* @param {*} value the value to query.
* @returns {string} returns the `tostringtag`.
*/
function basegettag(value) {
if (value == null) {
return value === undefined ? undefinedtag : nulltag;
}
return (symtostringtag && symtostringtag in object(value))
? getrawtag(value)
: objecttostring(value);
}
/**
* the base implementation of `_.gt` which doesn't coerce arguments.
*
* @private
* @param {*} value the value to compare.
* @param {*} other the other value to compare.
* @returns {boolean} returns `true` if `value` is greater than `other`,
* else `false`.
*/
function basegt(value, other) {
return value > other;
}
/**
* the base implementation of `_.has` without support for deep paths.
*
* @private
* @param {object} [object] the object to query.
* @param {array|string} key the key to check.
* @returns {boolean} returns `true` if `key` exists, else `false`.
*/
function basehas(object, key) {
return object != null && hasownproperty.call(object, key);
}
/**
* the base implementation of `_.hasin` without support for deep paths.
*
* @private
* @param {object} [object] the object to query.
* @param {array|string} key the key to check.
* @returns {boolean} returns `true` if `key` exists, else `false`.
*/
function basehasin(object, key) {
return object != null && key in object(object);
}
/**
* the base implementation of `_.inrange` which doesn't coerce arguments.
*
* @private
* @param {number} number the number to check.
* @param {number} start the start of the range.
* @param {number} end the end of the range.
* @returns {boolean} returns `true` if `number` is in the range, else `false`.
*/
function baseinrange(number, start, end) {
return number >= nativemin(start, end) && number < nativemax(start, end);
}
/**
* the base implementation of methods like `_.intersection`, without support
* for iteratee shorthands, that accepts an array of arrays to inspect.
*
* @private
* @param {array} arrays the arrays to inspect.
* @param {function} [iteratee] the iteratee invoked per element.
* @param {function} [comparator] the comparator invoked per element.
* @returns {array} returns the new array of shared values.
*/
function baseintersection(arrays, iteratee, comparator) {
var includes = comparator ? arrayincludeswith : arrayincludes,
length = arrays[0].length,
othlength = arrays.length,
othindex = othlength,
caches = array(othlength),
maxlength = infinity,
result = [];
while (othindex--) {
var array = arrays[othindex];
if (othindex && iteratee) {
array = arraymap(array, baseunary(iteratee));
}
maxlength = nativemin(array.length, maxlength);
caches[othindex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
? new setcache(othindex && array)
: undefined;
}
array = arrays[0];
var index = -1,
seen = caches[0];
outer:
while (++index < length && result.length < maxlength) {
var value = array[index],
computed = iteratee ? iteratee(value) : value;
value = (comparator || value !== 0) ? value : 0;
if (!(seen
? cachehas(seen, computed)
: includes(result, computed, comparator)
)) {
othindex = othlength;
while (--othindex) {
var cache = caches[othindex];
if (!(cache
? cachehas(cache, computed)
: includes(arrays[othindex], computed, comparator))
) {
continue outer;
}
}
if (seen) {
seen.push(computed);
}
result.push(value);
}
}
return result;
}
/**
* the base implementation of `_.invert` and `_.invertby` which inverts
* `object` with values transformed by `iteratee` and set by `setter`.
*
* @private
* @param {object} object the object to iterate over.
* @param {function} setter the function to set `accumulator` values.
* @param {function} iteratee the iteratee to transform values.
* @param {object} accumulator the initial inverted object.
* @returns {function} returns `accumulator`.
*/
function baseinverter(object, setter, iteratee, accumulator) {
baseforown(object, function(value, key, object) {
setter(accumulator, iteratee(value), key, object);
});
return accumulator;
}
/**
* the base implementation of `_.invoke` without support for individual
* method arguments.
*
* @private
* @param {object} object the object to query.
* @param {array|string} path the path of the method to invoke.
* @param {array} args the arguments to invoke the method with.
* @returns {*} returns the result of the invoked method.
*/
function baseinvoke(object, path, args) {
path = castpath(path, object);
object = parent(object, path);
var func = object == null ? object : object[tokey(last(path))];
return func == null ? undefined : apply(func, object, args);
}
/**
* the base implementation of `_.isarguments`.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is an `arguments` object,
*/
function baseisarguments(value) {
return isobjectlike(value) && basegettag(value) == argstag;
}
/**
* the base implementation of `_.isarraybuffer` without node.js optimizations.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is an array buffer, else `false`.
*/
function baseisarraybuffer(value) {
return isobjectlike(value) && basegettag(value) == arraybuffertag;
}
/**
* the base implementation of `_.isdate` without node.js optimizations.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a date object, else `false`.
*/
function baseisdate(value) {
return isobjectlike(value) && basegettag(value) == datetag;
}
/**
* the base implementation of `_.isequal` which supports partial comparisons
* and tracks traversed objects.
*
* @private
* @param {*} value the value to compare.
* @param {*} other the other value to compare.
* @param {boolean} bitmask the bitmask flags.
* 1 - unordered comparison
* 2 - partial comparison
* @param {function} [customizer] the function to customize comparisons.
* @param {object} [stack] tracks traversed `value` and `other` objects.
* @returns {boolean} returns `true` if the values are equivalent, else `false`.
*/
function baseisequal(value, other, bitmask, customizer, stack) {
if (value === other) {
return true;
}
if (value == null || other == null || (!isobjectlike(value) && !isobjectlike(other))) {
return value !== value && other !== other;
}
return baseisequaldeep(value, other, bitmask, customizer, baseisequal, stack);
}
/**
* a specialized version of `baseisequal` for arrays and objects which performs
* deep comparisons and tracks traversed objects enabling objects with circular
* references to be compared.
*
* @private
* @param {object} object the object to compare.
* @param {object} other the other object to compare.
* @param {number} bitmask the bitmask flags. see `baseisequal` for more details.
* @param {function} customizer the function to customize comparisons.
* @param {function} equalfunc the function to determine equivalents of values.
* @param {object} [stack] tracks traversed `object` and `other` objects.
* @returns {boolean} returns `true` if the objects are equivalent, else `false`.
*/
function baseisequaldeep(object, other, bitmask, customizer, equalfunc, stack) {
var objisarr = isarray(object),
othisarr = isarray(other),
objtag = objisarr ? arraytag : gettag(object),
othtag = othisarr ? arraytag : gettag(other);
objtag = objtag == argstag ? objecttag : objtag;
othtag = othtag == argstag ? objecttag : othtag;
var objisobj = objtag == objecttag,
othisobj = othtag == objecttag,
issametag = objtag == othtag;
if (issametag && isbuffer(object)) {
if (!isbuffer(other)) {
return false;
}
objisarr = true;
objisobj = false;
}
if (issametag && !objisobj) {
stack || (stack = new stack);
return (objisarr || istypedarray(object))
? equalarrays(object, other, bitmask, customizer, equalfunc, stack)
: equalbytag(object, other, objtag, bitmask, customizer, equalfunc, stack);
}
if (!(bitmask & compare_partial_flag)) {
var objiswrapped = objisobj && hasownproperty.call(object, '__wrapped__'),
othiswrapped = othisobj && hasownproperty.call(other, '__wrapped__');
if (objiswrapped || othiswrapped) {
var objunwrapped = objiswrapped ? object.value() : object,
othunwrapped = othiswrapped ? other.value() : other;
stack || (stack = new stack);
return equalfunc(objunwrapped, othunwrapped, bitmask, customizer, stack);
}
}
if (!issametag) {
return false;
}
stack || (stack = new stack);
return equalobjects(object, other, bitmask, customizer, equalfunc, stack);
}
/**
* the base implementation of `_.ismap` without node.js optimizations.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a map, else `false`.
*/
function baseismap(value) {
return isobjectlike(value) && gettag(value) == maptag;
}
/**
* the base implementation of `_.ismatch` without support for iteratee shorthands.
*
* @private
* @param {object} object the object to inspect.
* @param {object} source the object of property values to match.
* @param {array} matchdata the property names, values, and compare flags to match.
* @param {function} [customizer] the function to customize comparisons.
* @returns {boolean} returns `true` if `object` is a match, else `false`.
*/
function baseismatch(object, source, matchdata, customizer) {
var index = matchdata.length,
length = index,
nocustomizer = !customizer;
if (object == null) {
return !length;
}
object = object(object);
while (index--) {
var data = matchdata[index];
if ((nocustomizer && data[2])
? data[1] !== object[data[0]]
: !(data[0] in object)
) {
return false;
}
}
while (++index < length) {
data = matchdata[index];
var key = data[0],
objvalue = object[key],
srcvalue = data[1];
if (nocustomizer && data[2]) {
if (objvalue === undefined && !(key in object)) {
return false;
}
} else {
var stack = new stack;
if (customizer) {
var result = customizer(objvalue, srcvalue, key, object, source, stack);
}
if (!(result === undefined
? baseisequal(srcvalue, objvalue, compare_partial_flag | compare_unordered_flag, customizer, stack)
: result
)) {
return false;
}
}
}
return true;
}
/**
* the base implementation of `_.isnative` without bad shim checks.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a native function,
* else `false`.
*/
function baseisnative(value) {
if (!isobject(value) || ismasked(value)) {
return false;
}
var pattern = isfunction(value) ? reisnative : reishostctor;
return pattern.test(tosource(value));
}
/**
* the base implementation of `_.isregexp` without node.js optimizations.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a regexp, else `false`.
*/
function baseisregexp(value) {
return isobjectlike(value) && basegettag(value) == regexptag;
}
/**
* the base implementation of `_.isset` without node.js optimizations.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a set, else `false`.
*/
function baseisset(value) {
return isobjectlike(value) && gettag(value) == settag;
}
/**
* the base implementation of `_.istypedarray` without node.js optimizations.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a typed array, else `false`.
*/
function baseistypedarray(value) {
return isobjectlike(value) &&
islength(value.length) && !!typedarraytags[basegettag(value)];
}
/**
* the base implementation of `_.iteratee`.
*
* @private
* @param {*} [value=_.identity] the value to convert to an iteratee.
* @returns {function} returns the iteratee.
*/
function baseiteratee(value) {
// don't store the `typeof` result in a variable to avoid a jit bug in safari 9.
// see https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
if (typeof value == 'function') {
return value;
}
if (value == null) {
return identity;
}
if (typeof value == 'object') {
return isarray(value)
? basematchesproperty(value[0], value[1])
: basematches(value);
}
return property(value);
}
/**
* the base implementation of `_.keys` which doesn't treat sparse arrays as dense.
*
* @private
* @param {object} object the object to query.
* @returns {array} returns the array of property names.
*/
function basekeys(object) {
if (!isprototype(object)) {
return nativekeys(object);
}
var result = [];
for (var key in object(object)) {
if (hasownproperty.call(object, key) && key != 'constructor') {
result.push(key);
}
}
return result;
}
/**
* the base implementation of `_.keysin` which doesn't treat sparse arrays as dense.
*
* @private
* @param {object} object the object to query.
* @returns {array} returns the array of property names.
*/
function basekeysin(object) {
if (!isobject(object)) {
return nativekeysin(object);
}
var isproto = isprototype(object),
result = [];
for (var key in object) {
if (!(key == 'constructor' && (isproto || !hasownproperty.call(object, key)))) {
result.push(key);
}
}
return result;
}
/**
* the base implementation of `_.lt` which doesn't coerce arguments.
*
* @private
* @param {*} value the value to compare.
* @param {*} other the other value to compare.
* @returns {boolean} returns `true` if `value` is less than `other`,
* else `false`.
*/
function baselt(value, other) {
return value < other;
}
/**
* the base implementation of `_.map` without support for iteratee shorthands.
*
* @private
* @param {array|object} collection the collection to iterate over.
* @param {function} iteratee the function invoked per iteration.
* @returns {array} returns the new mapped array.
*/
function basemap(collection, iteratee) {
var index = -1,
result = isarraylike(collection) ? array(collection.length) : [];
baseeach(collection, function(value, key, collection) {
result[++index] = iteratee(value, key, collection);
});
return result;
}
/**
* the base implementation of `_.matches` which doesn't clone `source`.
*
* @private
* @param {object} source the object of property values to match.
* @returns {function} returns the new spec function.
*/
function basematches(source) {
var matchdata = getmatchdata(source);
if (matchdata.length == 1 && matchdata[0][2]) {
return matchesstrictcomparable(matchdata[0][0], matchdata[0][1]);
}
return function(object) {
return object === source || baseismatch(object, source, matchdata);
};
}
/**
* the base implementation of `_.matchesproperty` which doesn't clone `srcvalue`.
*
* @private
* @param {string} path the path of the property to get.
* @param {*} srcvalue the value to match.
* @returns {function} returns the new spec function.
*/
function basematchesproperty(path, srcvalue) {
if (iskey(path) && isstrictcomparable(srcvalue)) {
return matchesstrictcomparable(tokey(path), srcvalue);
}
return function(object) {
var objvalue = get(object, path);
return (objvalue === undefined && objvalue === srcvalue)
? hasin(object, path)
: baseisequal(srcvalue, objvalue, compare_partial_flag | compare_unordered_flag);
};
}
/**
* the base implementation of `_.merge` without support for multiple sources.
*
* @private
* @param {object} object the destination object.
* @param {object} source the source object.
* @param {number} srcindex the index of `source`.
* @param {function} [customizer] the function to customize merged values.
* @param {object} [stack] tracks traversed source values and their merged
* counterparts.
*/
function basemerge(object, source, srcindex, customizer, stack) {
if (object === source) {
return;
}
basefor(source, function(srcvalue, key) {
stack || (stack = new stack);
if (isobject(srcvalue)) {
basemergedeep(object, source, key, srcindex, basemerge, customizer, stack);
}
else {
var newvalue = customizer
? customizer(safeget(object, key), srcvalue, (key + ''), object, source, stack)
: undefined;
if (newvalue === undefined) {
newvalue = srcvalue;
}
assignmergevalue(object, key, newvalue);
}
}, keysin);
}
/**
* a specialized version of `basemerge` for arrays and objects which performs
* deep merges and tracks traversed objects enabling objects with circular
* references to be merged.
*
* @private
* @param {object} object the destination object.
* @param {object} source the source object.
* @param {string} key the key of the value to merge.
* @param {number} srcindex the index of `source`.
* @param {function} mergefunc the function to merge values.
* @param {function} [customizer] the function to customize assigned values.
* @param {object} [stack] tracks traversed source values and their merged
* counterparts.
*/
function basemergedeep(object, source, key, srcindex, mergefunc, customizer, stack) {
var objvalue = safeget(object, key),
srcvalue = safeget(source, key),
stacked = stack.get(srcvalue);
if (stacked) {
assignmergevalue(object, key, stacked);
return;
}
var newvalue = customizer
? customizer(objvalue, srcvalue, (key + ''), object, source, stack)
: undefined;
var iscommon = newvalue === undefined;
if (iscommon) {
var isarr = isarray(srcvalue),
isbuff = !isarr && isbuffer(srcvalue),
istyped = !isarr && !isbuff && istypedarray(srcvalue);
newvalue = srcvalue;
if (isarr || isbuff || istyped) {
if (isarray(objvalue)) {
newvalue = objvalue;
}
else if (isarraylikeobject(objvalue)) {
newvalue = copyarray(objvalue);
}
else if (isbuff) {
iscommon = false;
newvalue = clonebuffer(srcvalue, true);
}
else if (istyped) {
iscommon = false;
newvalue = clonetypedarray(srcvalue, true);
}
else {
newvalue = [];
}
}
else if (isplainobject(srcvalue) || isarguments(srcvalue)) {
newvalue = objvalue;
if (isarguments(objvalue)) {
newvalue = toplainobject(objvalue);
}
else if (!isobject(objvalue) || isfunction(objvalue)) {
newvalue = initcloneobject(srcvalue);
}
}
else {
iscommon = false;
}
}
if (iscommon) {
// recursively merge objects and arrays (susceptible to call stack limits).
stack.set(srcvalue, newvalue);
mergefunc(newvalue, srcvalue, srcindex, customizer, stack);
stack['delete'](srcvalue);
}
assignmergevalue(object, key, newvalue);
}
/**
* the base implementation of `_.nth` which doesn't coerce arguments.
*
* @private
* @param {array} array the array to query.
* @param {number} n the index of the element to return.
* @returns {*} returns the nth element of `array`.
*/
function basenth(array, n) {
var length = array.length;
if (!length) {
return;
}
n += n < 0 ? length : 0;
return isindex(n, length) ? array[n] : undefined;
}
/**
* the base implementation of `_.orderby` without param guards.
*
* @private
* @param {array|object} collection the collection to iterate over.
* @param {function[]|object[]|string[]} iteratees the iteratees to sort by.
* @param {string[]} orders the sort orders of `iteratees`.
* @returns {array} returns the new sorted array.
*/
function baseorderby(collection, iteratees, orders) {
if (iteratees.length) {
iteratees = arraymap(iteratees, function(iteratee) {
if (isarray(iteratee)) {
return function(value) {
return baseget(value, iteratee.length === 1 ? iteratee[0] : iteratee);
}
}
return iteratee;
});
} else {
iteratees = [identity];
}
var index = -1;
iteratees = arraymap(iteratees, baseunary(getiteratee()));
var result = basemap(collection, function(value, key, collection) {
var criteria = arraymap(iteratees, function(iteratee) {
return iteratee(value);
});
return { 'criteria': criteria, 'index': ++index, 'value': value };
});
return basesortby(result, function(object, other) {
return comparemultiple(object, other, orders);
});
}
/**
* the base implementation of `_.pick` without support for individual
* property identifiers.
*
* @private
* @param {object} object the source object.
* @param {string[]} paths the property paths to pick.
* @returns {object} returns the new object.
*/
function basepick(object, paths) {
return basepickby(object, paths, function(value, path) {
return hasin(object, path);
});
}
/**
* the base implementation of `_.pickby` without support for iteratee shorthands.
*
* @private
* @param {object} object the source object.
* @param {string[]} paths the property paths to pick.
* @param {function} predicate the function invoked per property.
* @returns {object} returns the new object.
*/
function basepickby(object, paths, predicate) {
var index = -1,
length = paths.length,
result = {};
while (++index < length) {
var path = paths[index],
value = baseget(object, path);
if (predicate(value, path)) {
baseset(result, castpath(path, object), value);
}
}
return result;
}
/**
* a specialized version of `baseproperty` which supports deep paths.
*
* @private
* @param {array|string} path the path of the property to get.
* @returns {function} returns the new accessor function.
*/
function basepropertydeep(path) {
return function(object) {
return baseget(object, path);
};
}
/**
* the base implementation of `_.pullallby` without support for iteratee
* shorthands.
*
* @private
* @param {array} array the array to modify.
* @param {array} values the values to remove.
* @param {function} [iteratee] the iteratee invoked per element.
* @param {function} [comparator] the comparator invoked per element.
* @returns {array} returns `array`.
*/
function basepullall(array, values, iteratee, comparator) {
var indexof = comparator ? baseindexofwith : baseindexof,
index = -1,
length = values.length,
seen = array;
if (array === values) {
values = copyarray(values);
}
if (iteratee) {
seen = arraymap(array, baseunary(iteratee));
}
while (++index < length) {
var fromindex = 0,
value = values[index],
computed = iteratee ? iteratee(value) : value;
while ((fromindex = indexof(seen, computed, fromindex, comparator)) > -1) {
if (seen !== array) {
splice.call(seen, fromindex, 1);
}
splice.call(array, fromindex, 1);
}
}
return array;
}
/**
* the base implementation of `_.pullat` without support for individual
* indexes or capturing the removed elements.
*
* @private
* @param {array} array the array to modify.
* @param {number[]} indexes the indexes of elements to remove.
* @returns {array} returns `array`.
*/
function basepullat(array, indexes) {
var length = array ? indexes.length : 0,
lastindex = length - 1;
while (length--) {
var index = indexes[length];
if (length == lastindex || index !== previous) {
var previous = index;
if (isindex(index)) {
splice.call(array, index, 1);
} else {
baseunset(array, index);
}
}
}
return array;
}
/**
* the base implementation of `_.random` without support for returning
* floating-point numbers.
*
* @private
* @param {number} lower the lower bound.
* @param {number} upper the upper bound.
* @returns {number} returns the random number.
*/
function baserandom(lower, upper) {
return lower + nativefloor(nativerandom() * (upper - lower + 1));
}
/**
* the base implementation of `_.range` and `_.rangeright` which doesn't
* coerce arguments.
*
* @private
* @param {number} start the start of the range.
* @param {number} end the end of the range.
* @param {number} step the value to increment or decrement by.
* @param {boolean} [fromright] specify iterating from right to left.
* @returns {array} returns the range of numbers.
*/
function baserange(start, end, step, fromright) {
var index = -1,
length = nativemax(nativeceil((end - start) / (step || 1)), 0),
result = array(length);
while (length--) {
result[fromright ? length : ++index] = start;
start += step;
}
return result;
}
/**
* the base implementation of `_.repeat` which doesn't coerce arguments.
*
* @private
* @param {string} string the string to repeat.
* @param {number} n the number of times to repeat the string.
* @returns {string} returns the repeated string.
*/
function baserepeat(string, n) {
var result = '';
if (!string || n < 1 || n > max_safe_integer) {
return result;
}
// leverage the exponentiation by squaring algorithm for a faster repeat.
// see https://en.wikipedia.org/wiki/exponentiation_by_squaring for more details.
do {
if (n % 2) {
result += string;
}
n = nativefloor(n / 2);
if (n) {
string += string;
}
} while (n);
return result;
}
/**
* the base implementation of `_.rest` which doesn't validate or coerce arguments.
*
* @private
* @param {function} func the function to apply a rest parameter to.
* @param {number} [start=func.length-1] the start position of the rest parameter.
* @returns {function} returns the new function.
*/
function baserest(func, start) {
return settostring(overrest(func, start, identity), func + '');
}
/**
* the base implementation of `_.sample`.
*
* @private
* @param {array|object} collection the collection to sample.
* @returns {*} returns the random element.
*/
function basesample(collection) {
return arraysample(values(collection));
}
/**
* the base implementation of `_.samplesize` without param guards.
*
* @private
* @param {array|object} collection the collection to sample.
* @param {number} n the number of elements to sample.
* @returns {array} returns the random elements.
*/
function basesamplesize(collection, n) {
var array = values(collection);
return shuffleself(array, baseclamp(n, 0, array.length));
}
/**
* the base implementation of `_.set`.
*
* @private
* @param {object} object the object to modify.
* @param {array|string} path the path of the property to set.
* @param {*} value the value to set.
* @param {function} [customizer] the function to customize path creation.
* @returns {object} returns `object`.
*/
function baseset(object, path, value, customizer) {
if (!isobject(object)) {
return object;
}
path = castpath(path, object);
var index = -1,
length = path.length,
lastindex = length - 1,
nested = object;
while (nested != null && ++index < length) {
var key = tokey(path[index]),
newvalue = value;
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
return object;
}
if (index != lastindex) {
var objvalue = nested[key];
newvalue = customizer ? customizer(objvalue, key, nested) : undefined;
if (newvalue === undefined) {
newvalue = isobject(objvalue)
? objvalue
: (isindex(path[index + 1]) ? [] : {});
}
}
assignvalue(nested, key, newvalue);
nested = nested[key];
}
return object;
}
/**
* the base implementation of `setdata` without support for hot loop shorting.
*
* @private
* @param {function} func the function to associate metadata with.
* @param {*} data the metadata.
* @returns {function} returns `func`.
*/
var basesetdata = !metamap ? identity : function(func, data) {
metamap.set(func, data);
return func;
};
/**
* the base implementation of `settostring` without support for hot loop shorting.
*
* @private
* @param {function} func the function to modify.
* @param {function} string the `tostring` result.
* @returns {function} returns `func`.
*/
var basesettostring = !defineproperty ? identity : function(func, string) {
return defineproperty(func, 'tostring', {
'configurable': true,
'enumerable': false,
'value': constant(string),
'writable': true
});
};
/**
* the base implementation of `_.shuffle`.
*
* @private
* @param {array|object} collection the collection to shuffle.
* @returns {array} returns the new shuffled array.
*/
function baseshuffle(collection) {
return shuffleself(values(collection));
}
/**
* the base implementation of `_.slice` without an iteratee call guard.
*
* @private
* @param {array} array the array to slice.
* @param {number} [start=0] the start position.
* @param {number} [end=array.length] the end position.
* @returns {array} returns the slice of `array`.
*/
function baseslice(array, start, end) {
var index = -1,
length = array.length;
if (start < 0) {
start = -start > length ? 0 : (length + start);
}
end = end > length ? length : end;
if (end < 0) {
end += length;
}
length = start > end ? 0 : ((end - start) >>> 0);
start >>>= 0;
var result = array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
/**
* the base implementation of `_.some` without support for iteratee shorthands.
*
* @private
* @param {array|object} collection the collection to iterate over.
* @param {function} predicate the function invoked per iteration.
* @returns {boolean} returns `true` if any element passes the predicate check,
* else `false`.
*/
function basesome(collection, predicate) {
var result;
baseeach(collection, function(value, index, collection) {
result = predicate(value, index, collection);
return !result;
});
return !!result;
}
/**
* the base implementation of `_.sortedindex` and `_.sortedlastindex` which
* performs a binary search of `array` to determine the index at which `value`
* should be inserted into `array` in order to maintain its sort order.
*
* @private
* @param {array} array the sorted array to inspect.
* @param {*} value the value to evaluate.
* @param {boolean} [rethighest] specify returning the highest qualified index.
* @returns {number} returns the index at which `value` should be inserted
* into `array`.
*/
function basesortedindex(array, value, rethighest) {
var low = 0,
high = array == null ? low : array.length;
if (typeof value == 'number' && value === value && high <= half_max_array_length) {
while (low < high) {
var mid = (low + high) >>> 1,
computed = array[mid];
if (computed !== null && !issymbol(computed) &&
(rethighest ? (computed <= value) : (computed < value))) {
low = mid + 1;
} else {
high = mid;
}
}
return high;
}
return basesortedindexby(array, value, identity, rethighest);
}
/**
* the base implementation of `_.sortedindexby` and `_.sortedlastindexby`
* which invokes `iteratee` for `value` and each element of `array` to compute
* their sort ranking. the iteratee is invoked with one argument; (value).
*
* @private
* @param {array} array the sorted array to inspect.
* @param {*} value the value to evaluate.
* @param {function} iteratee the iteratee invoked per element.
* @param {boolean} [rethighest] specify returning the highest qualified index.
* @returns {number} returns the index at which `value` should be inserted
* into `array`.
*/
function basesortedindexby(array, value, iteratee, rethighest) {
var low = 0,
high = array == null ? 0 : array.length;
if (high === 0) {
return 0;
}
value = iteratee(value);
var valisnan = value !== value,
valisnull = value === null,
valissymbol = issymbol(value),
valisundefined = value === undefined;
while (low < high) {
var mid = nativefloor((low + high) / 2),
computed = iteratee(array[mid]),
othisdefined = computed !== undefined,
othisnull = computed === null,
othisreflexive = computed === computed,
othissymbol = issymbol(computed);
if (valisnan) {
var setlow = rethighest || othisreflexive;
} else if (valisundefined) {
setlow = othisreflexive && (rethighest || othisdefined);
} else if (valisnull) {
setlow = othisreflexive && othisdefined && (rethighest || !othisnull);
} else if (valissymbol) {
setlow = othisreflexive && othisdefined && !othisnull && (rethighest || !othissymbol);
} else if (othisnull || othissymbol) {
setlow = false;
} else {
setlow = rethighest ? (computed <= value) : (computed < value);
}
if (setlow) {
low = mid + 1;
} else {
high = mid;
}
}
return nativemin(high, max_array_index);
}
/**
* the base implementation of `_.sorteduniq` and `_.sorteduniqby` without
* support for iteratee shorthands.
*
* @private
* @param {array} array the array to inspect.
* @param {function} [iteratee] the iteratee invoked per element.
* @returns {array} returns the new duplicate free array.
*/
function basesorteduniq(array, iteratee) {
var index = -1,
length = array.length,
resindex = 0,
result = [];
while (++index < length) {
var value = array[index],
computed = iteratee ? iteratee(value) : value;
if (!index || !eq(computed, seen)) {
var seen = computed;
result[resindex++] = value === 0 ? 0 : value;
}
}
return result;
}
/**
* the base implementation of `_.tonumber` which doesn't ensure correct
* conversions of binary, hexadecimal, or octal string values.
*
* @private
* @param {*} value the value to process.
* @returns {number} returns the number.
*/
function basetonumber(value) {
if (typeof value == 'number') {
return value;
}
if (issymbol(value)) {
return nan;
}
return +value;
}
/**
* the base implementation of `_.tostring` which doesn't convert nullish
* values to empty strings.
*
* @private
* @param {*} value the value to process.
* @returns {string} returns the string.
*/
function basetostring(value) {
// exit early for strings to avoid a performance hit in some environments.
if (typeof value == 'string') {
return value;
}
if (isarray(value)) {
// recursively convert values (susceptible to call stack limits).
return arraymap(value, basetostring) + '';
}
if (issymbol(value)) {
return symboltostring ? symboltostring.call(value) : '';
}
var result = (value + '');
return (result == '0' && (1 / value) == -infinity) ? '-0' : result;
}
/**
* the base implementation of `_.uniqby` without support for iteratee shorthands.
*
* @private
* @param {array} array the array to inspect.
* @param {function} [iteratee] the iteratee invoked per element.
* @param {function} [comparator] the comparator invoked per element.
* @returns {array} returns the new duplicate free array.
*/
function baseuniq(array, iteratee, comparator) {
var index = -1,
includes = arrayincludes,
length = array.length,
iscommon = true,
result = [],
seen = result;
if (comparator) {
iscommon = false;
includes = arrayincludeswith;
}
else if (length >= large_array_size) {
var set = iteratee ? null : createset(array);
if (set) {
return settoarray(set);
}
iscommon = false;
includes = cachehas;
seen = new setcache;
}
else {
seen = iteratee ? [] : result;
}
outer:
while (++index < length) {
var value = array[index],
computed = iteratee ? iteratee(value) : value;
value = (comparator || value !== 0) ? value : 0;
if (iscommon && computed === computed) {
var seenindex = seen.length;
while (seenindex--) {
if (seen[seenindex] === computed) {
continue outer;
}
}
if (iteratee) {
seen.push(computed);
}
result.push(value);
}
else if (!includes(seen, computed, comparator)) {
if (seen !== result) {
seen.push(computed);
}
result.push(value);
}
}
return result;
}
/**
* the base implementation of `_.unset`.
*
* @private
* @param {object} object the object to modify.
* @param {array|string} path the property path to unset.
* @returns {boolean} returns `true` if the property is deleted, else `false`.
*/
function baseunset(object, path) {
path = castpath(path, object);
object = parent(object, path);
return object == null || delete object[tokey(last(path))];
}
/**
* the base implementation of `_.update`.
*
* @private
* @param {object} object the object to modify.
* @param {array|string} path the path of the property to update.
* @param {function} updater the function to produce the updated value.
* @param {function} [customizer] the function to customize path creation.
* @returns {object} returns `object`.
*/
function baseupdate(object, path, updater, customizer) {
return baseset(object, path, updater(baseget(object, path)), customizer);
}
/**
* the base implementation of methods like `_.dropwhile` and `_.takewhile`
* without support for iteratee shorthands.
*
* @private
* @param {array} array the array to query.
* @param {function} predicate the function invoked per iteration.
* @param {boolean} [isdrop] specify dropping elements instead of taking them.
* @param {boolean} [fromright] specify iterating from right to left.
* @returns {array} returns the slice of `array`.
*/
function basewhile(array, predicate, isdrop, fromright) {
var length = array.length,
index = fromright ? length : -1;
while ((fromright ? index-- : ++index < length) &&
predicate(array[index], index, array)) {}
return isdrop
? baseslice(array, (fromright ? 0 : index), (fromright ? index + 1 : length))
: baseslice(array, (fromright ? index + 1 : 0), (fromright ? length : index));
}
/**
* the base implementation of `wrappervalue` which returns the result of
* performing a sequence of actions on the unwrapped `value`, where each
* successive action is supplied the return value of the previous.
*
* @private
* @param {*} value the unwrapped value.
* @param {array} actions actions to perform to resolve the unwrapped value.
* @returns {*} returns the resolved value.
*/
function basewrappervalue(value, actions) {
var result = value;
if (result instanceof lazywrapper) {
result = result.value();
}
return arrayreduce(actions, function(result, action) {
return action.func.apply(action.thisarg, arraypush([result], action.args));
}, result);
}
/**
* the base implementation of methods like `_.xor`, without support for
* iteratee shorthands, that accepts an array of arrays to inspect.
*
* @private
* @param {array} arrays the arrays to inspect.
* @param {function} [iteratee] the iteratee invoked per element.
* @param {function} [comparator] the comparator invoked per element.
* @returns {array} returns the new array of values.
*/
function basexor(arrays, iteratee, comparator) {
var length = arrays.length;
if (length < 2) {
return length ? baseuniq(arrays[0]) : [];
}
var index = -1,
result = array(length);
while (++index < length) {
var array = arrays[index],
othindex = -1;
while (++othindex < length) {
if (othindex != index) {
result[index] = basedifference(result[index] || array, arrays[othindex], iteratee, comparator);
}
}
}
return baseuniq(baseflatten(result, 1), iteratee, comparator);
}
/**
* this base implementation of `_.zipobject` which assigns values using `assignfunc`.
*
* @private
* @param {array} props the property identifiers.
* @param {array} values the property values.
* @param {function} assignfunc the function to assign values.
* @returns {object} returns the new object.
*/
function basezipobject(props, values, assignfunc) {
var index = -1,
length = props.length,
valslength = values.length,
result = {};
while (++index < length) {
var value = index < valslength ? values[index] : undefined;
assignfunc(result, props[index], value);
}
return result;
}
/**
* casts `value` to an empty array if it's not an array like object.
*
* @private
* @param {*} value the value to inspect.
* @returns {array|object} returns the cast array-like object.
*/
function castarraylikeobject(value) {
return isarraylikeobject(value) ? value : [];
}
/**
* casts `value` to `identity` if it's not a function.
*
* @private
* @param {*} value the value to inspect.
* @returns {function} returns cast function.
*/
function castfunction(value) {
return typeof value == 'function' ? value : identity;
}
/**
* casts `value` to a path array if it's not one.
*
* @private
* @param {*} value the value to inspect.
* @param {object} [object] the object to query keys on.
* @returns {array} returns the cast property path array.
*/
function castpath(value, object) {
if (isarray(value)) {
return value;
}
return iskey(value, object) ? [value] : stringtopath(tostring(value));
}
/**
* a `baserest` alias which can be replaced with `identity` by module
* replacement plugins.
*
* @private
* @type {function}
* @param {function} func the function to apply a rest parameter to.
* @returns {function} returns the new function.
*/
var castrest = baserest;
/**
* casts `array` to a slice if it's needed.
*
* @private
* @param {array} array the array to inspect.
* @param {number} start the start position.
* @param {number} [end=array.length] the end position.
* @returns {array} returns the cast slice.
*/
function castslice(array, start, end) {
var length = array.length;
end = end === undefined ? length : end;
return (!start && end >= length) ? array : baseslice(array, start, end);
}
/**
* a simple wrapper around the global [`cleartimeout`](https://mdn.io/cleartimeout).
*
* @private
* @param {number|object} id the timer id or timeout object of the timer to clear.
*/
var cleartimeout = ctxcleartimeout || function(id) {
return root.cleartimeout(id);
};
/**
* creates a clone of `buffer`.
*
* @private
* @param {buffer} buffer the buffer to clone.
* @param {boolean} [isdeep] specify a deep clone.
* @returns {buffer} returns the cloned buffer.
*/
function clonebuffer(buffer, isdeep) {
if (isdeep) {
return buffer.slice();
}
var length = buffer.length,
result = allocunsafe ? allocunsafe(length) : new buffer.constructor(length);
buffer.copy(result);
return result;
}
/**
* creates a clone of `arraybuffer`.
*
* @private
* @param {arraybuffer} arraybuffer the array buffer to clone.
* @returns {arraybuffer} returns the cloned array buffer.
*/
function clonearraybuffer(arraybuffer) {
var result = new arraybuffer.constructor(arraybuffer.bytelength);
new uint8array(result).set(new uint8array(arraybuffer));
return result;
}
/**
* creates a clone of `dataview`.
*
* @private
* @param {object} dataview the data view to clone.
* @param {boolean} [isdeep] specify a deep clone.
* @returns {object} returns the cloned data view.
*/
function clonedataview(dataview, isdeep) {
var buffer = isdeep ? clonearraybuffer(dataview.buffer) : dataview.buffer;
return new dataview.constructor(buffer, dataview.byteoffset, dataview.bytelength);
}
/**
* creates a clone of `regexp`.
*
* @private
* @param {object} regexp the regexp to clone.
* @returns {object} returns the cloned regexp.
*/
function cloneregexp(regexp) {
var result = new regexp.constructor(regexp.source, reflags.exec(regexp));
result.lastindex = regexp.lastindex;
return result;
}
/**
* creates a clone of the `symbol` object.
*
* @private
* @param {object} symbol the symbol object to clone.
* @returns {object} returns the cloned symbol object.
*/
function clonesymbol(symbol) {
return symbolvalueof ? object(symbolvalueof.call(symbol)) : {};
}
/**
* creates a clone of `typedarray`.
*
* @private
* @param {object} typedarray the typed array to clone.
* @param {boolean} [isdeep] specify a deep clone.
* @returns {object} returns the cloned typed array.
*/
function clonetypedarray(typedarray, isdeep) {
var buffer = isdeep ? clonearraybuffer(typedarray.buffer) : typedarray.buffer;
return new typedarray.constructor(buffer, typedarray.byteoffset, typedarray.length);
}
/**
* compares values to sort them in ascending order.
*
* @private
* @param {*} value the value to compare.
* @param {*} other the other value to compare.
* @returns {number} returns the sort order indicator for `value`.
*/
function compareascending(value, other) {
if (value !== other) {
var valisdefined = value !== undefined,
valisnull = value === null,
valisreflexive = value === value,
valissymbol = issymbol(value);
var othisdefined = other !== undefined,
othisnull = other === null,
othisreflexive = other === other,
othissymbol = issymbol(other);
if ((!othisnull && !othissymbol && !valissymbol && value > other) ||
(valissymbol && othisdefined && othisreflexive && !othisnull && !othissymbol) ||
(valisnull && othisdefined && othisreflexive) ||
(!valisdefined && othisreflexive) ||
!valisreflexive) {
return 1;
}
if ((!valisnull && !valissymbol && !othissymbol && value < other) ||
(othissymbol && valisdefined && valisreflexive && !valisnull && !valissymbol) ||
(othisnull && valisdefined && valisreflexive) ||
(!othisdefined && valisreflexive) ||
!othisreflexive) {
return -1;
}
}
return 0;
}
/**
* used by `_.orderby` to compare multiple properties of a value to another
* and stable sort them.
*
* if `orders` is unspecified, all values are sorted in ascending order. otherwise,
* specify an order of "desc" for descending or "asc" for ascending sort order
* of corresponding values.
*
* @private
* @param {object} object the object to compare.
* @param {object} other the other object to compare.
* @param {boolean[]|string[]} orders the order to sort by for each property.
* @returns {number} returns the sort order indicator for `object`.
*/
function comparemultiple(object, other, orders) {
var index = -1,
objcriteria = object.criteria,
othcriteria = other.criteria,
length = objcriteria.length,
orderslength = orders.length;
while (++index < length) {
var result = compareascending(objcriteria[index], othcriteria[index]);
if (result) {
if (index >= orderslength) {
return result;
}
var order = orders[index];
return result * (order == 'desc' ? -1 : 1);
}
}
// fixes an `array#sort` bug in the js engine embedded in adobe applications
// that causes it, under certain circumstances, to provide the same value for
// `object` and `other`. see https://github.com/jashkenas/underscore/pull/1247
// for more details.
//
// this also ensures a stable sort in v8 and other engines.
// see https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
return object.index - other.index;
}
/**
* creates an array that is the composition of partially applied arguments,
* placeholders, and provided arguments into a single array of arguments.
*
* @private
* @param {array} args the provided arguments.
* @param {array} partials the arguments to prepend to those provided.
* @param {array} holders the `partials` placeholder indexes.
* @params {boolean} [iscurried] specify composing for a curried function.
* @returns {array} returns the new array of composed arguments.
*/
function composeargs(args, partials, holders, iscurried) {
var argsindex = -1,
argslength = args.length,
holderslength = holders.length,
leftindex = -1,
leftlength = partials.length,
rangelength = nativemax(argslength - holderslength, 0),
result = array(leftlength + rangelength),
isuncurried = !iscurried;
while (++leftindex < leftlength) {
result[leftindex] = partials[leftindex];
}
while (++argsindex < holderslength) {
if (isuncurried || argsindex < argslength) {
result[holders[argsindex]] = args[argsindex];
}
}
while (rangelength--) {
result[leftindex++] = args[argsindex++];
}
return result;
}
/**
* this function is like `composeargs` except that the arguments composition
* is tailored for `_.partialright`.
*
* @private
* @param {array} args the provided arguments.
* @param {array} partials the arguments to append to those provided.
* @param {array} holders the `partials` placeholder indexes.
* @params {boolean} [iscurried] specify composing for a curried function.
* @returns {array} returns the new array of composed arguments.
*/
function composeargsright(args, partials, holders, iscurried) {
var argsindex = -1,
argslength = args.length,
holdersindex = -1,
holderslength = holders.length,
rightindex = -1,
rightlength = partials.length,
rangelength = nativemax(argslength - holderslength, 0),
result = array(rangelength + rightlength),
isuncurried = !iscurried;
while (++argsindex < rangelength) {
result[argsindex] = args[argsindex];
}
var offset = argsindex;
while (++rightindex < rightlength) {
result[offset + rightindex] = partials[rightindex];
}
while (++holdersindex < holderslength) {
if (isuncurried || argsindex < argslength) {
result[offset + holders[holdersindex]] = args[argsindex++];
}
}
return result;
}
/**
* copies the values of `source` to `array`.
*
* @private
* @param {array} source the array to copy values from.
* @param {array} [array=[]] the array to copy values to.
* @returns {array} returns `array`.
*/
function copyarray(source, array) {
var index = -1,
length = source.length;
array || (array = array(length));
while (++index < length) {
array[index] = source[index];
}
return array;
}
/**
* copies properties of `source` to `object`.
*
* @private
* @param {object} source the object to copy properties from.
* @param {array} props the property identifiers to copy.
* @param {object} [object={}] the object to copy properties to.
* @param {function} [customizer] the function to customize copied values.
* @returns {object} returns `object`.
*/
function copyobject(source, props, object, customizer) {
var isnew = !object;
object || (object = {});
var index = -1,
length = props.length;
while (++index < length) {
var key = props[index];
var newvalue = customizer
? customizer(object[key], source[key], key, object, source)
: undefined;
if (newvalue === undefined) {
newvalue = source[key];
}
if (isnew) {
baseassignvalue(object, key, newvalue);
} else {
assignvalue(object, key, newvalue);
}
}
return object;
}
/**
* copies own symbols of `source` to `object`.
*
* @private
* @param {object} source the object to copy symbols from.
* @param {object} [object={}] the object to copy symbols to.
* @returns {object} returns `object`.
*/
function copysymbols(source, object) {
return copyobject(source, getsymbols(source), object);
}
/**
* copies own and inherited symbols of `source` to `object`.
*
* @private
* @param {object} source the object to copy symbols from.
* @param {object} [object={}] the object to copy symbols to.
* @returns {object} returns `object`.
*/
function copysymbolsin(source, object) {
return copyobject(source, getsymbolsin(source), object);
}
/**
* creates a function like `_.groupby`.
*
* @private
* @param {function} setter the function to set accumulator values.
* @param {function} [initializer] the accumulator object initializer.
* @returns {function} returns the new aggregator function.
*/
function createaggregator(setter, initializer) {
return function(collection, iteratee) {
var func = isarray(collection) ? arrayaggregator : baseaggregator,
accumulator = initializer ? initializer() : {};
return func(collection, setter, getiteratee(iteratee, 2), accumulator);
};
}
/**
* creates a function like `_.assign`.
*
* @private
* @param {function} assigner the function to assign values.
* @returns {function} returns the new assigner function.
*/
function createassigner(assigner) {
return baserest(function(object, sources) {
var index = -1,
length = sources.length,
customizer = length > 1 ? sources[length - 1] : undefined,
guard = length > 2 ? sources[2] : undefined;
customizer = (assigner.length > 3 && typeof customizer == 'function')
? (length--, customizer)
: undefined;
if (guard && isiterateecall(sources[0], sources[1], guard)) {
customizer = length < 3 ? undefined : customizer;
length = 1;
}
object = object(object);
while (++index < length) {
var source = sources[index];
if (source) {
assigner(object, source, index, customizer);
}
}
return object;
});
}
/**
* creates a `baseeach` or `baseeachright` function.
*
* @private
* @param {function} eachfunc the function to iterate over a collection.
* @param {boolean} [fromright] specify iterating from right to left.
* @returns {function} returns the new base function.
*/
function createbaseeach(eachfunc, fromright) {
return function(collection, iteratee) {
if (collection == null) {
return collection;
}
if (!isarraylike(collection)) {
return eachfunc(collection, iteratee);
}
var length = collection.length,
index = fromright ? length : -1,
iterable = object(collection);
while ((fromright ? index-- : ++index < length)) {
if (iteratee(iterable[index], index, iterable) === false) {
break;
}
}
return collection;
};
}
/**
* creates a base function for methods like `_.forin` and `_.forown`.
*
* @private
* @param {boolean} [fromright] specify iterating from right to left.
* @returns {function} returns the new base function.
*/
function createbasefor(fromright) {
return function(object, iteratee, keysfunc) {
var index = -1,
iterable = object(object),
props = keysfunc(object),
length = props.length;
while (length--) {
var key = props[fromright ? length : ++index];
if (iteratee(iterable[key], key, iterable) === false) {
break;
}
}
return object;
};
}
/**
* creates a function that wraps `func` to invoke it with the optional `this`
* binding of `thisarg`.
*
* @private
* @param {function} func the function to wrap.
* @param {number} bitmask the bitmask flags. see `createwrap` for more details.
* @param {*} [thisarg] the `this` binding of `func`.
* @returns {function} returns the new wrapped function.
*/
function createbind(func, bitmask, thisarg) {
var isbind = bitmask & wrap_bind_flag,
ctor = creatector(func);
function wrapper() {
var fn = (this && this !== root && this instanceof wrapper) ? ctor : func;
return fn.apply(isbind ? thisarg : this, arguments);
}
return wrapper;
}
/**
* creates a function like `_.lowerfirst`.
*
* @private
* @param {string} methodname the name of the `string` case method to use.
* @returns {function} returns the new case function.
*/
function createcasefirst(methodname) {
return function(string) {
string = tostring(string);
var strsymbols = hasunicode(string)
? stringtoarray(string)
: undefined;
var chr = strsymbols
? strsymbols[0]
: string.charat(0);
var trailing = strsymbols
? castslice(strsymbols, 1).join('')
: string.slice(1);
return chr[methodname]() + trailing;
};
}
/**
* creates a function like `_.camelcase`.
*
* @private
* @param {function} callback the function to combine each word.
* @returns {function} returns the new compounder function.
*/
function createcompounder(callback) {
return function(string) {
return arrayreduce(words(deburr(string).replace(reapos, '')), callback, '');
};
}
/**
* creates a function that produces an instance of `ctor` regardless of
* whether it was invoked as part of a `new` expression or by `call` or `apply`.
*
* @private
* @param {function} ctor the constructor to wrap.
* @returns {function} returns the new wrapped function.
*/
function creatector(ctor) {
return function() {
// use a `switch` statement to work with class constructors. see
// http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
// for more details.
var args = arguments;
switch (args.length) {
case 0: return new ctor;
case 1: return new ctor(args[0]);
case 2: return new ctor(args[0], args[1]);
case 3: return new ctor(args[0], args[1], args[2]);
case 4: return new ctor(args[0], args[1], args[2], args[3]);
case 5: return new ctor(args[0], args[1], args[2], args[3], args[4]);
case 6: return new ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
case 7: return new ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
}
var thisbinding = basecreate(ctor.prototype),
result = ctor.apply(thisbinding, args);
// mimic the constructor's `return` behavior.
// see https://es5.github.io/#x13.2.2 for more details.
return isobject(result) ? result : thisbinding;
};
}
/**
* creates a function that wraps `func` to enable currying.
*
* @private
* @param {function} func the function to wrap.
* @param {number} bitmask the bitmask flags. see `createwrap` for more details.
* @param {number} arity the arity of `func`.
* @returns {function} returns the new wrapped function.
*/
function createcurry(func, bitmask, arity) {
var ctor = creatector(func);
function wrapper() {
var length = arguments.length,
args = array(length),
index = length,
placeholder = getholder(wrapper);
while (index--) {
args[index] = arguments[index];
}
var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
? []
: replaceholders(args, placeholder);
length -= holders.length;
if (length < arity) {
return createrecurry(
func, bitmask, createhybrid, wrapper.placeholder, undefined,
args, holders, undefined, undefined, arity - length);
}
var fn = (this && this !== root && this instanceof wrapper) ? ctor : func;
return apply(fn, this, args);
}
return wrapper;
}
/**
* creates a `_.find` or `_.findlast` function.
*
* @private
* @param {function} findindexfunc the function to find the collection index.
* @returns {function} returns the new find function.
*/
function createfind(findindexfunc) {
return function(collection, predicate, fromindex) {
var iterable = object(collection);
if (!isarraylike(collection)) {
var iteratee = getiteratee(predicate, 3);
collection = keys(collection);
predicate = function(key) { return iteratee(iterable[key], key, iterable); };
}
var index = findindexfunc(collection, predicate, fromindex);
return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
};
}
/**
* creates a `_.flow` or `_.flowright` function.
*
* @private
* @param {boolean} [fromright] specify iterating from right to left.
* @returns {function} returns the new flow function.
*/
function createflow(fromright) {
return flatrest(function(funcs) {
var length = funcs.length,
index = length,
prereq = lodashwrapper.prototype.thru;
if (fromright) {
funcs.reverse();
}
while (index--) {
var func = funcs[index];
if (typeof func != 'function') {
throw new typeerror(func_error_text);
}
if (prereq && !wrapper && getfuncname(func) == 'wrapper') {
var wrapper = new lodashwrapper([], true);
}
}
index = wrapper ? index : length;
while (++index < length) {
func = funcs[index];
var funcname = getfuncname(func),
data = funcname == 'wrapper' ? getdata(func) : undefined;
if (data && islaziable(data[0]) &&
data[1] == (wrap_ary_flag | wrap_curry_flag | wrap_partial_flag | wrap_rearg_flag) &&
!data[4].length && data[9] == 1
) {
wrapper = wrapper[getfuncname(data[0])].apply(wrapper, data[3]);
} else {
wrapper = (func.length == 1 && islaziable(func))
? wrapper[funcname]()
: wrapper.thru(func);
}
}
return function() {
var args = arguments,
value = args[0];
if (wrapper && args.length == 1 && isarray(value)) {
return wrapper.plant(value).value();
}
var index = 0,
result = length ? funcs[index].apply(this, args) : value;
while (++index < length) {
result = funcs[index].call(this, result);
}
return result;
};
});
}
/**
* creates a function that wraps `func` to invoke it with optional `this`
* binding of `thisarg`, partial application, and currying.
*
* @private
* @param {function|string} func the function or method name to wrap.
* @param {number} bitmask the bitmask flags. see `createwrap` for more details.
* @param {*} [thisarg] the `this` binding of `func`.
* @param {array} [partials] the arguments to prepend to those provided to
* the new function.
* @param {array} [holders] the `partials` placeholder indexes.
* @param {array} [partialsright] the arguments to append to those provided
* to the new function.
* @param {array} [holdersright] the `partialsright` placeholder indexes.
* @param {array} [argpos] the argument positions of the new function.
* @param {number} [ary] the arity cap of `func`.
* @param {number} [arity] the arity of `func`.
* @returns {function} returns the new wrapped function.
*/
function createhybrid(func, bitmask, thisarg, partials, holders, partialsright, holdersright, argpos, ary, arity) {
var isary = bitmask & wrap_ary_flag,
isbind = bitmask & wrap_bind_flag,
isbindkey = bitmask & wrap_bind_key_flag,
iscurried = bitmask & (wrap_curry_flag | wrap_curry_right_flag),
isflip = bitmask & wrap_flip_flag,
ctor = isbindkey ? undefined : creatector(func);
function wrapper() {
var length = arguments.length,
args = array(length),
index = length;
while (index--) {
args[index] = arguments[index];
}
if (iscurried) {
var placeholder = getholder(wrapper),
holderscount = countholders(args, placeholder);
}
if (partials) {
args = composeargs(args, partials, holders, iscurried);
}
if (partialsright) {
args = composeargsright(args, partialsright, holdersright, iscurried);
}
length -= holderscount;
if (iscurried && length < arity) {
var newholders = replaceholders(args, placeholder);
return createrecurry(
func, bitmask, createhybrid, wrapper.placeholder, thisarg,
args, newholders, argpos, ary, arity - length
);
}
var thisbinding = isbind ? thisarg : this,
fn = isbindkey ? thisbinding[func] : func;
length = args.length;
if (argpos) {
args = reorder(args, argpos);
} else if (isflip && length > 1) {
args.reverse();
}
if (isary && ary < length) {
args.length = ary;
}
if (this && this !== root && this instanceof wrapper) {
fn = ctor || creatector(fn);
}
return fn.apply(thisbinding, args);
}
return wrapper;
}
/**
* creates a function like `_.invertby`.
*
* @private
* @param {function} setter the function to set accumulator values.
* @param {function} toiteratee the function to resolve iteratees.
* @returns {function} returns the new inverter function.
*/
function createinverter(setter, toiteratee) {
return function(object, iteratee) {
return baseinverter(object, setter, toiteratee(iteratee), {});
};
}
/**
* creates a function that performs a mathematical operation on two values.
*
* @private
* @param {function} operator the function to perform the operation.
* @param {number} [defaultvalue] the value used for `undefined` arguments.
* @returns {function} returns the new mathematical operation function.
*/
function createmathoperation(operator, defaultvalue) {
return function(value, other) {
var result;
if (value === undefined && other === undefined) {
return defaultvalue;
}
if (value !== undefined) {
result = value;
}
if (other !== undefined) {
if (result === undefined) {
return other;
}
if (typeof value == 'string' || typeof other == 'string') {
value = basetostring(value);
other = basetostring(other);
} else {
value = basetonumber(value);
other = basetonumber(other);
}
result = operator(value, other);
}
return result;
};
}
/**
* creates a function like `_.over`.
*
* @private
* @param {function} arrayfunc the function to iterate over iteratees.
* @returns {function} returns the new over function.
*/
function createover(arrayfunc) {
return flatrest(function(iteratees) {
iteratees = arraymap(iteratees, baseunary(getiteratee()));
return baserest(function(args) {
var thisarg = this;
return arrayfunc(iteratees, function(iteratee) {
return apply(iteratee, thisarg, args);
});
});
});
}
/**
* creates the padding for `string` based on `length`. the `chars` string
* is truncated if the number of characters exceeds `length`.
*
* @private
* @param {number} length the padding length.
* @param {string} [chars=' '] the string used as padding.
* @returns {string} returns the padding for `string`.
*/
function createpadding(length, chars) {
chars = chars === undefined ? ' ' : basetostring(chars);
var charslength = chars.length;
if (charslength < 2) {
return charslength ? baserepeat(chars, length) : chars;
}
var result = baserepeat(chars, nativeceil(length / stringsize(chars)));
return hasunicode(chars)
? castslice(stringtoarray(result), 0, length).join('')
: result.slice(0, length);
}
/**
* creates a function that wraps `func` to invoke it with the `this` binding
* of `thisarg` and `partials` prepended to the arguments it receives.
*
* @private
* @param {function} func the function to wrap.
* @param {number} bitmask the bitmask flags. see `createwrap` for more details.
* @param {*} thisarg the `this` binding of `func`.
* @param {array} partials the arguments to prepend to those provided to
* the new function.
* @returns {function} returns the new wrapped function.
*/
function createpartial(func, bitmask, thisarg, partials) {
var isbind = bitmask & wrap_bind_flag,
ctor = creatector(func);
function wrapper() {
var argsindex = -1,
argslength = arguments.length,
leftindex = -1,
leftlength = partials.length,
args = array(leftlength + argslength),
fn = (this && this !== root && this instanceof wrapper) ? ctor : func;
while (++leftindex < leftlength) {
args[leftindex] = partials[leftindex];
}
while (argslength--) {
args[leftindex++] = arguments[++argsindex];
}
return apply(fn, isbind ? thisarg : this, args);
}
return wrapper;
}
/**
* creates a `_.range` or `_.rangeright` function.
*
* @private
* @param {boolean} [fromright] specify iterating from right to left.
* @returns {function} returns the new range function.
*/
function createrange(fromright) {
return function(start, end, step) {
if (step && typeof step != 'number' && isiterateecall(start, end, step)) {
end = step = undefined;
}
// ensure the sign of `-0` is preserved.
start = tofinite(start);
if (end === undefined) {
end = start;
start = 0;
} else {
end = tofinite(end);
}
step = step === undefined ? (start < end ? 1 : -1) : tofinite(step);
return baserange(start, end, step, fromright);
};
}
/**
* creates a function that performs a relational operation on two values.
*
* @private
* @param {function} operator the function to perform the operation.
* @returns {function} returns the new relational operation function.
*/
function createrelationaloperation(operator) {
return function(value, other) {
if (!(typeof value == 'string' && typeof other == 'string')) {
value = tonumber(value);
other = tonumber(other);
}
return operator(value, other);
};
}
/**
* creates a function that wraps `func` to continue currying.
*
* @private
* @param {function} func the function to wrap.
* @param {number} bitmask the bitmask flags. see `createwrap` for more details.
* @param {function} wrapfunc the function to create the `func` wrapper.
* @param {*} placeholder the placeholder value.
* @param {*} [thisarg] the `this` binding of `func`.
* @param {array} [partials] the arguments to prepend to those provided to
* the new function.
* @param {array} [holders] the `partials` placeholder indexes.
* @param {array} [argpos] the argument positions of the new function.
* @param {number} [ary] the arity cap of `func`.
* @param {number} [arity] the arity of `func`.
* @returns {function} returns the new wrapped function.
*/
function createrecurry(func, bitmask, wrapfunc, placeholder, thisarg, partials, holders, argpos, ary, arity) {
var iscurry = bitmask & wrap_curry_flag,
newholders = iscurry ? holders : undefined,
newholdersright = iscurry ? undefined : holders,
newpartials = iscurry ? partials : undefined,
newpartialsright = iscurry ? undefined : partials;
bitmask |= (iscurry ? wrap_partial_flag : wrap_partial_right_flag);
bitmask &= ~(iscurry ? wrap_partial_right_flag : wrap_partial_flag);
if (!(bitmask & wrap_curry_bound_flag)) {
bitmask &= ~(wrap_bind_flag | wrap_bind_key_flag);
}
var newdata = [
func, bitmask, thisarg, newpartials, newholders, newpartialsright,
newholdersright, argpos, ary, arity
];
var result = wrapfunc.apply(undefined, newdata);
if (islaziable(func)) {
setdata(result, newdata);
}
result.placeholder = placeholder;
return setwraptostring(result, func, bitmask);
}
/**
* creates a function like `_.round`.
*
* @private
* @param {string} methodname the name of the `math` method to use when rounding.
* @returns {function} returns the new round function.
*/
function createround(methodname) {
var func = math[methodname];
return function(number, precision) {
number = tonumber(number);
precision = precision == null ? 0 : nativemin(tointeger(precision), 292);
if (precision && nativeisfinite(number)) {
// shift with exponential notation to avoid floating-point issues.
// see [mdn](https://mdn.io/round#examples) for more details.
var pair = (tostring(number) + 'e').split('e'),
value = func(pair[0] + 'e' + (+pair[1] + precision));
pair = (tostring(value) + 'e').split('e');
return +(pair[0] + 'e' + (+pair[1] - precision));
}
return func(number);
};
}
/**
* creates a set object of `values`.
*
* @private
* @param {array} values the values to add to the set.
* @returns {object} returns the new set.
*/
var createset = !(set && (1 / settoarray(new set([,-0]))[1]) == infinity) ? noop : function(values) {
return new set(values);
};
/**
* creates a `_.topairs` or `_.topairsin` function.
*
* @private
* @param {function} keysfunc the function to get the keys of a given object.
* @returns {function} returns the new pairs function.
*/
function createtopairs(keysfunc) {
return function(object) {
var tag = gettag(object);
if (tag == maptag) {
return maptoarray(object);
}
if (tag == settag) {
return settopairs(object);
}
return basetopairs(object, keysfunc(object));
};
}
/**
* creates a function that either curries or invokes `func` with optional
* `this` binding and partially applied arguments.
*
* @private
* @param {function|string} func the function or method name to wrap.
* @param {number} bitmask the bitmask flags.
* 1 - `_.bind`
* 2 - `_.bindkey`
* 4 - `_.curry` or `_.curryright` of a bound function
* 8 - `_.curry`
* 16 - `_.curryright`
* 32 - `_.partial`
* 64 - `_.partialright`
* 128 - `_.rearg`
* 256 - `_.ary`
* 512 - `_.flip`
* @param {*} [thisarg] the `this` binding of `func`.
* @param {array} [partials] the arguments to be partially applied.
* @param {array} [holders] the `partials` placeholder indexes.
* @param {array} [argpos] the argument positions of the new function.
* @param {number} [ary] the arity cap of `func`.
* @param {number} [arity] the arity of `func`.
* @returns {function} returns the new wrapped function.
*/
function createwrap(func, bitmask, thisarg, partials, holders, argpos, ary, arity) {
var isbindkey = bitmask & wrap_bind_key_flag;
if (!isbindkey && typeof func != 'function') {
throw new typeerror(func_error_text);
}
var length = partials ? partials.length : 0;
if (!length) {
bitmask &= ~(wrap_partial_flag | wrap_partial_right_flag);
partials = holders = undefined;
}
ary = ary === undefined ? ary : nativemax(tointeger(ary), 0);
arity = arity === undefined ? arity : tointeger(arity);
length -= holders ? holders.length : 0;
if (bitmask & wrap_partial_right_flag) {
var partialsright = partials,
holdersright = holders;
partials = holders = undefined;
}
var data = isbindkey ? undefined : getdata(func);
var newdata = [
func, bitmask, thisarg, partials, holders, partialsright, holdersright,
argpos, ary, arity
];
if (data) {
mergedata(newdata, data);
}
func = newdata[0];
bitmask = newdata[1];
thisarg = newdata[2];
partials = newdata[3];
holders = newdata[4];
arity = newdata[9] = newdata[9] === undefined
? (isbindkey ? 0 : func.length)
: nativemax(newdata[9] - length, 0);
if (!arity && bitmask & (wrap_curry_flag | wrap_curry_right_flag)) {
bitmask &= ~(wrap_curry_flag | wrap_curry_right_flag);
}
if (!bitmask || bitmask == wrap_bind_flag) {
var result = createbind(func, bitmask, thisarg);
} else if (bitmask == wrap_curry_flag || bitmask == wrap_curry_right_flag) {
result = createcurry(func, bitmask, arity);
} else if ((bitmask == wrap_partial_flag || bitmask == (wrap_bind_flag | wrap_partial_flag)) && !holders.length) {
result = createpartial(func, bitmask, thisarg, partials);
} else {
result = createhybrid.apply(undefined, newdata);
}
var setter = data ? basesetdata : setdata;
return setwraptostring(setter(result, newdata), func, bitmask);
}
/**
* used by `_.defaults` to customize its `_.assignin` use to assign properties
* of source objects to the destination object for all destination properties
* that resolve to `undefined`.
*
* @private
* @param {*} objvalue the destination value.
* @param {*} srcvalue the source value.
* @param {string} key the key of the property to assign.
* @param {object} object the parent object of `objvalue`.
* @returns {*} returns the value to assign.
*/
function customdefaultsassignin(objvalue, srcvalue, key, object) {
if (objvalue === undefined ||
(eq(objvalue, objectproto[key]) && !hasownproperty.call(object, key))) {
return srcvalue;
}
return objvalue;
}
/**
* used by `_.defaultsdeep` to customize its `_.merge` use to merge source
* objects into destination objects that are passed thru.
*
* @private
* @param {*} objvalue the destination value.
* @param {*} srcvalue the source value.
* @param {string} key the key of the property to merge.
* @param {object} object the parent object of `objvalue`.
* @param {object} source the parent object of `srcvalue`.
* @param {object} [stack] tracks traversed source values and their merged
* counterparts.
* @returns {*} returns the value to assign.
*/
function customdefaultsmerge(objvalue, srcvalue, key, object, source, stack) {
if (isobject(objvalue) && isobject(srcvalue)) {
// recursively merge objects and arrays (susceptible to call stack limits).
stack.set(srcvalue, objvalue);
basemerge(objvalue, srcvalue, undefined, customdefaultsmerge, stack);
stack['delete'](srcvalue);
}
return objvalue;
}
/**
* used by `_.omit` to customize its `_.clonedeep` use to only clone plain
* objects.
*
* @private
* @param {*} value the value to inspect.
* @param {string} key the key of the property to inspect.
* @returns {*} returns the uncloned value or `undefined` to defer cloning to `_.clonedeep`.
*/
function customomitclone(value) {
return isplainobject(value) ? undefined : value;
}
/**
* a specialized version of `baseisequaldeep` for arrays with support for
* partial deep comparisons.
*
* @private
* @param {array} array the array to compare.
* @param {array} other the other array to compare.
* @param {number} bitmask the bitmask flags. see `baseisequal` for more details.
* @param {function} customizer the function to customize comparisons.
* @param {function} equalfunc the function to determine equivalents of values.
* @param {object} stack tracks traversed `array` and `other` objects.
* @returns {boolean} returns `true` if the arrays are equivalent, else `false`.
*/
function equalarrays(array, other, bitmask, customizer, equalfunc, stack) {
var ispartial = bitmask & compare_partial_flag,
arrlength = array.length,
othlength = other.length;
if (arrlength != othlength && !(ispartial && othlength > arrlength)) {
return false;
}
// check that cyclic values are equal.
var arrstacked = stack.get(array);
var othstacked = stack.get(other);
if (arrstacked && othstacked) {
return arrstacked == other && othstacked == array;
}
var index = -1,
result = true,
seen = (bitmask & compare_unordered_flag) ? new setcache : undefined;
stack.set(array, other);
stack.set(other, array);
// ignore non-index properties.
while (++index < arrlength) {
var arrvalue = array[index],
othvalue = other[index];
if (customizer) {
var compared = ispartial
? customizer(othvalue, arrvalue, index, other, array, stack)
: customizer(arrvalue, othvalue, index, array, other, stack);
}
if (compared !== undefined) {
if (compared) {
continue;
}
result = false;
break;
}
// recursively compare arrays (susceptible to call stack limits).
if (seen) {
if (!arraysome(other, function(othvalue, othindex) {
if (!cachehas(seen, othindex) &&
(arrvalue === othvalue || equalfunc(arrvalue, othvalue, bitmask, customizer, stack))) {
return seen.push(othindex);
}
})) {
result = false;
break;
}
} else if (!(
arrvalue === othvalue ||
equalfunc(arrvalue, othvalue, bitmask, customizer, stack)
)) {
result = false;
break;
}
}
stack['delete'](array);
stack['delete'](other);
return result;
}
/**
* a specialized version of `baseisequaldeep` for comparing objects of
* the same `tostringtag`.
*
* **note:** this function only supports comparing values with tags of
* `boolean`, `date`, `error`, `number`, `regexp`, or `string`.
*
* @private
* @param {object} object the object to compare.
* @param {object} other the other object to compare.
* @param {string} tag the `tostringtag` of the objects to compare.
* @param {number} bitmask the bitmask flags. see `baseisequal` for more details.
* @param {function} customizer the function to customize comparisons.
* @param {function} equalfunc the function to determine equivalents of values.
* @param {object} stack tracks traversed `object` and `other` objects.
* @returns {boolean} returns `true` if the objects are equivalent, else `false`.
*/
function equalbytag(object, other, tag, bitmask, customizer, equalfunc, stack) {
switch (tag) {
case dataviewtag:
if ((object.bytelength != other.bytelength) ||
(object.byteoffset != other.byteoffset)) {
return false;
}
object = object.buffer;
other = other.buffer;
case arraybuffertag:
if ((object.bytelength != other.bytelength) ||
!equalfunc(new uint8array(object), new uint8array(other))) {
return false;
}
return true;
case booltag:
case datetag:
case numbertag:
// coerce booleans to `1` or `0` and dates to milliseconds.
// invalid dates are coerced to `nan`.
return eq(+object, +other);
case errortag:
return object.name == other.name && object.message == other.message;
case regexptag:
case stringtag:
// coerce regexes to strings and treat strings, primitives and objects,
// as equal. see http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
// for more details.
return object == (other + '');
case maptag:
var convert = maptoarray;
case settag:
var ispartial = bitmask & compare_partial_flag;
convert || (convert = settoarray);
if (object.size != other.size && !ispartial) {
return false;
}
// assume cyclic values are equal.
var stacked = stack.get(object);
if (stacked) {
return stacked == other;
}
bitmask |= compare_unordered_flag;
// recursively compare objects (susceptible to call stack limits).
stack.set(object, other);
var result = equalarrays(convert(object), convert(other), bitmask, customizer, equalfunc, stack);
stack['delete'](object);
return result;
case symboltag:
if (symbolvalueof) {
return symbolvalueof.call(object) == symbolvalueof.call(other);
}
}
return false;
}
/**
* a specialized version of `baseisequaldeep` for objects with support for
* partial deep comparisons.
*
* @private
* @param {object} object the object to compare.
* @param {object} other the other object to compare.
* @param {number} bitmask the bitmask flags. see `baseisequal` for more details.
* @param {function} customizer the function to customize comparisons.
* @param {function} equalfunc the function to determine equivalents of values.
* @param {object} stack tracks traversed `object` and `other` objects.
* @returns {boolean} returns `true` if the objects are equivalent, else `false`.
*/
function equalobjects(object, other, bitmask, customizer, equalfunc, stack) {
var ispartial = bitmask & compare_partial_flag,
objprops = getallkeys(object),
objlength = objprops.length,
othprops = getallkeys(other),
othlength = othprops.length;
if (objlength != othlength && !ispartial) {
return false;
}
var index = objlength;
while (index--) {
var key = objprops[index];
if (!(ispartial ? key in other : hasownproperty.call(other, key))) {
return false;
}
}
// check that cyclic values are equal.
var objstacked = stack.get(object);
var othstacked = stack.get(other);
if (objstacked && othstacked) {
return objstacked == other && othstacked == object;
}
var result = true;
stack.set(object, other);
stack.set(other, object);
var skipctor = ispartial;
while (++index < objlength) {
key = objprops[index];
var objvalue = object[key],
othvalue = other[key];
if (customizer) {
var compared = ispartial
? customizer(othvalue, objvalue, key, other, object, stack)
: customizer(objvalue, othvalue, key, object, other, stack);
}
// recursively compare objects (susceptible to call stack limits).
if (!(compared === undefined
? (objvalue === othvalue || equalfunc(objvalue, othvalue, bitmask, customizer, stack))
: compared
)) {
result = false;
break;
}
skipctor || (skipctor = key == 'constructor');
}
if (result && !skipctor) {
var objctor = object.constructor,
othctor = other.constructor;
// non `object` object instances with different constructors are not equal.
if (objctor != othctor &&
('constructor' in object && 'constructor' in other) &&
!(typeof objctor == 'function' && objctor instanceof objctor &&
typeof othctor == 'function' && othctor instanceof othctor)) {
result = false;
}
}
stack['delete'](object);
stack['delete'](other);
return result;
}
/**
* a specialized version of `baserest` which flattens the rest array.
*
* @private
* @param {function} func the function to apply a rest parameter to.
* @returns {function} returns the new function.
*/
function flatrest(func) {
return settostring(overrest(func, undefined, flatten), func + '');
}
/**
* creates an array of own enumerable property names and symbols of `object`.
*
* @private
* @param {object} object the object to query.
* @returns {array} returns the array of property names and symbols.
*/
function getallkeys(object) {
return basegetallkeys(object, keys, getsymbols);
}
/**
* creates an array of own and inherited enumerable property names and
* symbols of `object`.
*
* @private
* @param {object} object the object to query.
* @returns {array} returns the array of property names and symbols.
*/
function getallkeysin(object) {
return basegetallkeys(object, keysin, getsymbolsin);
}
/**
* gets metadata for `func`.
*
* @private
* @param {function} func the function to query.
* @returns {*} returns the metadata for `func`.
*/
var getdata = !metamap ? noop : function(func) {
return metamap.get(func);
};
/**
* gets the name of `func`.
*
* @private
* @param {function} func the function to query.
* @returns {string} returns the function name.
*/
function getfuncname(func) {
var result = (func.name + ''),
array = realnames[result],
length = hasownproperty.call(realnames, result) ? array.length : 0;
while (length--) {
var data = array[length],
otherfunc = data.func;
if (otherfunc == null || otherfunc == func) {
return data.name;
}
}
return result;
}
/**
* gets the argument placeholder value for `func`.
*
* @private
* @param {function} func the function to inspect.
* @returns {*} returns the placeholder value.
*/
function getholder(func) {
var object = hasownproperty.call(lodash, 'placeholder') ? lodash : func;
return object.placeholder;
}
/**
* gets the appropriate "iteratee" function. if `_.iteratee` is customized,
* this function returns the custom method, otherwise it returns `baseiteratee`.
* if arguments are provided, the chosen function is invoked with them and
* its result is returned.
*
* @private
* @param {*} [value] the value to convert to an iteratee.
* @param {number} [arity] the arity of the created iteratee.
* @returns {function} returns the chosen function or its result.
*/
function getiteratee() {
var result = lodash.iteratee || iteratee;
result = result === iteratee ? baseiteratee : result;
return arguments.length ? result(arguments[0], arguments[1]) : result;
}
/**
* gets the data for `map`.
*
* @private
* @param {object} map the map to query.
* @param {string} key the reference key.
* @returns {*} returns the map data.
*/
function getmapdata(map, key) {
var data = map.__data__;
return iskeyable(key)
? data[typeof key == 'string' ? 'string' : 'hash']
: data.map;
}
/**
* gets the property names, values, and compare flags of `object`.
*
* @private
* @param {object} object the object to query.
* @returns {array} returns the match data of `object`.
*/
function getmatchdata(object) {
var result = keys(object),
length = result.length;
while (length--) {
var key = result[length],
value = object[key];
result[length] = [key, value, isstrictcomparable(value)];
}
return result;
}
/**
* gets the native function at `key` of `object`.
*
* @private
* @param {object} object the object to query.
* @param {string} key the key of the method to get.
* @returns {*} returns the function if it's native, else `undefined`.
*/
function getnative(object, key) {
var value = getvalue(object, key);
return baseisnative(value) ? value : undefined;
}
/**
* a specialized version of `basegettag` which ignores `symbol.tostringtag` values.
*
* @private
* @param {*} value the value to query.
* @returns {string} returns the raw `tostringtag`.
*/
function getrawtag(value) {
var isown = hasownproperty.call(value, symtostringtag),
tag = value[symtostringtag];
try {
value[symtostringtag] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeobjecttostring.call(value);
if (unmasked) {
if (isown) {
value[symtostringtag] = tag;
} else {
delete value[symtostringtag];
}
}
return result;
}
/**
* creates an array of the own enumerable symbols of `object`.
*
* @private
* @param {object} object the object to query.
* @returns {array} returns the array of symbols.
*/
var getsymbols = !nativegetsymbols ? stubarray : function(object) {
if (object == null) {
return [];
}
object = object(object);
return arrayfilter(nativegetsymbols(object), function(symbol) {
return propertyisenumerable.call(object, symbol);
});
};
/**
* creates an array of the own and inherited enumerable symbols of `object`.
*
* @private
* @param {object} object the object to query.
* @returns {array} returns the array of symbols.
*/
var getsymbolsin = !nativegetsymbols ? stubarray : function(object) {
var result = [];
while (object) {
arraypush(result, getsymbols(object));
object = getprototype(object);
}
return result;
};
/**
* gets the `tostringtag` of `value`.
*
* @private
* @param {*} value the value to query.
* @returns {string} returns the `tostringtag`.
*/
var gettag = basegettag;
// fallback for data views, maps, sets, and weak maps in ie 11 and promises in node.js < 6.
if ((dataview && gettag(new dataview(new arraybuffer(1))) != dataviewtag) ||
(map && gettag(new map) != maptag) ||
(promise && gettag(promise.resolve()) != promisetag) ||
(set && gettag(new set) != settag) ||
(weakmap && gettag(new weakmap) != weakmaptag)) {
gettag = function(value) {
var result = basegettag(value),
ctor = result == objecttag ? value.constructor : undefined,
ctorstring = ctor ? tosource(ctor) : '';
if (ctorstring) {
switch (ctorstring) {
case dataviewctorstring: return dataviewtag;
case mapctorstring: return maptag;
case promisectorstring: return promisetag;
case setctorstring: return settag;
case weakmapctorstring: return weakmaptag;
}
}
return result;
};
}
/**
* gets the view, applying any `transforms` to the `start` and `end` positions.
*
* @private
* @param {number} start the start of the view.
* @param {number} end the end of the view.
* @param {array} transforms the transformations to apply to the view.
* @returns {object} returns an object containing the `start` and `end`
* positions of the view.
*/
function getview(start, end, transforms) {
var index = -1,
length = transforms.length;
while (++index < length) {
var data = transforms[index],
size = data.size;
switch (data.type) {
case 'drop': start += size; break;
case 'dropright': end -= size; break;
case 'take': end = nativemin(end, start + size); break;
case 'takeright': start = nativemax(start, end - size); break;
}
}
return { 'start': start, 'end': end };
}
/**
* extracts wrapper details from the `source` body comment.
*
* @private
* @param {string} source the source to inspect.
* @returns {array} returns the wrapper details.
*/
function getwrapdetails(source) {
var match = source.match(rewrapdetails);
return match ? match[1].split(resplitdetails) : [];
}
/**
* checks if `path` exists on `object`.
*
* @private
* @param {object} object the object to query.
* @param {array|string} path the path to check.
* @param {function} hasfunc the function to check properties.
* @returns {boolean} returns `true` if `path` exists, else `false`.
*/
function haspath(object, path, hasfunc) {
path = castpath(path, object);
var index = -1,
length = path.length,
result = false;
while (++index < length) {
var key = tokey(path[index]);
if (!(result = object != null && hasfunc(object, key))) {
break;
}
object = object[key];
}
if (result || ++index != length) {
return result;
}
length = object == null ? 0 : object.length;
return !!length && islength(length) && isindex(key, length) &&
(isarray(object) || isarguments(object));
}
/**
* initializes an array clone.
*
* @private
* @param {array} array the array to clone.
* @returns {array} returns the initialized clone.
*/
function initclonearray(array) {
var length = array.length,
result = new array.constructor(length);
// add properties assigned by `regexp#exec`.
if (length && typeof array[0] == 'string' && hasownproperty.call(array, 'index')) {
result.index = array.index;
result.input = array.input;
}
return result;
}
/**
* initializes an object clone.
*
* @private
* @param {object} object the object to clone.
* @returns {object} returns the initialized clone.
*/
function initcloneobject(object) {
return (typeof object.constructor == 'function' && !isprototype(object))
? basecreate(getprototype(object))
: {};
}
/**
* initializes an object clone based on its `tostringtag`.
*
* **note:** this function only supports cloning values with tags of
* `boolean`, `date`, `error`, `map`, `number`, `regexp`, `set`, or `string`.
*
* @private
* @param {object} object the object to clone.
* @param {string} tag the `tostringtag` of the object to clone.
* @param {boolean} [isdeep] specify a deep clone.
* @returns {object} returns the initialized clone.
*/
function initclonebytag(object, tag, isdeep) {
var ctor = object.constructor;
switch (tag) {
case arraybuffertag:
return clonearraybuffer(object);
case booltag:
case datetag:
return new ctor(+object);
case dataviewtag:
return clonedataview(object, isdeep);
case float32tag: case float64tag:
case int8tag: case int16tag: case int32tag:
case uint8tag: case uint8clampedtag: case uint16tag: case uint32tag:
return clonetypedarray(object, isdeep);
case maptag:
return new ctor;
case numbertag:
case stringtag:
return new ctor(object);
case regexptag:
return cloneregexp(object);
case settag:
return new ctor;
case symboltag:
return clonesymbol(object);
}
}
/**
* inserts wrapper `details` in a comment at the top of the `source` body.
*
* @private
* @param {string} source the source to modify.
* @returns {array} details the details to insert.
* @returns {string} returns the modified source.
*/
function insertwrapdetails(source, details) {
var length = details.length;
if (!length) {
return source;
}
var lastindex = length - 1;
details[lastindex] = (length > 1 ? '& ' : '') + details[lastindex];
details = details.join(length > 2 ? ', ' : ' ');
return source.replace(rewrapcomment, '{\n/* [wrapped with ' + details + '] */\n');
}
/**
* checks if `value` is a flattenable `arguments` object or array.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is flattenable, else `false`.
*/
function isflattenable(value) {
return isarray(value) || isarguments(value) ||
!!(spreadablesymbol && value && value[spreadablesymbol]);
}
/**
* checks if `value` is a valid array-like index.
*
* @private
* @param {*} value the value to check.
* @param {number} [length=max_safe_integer] the upper bounds of a valid index.
* @returns {boolean} returns `true` if `value` is a valid index, else `false`.
*/
function isindex(value, length) {
var type = typeof value;
length = length == null ? max_safe_integer : length;
return !!length &&
(type == 'number' ||
(type != 'symbol' && reisuint.test(value))) &&
(value > -1 && value % 1 == 0 && value < length);
}
/**
* checks if the given arguments are from an iteratee call.
*
* @private
* @param {*} value the potential iteratee value argument.
* @param {*} index the potential iteratee index or key argument.
* @param {*} object the potential iteratee object argument.
* @returns {boolean} returns `true` if the arguments are from an iteratee call,
* else `false`.
*/
function isiterateecall(value, index, object) {
if (!isobject(object)) {
return false;
}
var type = typeof index;
if (type == 'number'
? (isarraylike(object) && isindex(index, object.length))
: (type == 'string' && index in object)
) {
return eq(object[index], value);
}
return false;
}
/**
* checks if `value` is a property name and not a property path.
*
* @private
* @param {*} value the value to check.
* @param {object} [object] the object to query keys on.
* @returns {boolean} returns `true` if `value` is a property name, else `false`.
*/
function iskey(value, object) {
if (isarray(value)) {
return false;
}
var type = typeof value;
if (type == 'number' || type == 'symbol' || type == 'boolean' ||
value == null || issymbol(value)) {
return true;
}
return reisplainprop.test(value) || !reisdeepprop.test(value) ||
(object != null && value in object(object));
}
/**
* checks if `value` is suitable for use as unique object key.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is suitable, else `false`.
*/
function iskeyable(value) {
var type = typeof value;
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
? (value !== '__proto__')
: (value === null);
}
/**
* checks if `func` has a lazy counterpart.
*
* @private
* @param {function} func the function to check.
* @returns {boolean} returns `true` if `func` has a lazy counterpart,
* else `false`.
*/
function islaziable(func) {
var funcname = getfuncname(func),
other = lodash[funcname];
if (typeof other != 'function' || !(funcname in lazywrapper.prototype)) {
return false;
}
if (func === other) {
return true;
}
var data = getdata(other);
return !!data && func === data[0];
}
/**
* checks if `func` has its source masked.
*
* @private
* @param {function} func the function to check.
* @returns {boolean} returns `true` if `func` is masked, else `false`.
*/
function ismasked(func) {
return !!masksrckey && (masksrckey in func);
}
/**
* checks if `func` is capable of being masked.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `func` is maskable, else `false`.
*/
var ismaskable = corejsdata ? isfunction : stubfalse;
/**
* checks if `value` is likely a prototype object.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a prototype, else `false`.
*/
function isprototype(value) {
var ctor = value && value.constructor,
proto = (typeof ctor == 'function' && ctor.prototype) || objectproto;
return value === proto;
}
/**
* checks if `value` is suitable for strict equality comparisons, i.e. `===`.
*
* @private
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` if suitable for strict
* equality comparisons, else `false`.
*/
function isstrictcomparable(value) {
return value === value && !isobject(value);
}
/**
* a specialized version of `matchesproperty` for source values suitable
* for strict equality comparisons, i.e. `===`.
*
* @private
* @param {string} key the key of the property to get.
* @param {*} srcvalue the value to match.
* @returns {function} returns the new spec function.
*/
function matchesstrictcomparable(key, srcvalue) {
return function(object) {
if (object == null) {
return false;
}
return object[key] === srcvalue &&
(srcvalue !== undefined || (key in object(object)));
};
}
/**
* a specialized version of `_.memoize` which clears the memoized function's
* cache when it exceeds `max_memoize_size`.
*
* @private
* @param {function} func the function to have its output memoized.
* @returns {function} returns the new memoized function.
*/
function memoizecapped(func) {
var result = memoize(func, function(key) {
if (cache.size === max_memoize_size) {
cache.clear();
}
return key;
});
var cache = result.cache;
return result;
}
/**
* merges the function metadata of `source` into `data`.
*
* merging metadata reduces the number of wrappers used to invoke a function.
* this is possible because methods like `_.bind`, `_.curry`, and `_.partial`
* may be applied regardless of execution order. methods like `_.ary` and
* `_.rearg` modify function arguments, making the order in which they are
* executed important, preventing the merging of metadata. however, we make
* an exception for a safe combined case where curried functions have `_.ary`
* and or `_.rearg` applied.
*
* @private
* @param {array} data the destination metadata.
* @param {array} source the source metadata.
* @returns {array} returns `data`.
*/
function mergedata(data, source) {
var bitmask = data[1],
srcbitmask = source[1],
newbitmask = bitmask | srcbitmask,
iscommon = newbitmask < (wrap_bind_flag | wrap_bind_key_flag | wrap_ary_flag);
var iscombo =
((srcbitmask == wrap_ary_flag) && (bitmask == wrap_curry_flag)) ||
((srcbitmask == wrap_ary_flag) && (bitmask == wrap_rearg_flag) && (data[7].length <= source[8])) ||
((srcbitmask == (wrap_ary_flag | wrap_rearg_flag)) && (source[7].length <= source[8]) && (bitmask == wrap_curry_flag));
// exit early if metadata can't be merged.
if (!(iscommon || iscombo)) {
return data;
}
// use source `thisarg` if available.
if (srcbitmask & wrap_bind_flag) {
data[2] = source[2];
// set when currying a bound function.
newbitmask |= bitmask & wrap_bind_flag ? 0 : wrap_curry_bound_flag;
}
// compose partial arguments.
var value = source[3];
if (value) {
var partials = data[3];
data[3] = partials ? composeargs(partials, value, source[4]) : value;
data[4] = partials ? replaceholders(data[3], placeholder) : source[4];
}
// compose partial right arguments.
value = source[5];
if (value) {
partials = data[5];
data[5] = partials ? composeargsright(partials, value, source[6]) : value;
data[6] = partials ? replaceholders(data[5], placeholder) : source[6];
}
// use source `argpos` if available.
value = source[7];
if (value) {
data[7] = value;
}
// use source `ary` if it's smaller.
if (srcbitmask & wrap_ary_flag) {
data[8] = data[8] == null ? source[8] : nativemin(data[8], source[8]);
}
// use source `arity` if one is not provided.
if (data[9] == null) {
data[9] = source[9];
}
// use source `func` and merge bitmasks.
data[0] = source[0];
data[1] = newbitmask;
return data;
}
/**
* this function is like
* [`object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
* except that it includes inherited enumerable properties.
*
* @private
* @param {object} object the object to query.
* @returns {array} returns the array of property names.
*/
function nativekeysin(object) {
var result = [];
if (object != null) {
for (var key in object(object)) {
result.push(key);
}
}
return result;
}
/**
* converts `value` to a string using `object.prototype.tostring`.
*
* @private
* @param {*} value the value to convert.
* @returns {string} returns the converted string.
*/
function objecttostring(value) {
return nativeobjecttostring.call(value);
}
/**
* a specialized version of `baserest` which transforms the rest array.
*
* @private
* @param {function} func the function to apply a rest parameter to.
* @param {number} [start=func.length-1] the start position of the rest parameter.
* @param {function} transform the rest array transform.
* @returns {function} returns the new function.
*/
function overrest(func, start, transform) {
start = nativemax(start === undefined ? (func.length - 1) : start, 0);
return function() {
var args = arguments,
index = -1,
length = nativemax(args.length - start, 0),
array = array(length);
while (++index < length) {
array[index] = args[start + index];
}
index = -1;
var otherargs = array(start + 1);
while (++index < start) {
otherargs[index] = args[index];
}
otherargs[start] = transform(array);
return apply(func, this, otherargs);
};
}
/**
* gets the parent value at `path` of `object`.
*
* @private
* @param {object} object the object to query.
* @param {array} path the path to get the parent value of.
* @returns {*} returns the parent value.
*/
function parent(object, path) {
return path.length < 2 ? object : baseget(object, baseslice(path, 0, -1));
}
/**
* reorder `array` according to the specified indexes where the element at
* the first index is assigned as the first element, the element at
* the second index is assigned as the second element, and so on.
*
* @private
* @param {array} array the array to reorder.
* @param {array} indexes the arranged array indexes.
* @returns {array} returns `array`.
*/
function reorder(array, indexes) {
var arrlength = array.length,
length = nativemin(indexes.length, arrlength),
oldarray = copyarray(array);
while (length--) {
var index = indexes[length];
array[length] = isindex(index, arrlength) ? oldarray[index] : undefined;
}
return array;
}
/**
* gets the value at `key`, unless `key` is "__proto__" or "constructor".
*
* @private
* @param {object} object the object to query.
* @param {string} key the key of the property to get.
* @returns {*} returns the property value.
*/
function safeget(object, key) {
if (key === 'constructor' && typeof object[key] === 'function') {
return;
}
if (key == '__proto__') {
return;
}
return object[key];
}
/**
* sets metadata for `func`.
*
* **note:** if this function becomes hot, i.e. is invoked a lot in a short
* period of time, it will trip its breaker and transition to an identity
* function to avoid garbage collection pauses in v8. see
* [v8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
* for more details.
*
* @private
* @param {function} func the function to associate metadata with.
* @param {*} data the metadata.
* @returns {function} returns `func`.
*/
var setdata = shortout(basesetdata);
/**
* a simple wrapper around the global [`settimeout`](https://mdn.io/settimeout).
*
* @private
* @param {function} func the function to delay.
* @param {number} wait the number of milliseconds to delay invocation.
* @returns {number|object} returns the timer id or timeout object.
*/
var settimeout = ctxsettimeout || function(func, wait) {
return root.settimeout(func, wait);
};
/**
* sets the `tostring` method of `func` to return `string`.
*
* @private
* @param {function} func the function to modify.
* @param {function} string the `tostring` result.
* @returns {function} returns `func`.
*/
var settostring = shortout(basesettostring);
/**
* sets the `tostring` method of `wrapper` to mimic the source of `reference`
* with wrapper details in a comment at the top of the source body.
*
* @private
* @param {function} wrapper the function to modify.
* @param {function} reference the reference function.
* @param {number} bitmask the bitmask flags. see `createwrap` for more details.
* @returns {function} returns `wrapper`.
*/
function setwraptostring(wrapper, reference, bitmask) {
var source = (reference + '');
return settostring(wrapper, insertwrapdetails(source, updatewrapdetails(getwrapdetails(source), bitmask)));
}
/**
* creates a function that'll short out and invoke `identity` instead
* of `func` when it's called `hot_count` or more times in `hot_span`
* milliseconds.
*
* @private
* @param {function} func the function to restrict.
* @returns {function} returns the new shortable function.
*/
function shortout(func) {
var count = 0,
lastcalled = 0;
return function() {
var stamp = nativenow(),
remaining = hot_span - (stamp - lastcalled);
lastcalled = stamp;
if (remaining > 0) {
if (++count >= hot_count) {
return arguments[0];
}
} else {
count = 0;
}
return func.apply(undefined, arguments);
};
}
/**
* a specialized version of `_.shuffle` which mutates and sets the size of `array`.
*
* @private
* @param {array} array the array to shuffle.
* @param {number} [size=array.length] the size of `array`.
* @returns {array} returns `array`.
*/
function shuffleself(array, size) {
var index = -1,
length = array.length,
lastindex = length - 1;
size = size === undefined ? length : size;
while (++index < size) {
var rand = baserandom(index, lastindex),
value = array[rand];
array[rand] = array[index];
array[index] = value;
}
array.length = size;
return array;
}
/**
* converts `string` to a property path array.
*
* @private
* @param {string} string the string to convert.
* @returns {array} returns the property path array.
*/
var stringtopath = memoizecapped(function(string) {
var result = [];
if (string.charcodeat(0) === 46 /* . */) {
result.push('');
}
string.replace(repropname, function(match, number, quote, substring) {
result.push(quote ? substring.replace(reescapechar, '$1') : (number || match));
});
return result;
});
/**
* converts `value` to a string key if it's not a string or symbol.
*
* @private
* @param {*} value the value to inspect.
* @returns {string|symbol} returns the key.
*/
function tokey(value) {
if (typeof value == 'string' || issymbol(value)) {
return value;
}
var result = (value + '');
return (result == '0' && (1 / value) == -infinity) ? '-0' : result;
}
/**
* converts `func` to its source code.
*
* @private
* @param {function} func the function to convert.
* @returns {string} returns the source code.
*/
function tosource(func) {
if (func != null) {
try {
return functostring.call(func);
} catch (e) {}
try {
return (func + '');
} catch (e) {}
}
return '';
}
/**
* updates wrapper `details` based on `bitmask` flags.
*
* @private
* @returns {array} details the details to modify.
* @param {number} bitmask the bitmask flags. see `createwrap` for more details.
* @returns {array} returns `details`.
*/
function updatewrapdetails(details, bitmask) {
arrayeach(wrapflags, function(pair) {
var value = '_.' + pair[0];
if ((bitmask & pair[1]) && !arrayincludes(details, value)) {
details.push(value);
}
});
return details.sort();
}
/**
* creates a clone of `wrapper`.
*
* @private
* @param {object} wrapper the wrapper to clone.
* @returns {object} returns the cloned wrapper.
*/
function wrapperclone(wrapper) {
if (wrapper instanceof lazywrapper) {
return wrapper.clone();
}
var result = new lodashwrapper(wrapper.__wrapped__, wrapper.__chain__);
result.__actions__ = copyarray(wrapper.__actions__);
result.__index__ = wrapper.__index__;
result.__values__ = wrapper.__values__;
return result;
}
/*------------------------------------------------------------------------*/
/**
* creates an array of elements split into groups the length of `size`.
* if `array` can't be split evenly, the final chunk will be the remaining
* elements.
*
* @static
* @memberof _
* @since 3.0.0
* @category array
* @param {array} array the array to process.
* @param {number} [size=1] the length of each chunk
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {array} returns the new array of chunks.
* @example
*
* _.chunk(['a', 'b', 'c', 'd'], 2);
* // => [['a', 'b'], ['c', 'd']]
*
* _.chunk(['a', 'b', 'c', 'd'], 3);
* // => [['a', 'b', 'c'], ['d']]
*/
function chunk(array, size, guard) {
if ((guard ? isiterateecall(array, size, guard) : size === undefined)) {
size = 1;
} else {
size = nativemax(tointeger(size), 0);
}
var length = array == null ? 0 : array.length;
if (!length || size < 1) {
return [];
}
var index = 0,
resindex = 0,
result = array(nativeceil(length / size));
while (index < length) {
result[resindex++] = baseslice(array, index, (index += size));
}
return result;
}
/**
* creates an array with all falsey values removed. the values `false`, `null`,
* `0`, `""`, `undefined`, and `nan` are falsey.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {array} array the array to compact.
* @returns {array} returns the new array of filtered values.
* @example
*
* _.compact([0, 1, false, 2, '', 3]);
* // => [1, 2, 3]
*/
function compact(array) {
var index = -1,
length = array == null ? 0 : array.length,
resindex = 0,
result = [];
while (++index < length) {
var value = array[index];
if (value) {
result[resindex++] = value;
}
}
return result;
}
/**
* creates a new array concatenating `array` with any additional arrays
* and/or values.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to concatenate.
* @param {...*} [values] the values to concatenate.
* @returns {array} returns the new concatenated array.
* @example
*
* var array = [1];
* var other = _.concat(array, 2, [3], [[4]]);
*
* console.log(other);
* // => [1, 2, 3, [4]]
*
* console.log(array);
* // => [1]
*/
function concat() {
var length = arguments.length;
if (!length) {
return [];
}
var args = array(length - 1),
array = arguments[0],
index = length;
while (index--) {
args[index - 1] = arguments[index];
}
return arraypush(isarray(array) ? copyarray(array) : [array], baseflatten(args, 1));
}
/**
* creates an array of `array` values not included in the other given arrays
* using [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons. the order and references of result values are
* determined by the first array.
*
* **note:** unlike `_.pullall`, this method returns a new array.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {array} array the array to inspect.
* @param {...array} [values] the values to exclude.
* @returns {array} returns the new array of filtered values.
* @see _.without, _.xor
* @example
*
* _.difference([2, 1], [2, 3]);
* // => [1]
*/
var difference = baserest(function(array, values) {
return isarraylikeobject(array)
? basedifference(array, baseflatten(values, 1, isarraylikeobject, true))
: [];
});
/**
* this method is like `_.difference` except that it accepts `iteratee` which
* is invoked for each element of `array` and `values` to generate the criterion
* by which they're compared. the order and references of result values are
* determined by the first array. the iteratee is invoked with one argument:
* (value).
*
* **note:** unlike `_.pullallby`, this method returns a new array.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to inspect.
* @param {...array} [values] the values to exclude.
* @param {function} [iteratee=_.identity] the iteratee invoked per element.
* @returns {array} returns the new array of filtered values.
* @example
*
* _.differenceby([2.1, 1.2], [2.3, 3.4], math.floor);
* // => [1.2]
*
* // the `_.property` iteratee shorthand.
* _.differenceby([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
* // => [{ 'x': 2 }]
*/
var differenceby = baserest(function(array, values) {
var iteratee = last(values);
if (isarraylikeobject(iteratee)) {
iteratee = undefined;
}
return isarraylikeobject(array)
? basedifference(array, baseflatten(values, 1, isarraylikeobject, true), getiteratee(iteratee, 2))
: [];
});
/**
* this method is like `_.difference` except that it accepts `comparator`
* which is invoked to compare elements of `array` to `values`. the order and
* references of result values are determined by the first array. the comparator
* is invoked with two arguments: (arrval, othval).
*
* **note:** unlike `_.pullallwith`, this method returns a new array.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to inspect.
* @param {...array} [values] the values to exclude.
* @param {function} [comparator] the comparator invoked per element.
* @returns {array} returns the new array of filtered values.
* @example
*
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
*
* _.differencewith(objects, [{ 'x': 1, 'y': 2 }], _.isequal);
* // => [{ 'x': 2, 'y': 1 }]
*/
var differencewith = baserest(function(array, values) {
var comparator = last(values);
if (isarraylikeobject(comparator)) {
comparator = undefined;
}
return isarraylikeobject(array)
? basedifference(array, baseflatten(values, 1, isarraylikeobject, true), undefined, comparator)
: [];
});
/**
* creates a slice of `array` with `n` elements dropped from the beginning.
*
* @static
* @memberof _
* @since 0.5.0
* @category array
* @param {array} array the array to query.
* @param {number} [n=1] the number of elements to drop.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {array} returns the slice of `array`.
* @example
*
* _.drop([1, 2, 3]);
* // => [2, 3]
*
* _.drop([1, 2, 3], 2);
* // => [3]
*
* _.drop([1, 2, 3], 5);
* // => []
*
* _.drop([1, 2, 3], 0);
* // => [1, 2, 3]
*/
function drop(array, n, guard) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
n = (guard || n === undefined) ? 1 : tointeger(n);
return baseslice(array, n < 0 ? 0 : n, length);
}
/**
* creates a slice of `array` with `n` elements dropped from the end.
*
* @static
* @memberof _
* @since 3.0.0
* @category array
* @param {array} array the array to query.
* @param {number} [n=1] the number of elements to drop.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {array} returns the slice of `array`.
* @example
*
* _.dropright([1, 2, 3]);
* // => [1, 2]
*
* _.dropright([1, 2, 3], 2);
* // => [1]
*
* _.dropright([1, 2, 3], 5);
* // => []
*
* _.dropright([1, 2, 3], 0);
* // => [1, 2, 3]
*/
function dropright(array, n, guard) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
n = (guard || n === undefined) ? 1 : tointeger(n);
n = length - n;
return baseslice(array, 0, n < 0 ? 0 : n);
}
/**
* creates a slice of `array` excluding elements dropped from the end.
* elements are dropped until `predicate` returns falsey. the predicate is
* invoked with three arguments: (value, index, array).
*
* @static
* @memberof _
* @since 3.0.0
* @category array
* @param {array} array the array to query.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @returns {array} returns the slice of `array`.
* @example
*
* var users = [
* { 'user': 'barney', 'active': true },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': false }
* ];
*
* _.droprightwhile(users, function(o) { return !o.active; });
* // => objects for ['barney']
*
* // the `_.matches` iteratee shorthand.
* _.droprightwhile(users, { 'user': 'pebbles', 'active': false });
* // => objects for ['barney', 'fred']
*
* // the `_.matchesproperty` iteratee shorthand.
* _.droprightwhile(users, ['active', false]);
* // => objects for ['barney']
*
* // the `_.property` iteratee shorthand.
* _.droprightwhile(users, 'active');
* // => objects for ['barney', 'fred', 'pebbles']
*/
function droprightwhile(array, predicate) {
return (array && array.length)
? basewhile(array, getiteratee(predicate, 3), true, true)
: [];
}
/**
* creates a slice of `array` excluding elements dropped from the beginning.
* elements are dropped until `predicate` returns falsey. the predicate is
* invoked with three arguments: (value, index, array).
*
* @static
* @memberof _
* @since 3.0.0
* @category array
* @param {array} array the array to query.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @returns {array} returns the slice of `array`.
* @example
*
* var users = [
* { 'user': 'barney', 'active': false },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': true }
* ];
*
* _.dropwhile(users, function(o) { return !o.active; });
* // => objects for ['pebbles']
*
* // the `_.matches` iteratee shorthand.
* _.dropwhile(users, { 'user': 'barney', 'active': false });
* // => objects for ['fred', 'pebbles']
*
* // the `_.matchesproperty` iteratee shorthand.
* _.dropwhile(users, ['active', false]);
* // => objects for ['pebbles']
*
* // the `_.property` iteratee shorthand.
* _.dropwhile(users, 'active');
* // => objects for ['barney', 'fred', 'pebbles']
*/
function dropwhile(array, predicate) {
return (array && array.length)
? basewhile(array, getiteratee(predicate, 3), true)
: [];
}
/**
* fills elements of `array` with `value` from `start` up to, but not
* including, `end`.
*
* **note:** this method mutates `array`.
*
* @static
* @memberof _
* @since 3.2.0
* @category array
* @param {array} array the array to fill.
* @param {*} value the value to fill `array` with.
* @param {number} [start=0] the start position.
* @param {number} [end=array.length] the end position.
* @returns {array} returns `array`.
* @example
*
* var array = [1, 2, 3];
*
* _.fill(array, 'a');
* console.log(array);
* // => ['a', 'a', 'a']
*
* _.fill(array(3), 2);
* // => [2, 2, 2]
*
* _.fill([4, 6, 8, 10], '*', 1, 3);
* // => [4, '*', '*', 10]
*/
function fill(array, value, start, end) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
if (start && typeof start != 'number' && isiterateecall(array, value, start)) {
start = 0;
end = length;
}
return basefill(array, value, start, end);
}
/**
* this method is like `_.find` except that it returns the index of the first
* element `predicate` returns truthy for instead of the element itself.
*
* @static
* @memberof _
* @since 1.1.0
* @category array
* @param {array} array the array to inspect.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @param {number} [fromindex=0] the index to search from.
* @returns {number} returns the index of the found element, else `-1`.
* @example
*
* var users = [
* { 'user': 'barney', 'active': false },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': true }
* ];
*
* _.findindex(users, function(o) { return o.user == 'barney'; });
* // => 0
*
* // the `_.matches` iteratee shorthand.
* _.findindex(users, { 'user': 'fred', 'active': false });
* // => 1
*
* // the `_.matchesproperty` iteratee shorthand.
* _.findindex(users, ['active', false]);
* // => 0
*
* // the `_.property` iteratee shorthand.
* _.findindex(users, 'active');
* // => 2
*/
function findindex(array, predicate, fromindex) {
var length = array == null ? 0 : array.length;
if (!length) {
return -1;
}
var index = fromindex == null ? 0 : tointeger(fromindex);
if (index < 0) {
index = nativemax(length + index, 0);
}
return basefindindex(array, getiteratee(predicate, 3), index);
}
/**
* this method is like `_.findindex` except that it iterates over elements
* of `collection` from right to left.
*
* @static
* @memberof _
* @since 2.0.0
* @category array
* @param {array} array the array to inspect.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @param {number} [fromindex=array.length-1] the index to search from.
* @returns {number} returns the index of the found element, else `-1`.
* @example
*
* var users = [
* { 'user': 'barney', 'active': true },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': false }
* ];
*
* _.findlastindex(users, function(o) { return o.user == 'pebbles'; });
* // => 2
*
* // the `_.matches` iteratee shorthand.
* _.findlastindex(users, { 'user': 'barney', 'active': true });
* // => 0
*
* // the `_.matchesproperty` iteratee shorthand.
* _.findlastindex(users, ['active', false]);
* // => 2
*
* // the `_.property` iteratee shorthand.
* _.findlastindex(users, 'active');
* // => 0
*/
function findlastindex(array, predicate, fromindex) {
var length = array == null ? 0 : array.length;
if (!length) {
return -1;
}
var index = length - 1;
if (fromindex !== undefined) {
index = tointeger(fromindex);
index = fromindex < 0
? nativemax(length + index, 0)
: nativemin(index, length - 1);
}
return basefindindex(array, getiteratee(predicate, 3), index, true);
}
/**
* flattens `array` a single level deep.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {array} array the array to flatten.
* @returns {array} returns the new flattened array.
* @example
*
* _.flatten([1, [2, [3, [4]], 5]]);
* // => [1, 2, [3, [4]], 5]
*/
function flatten(array) {
var length = array == null ? 0 : array.length;
return length ? baseflatten(array, 1) : [];
}
/**
* recursively flattens `array`.
*
* @static
* @memberof _
* @since 3.0.0
* @category array
* @param {array} array the array to flatten.
* @returns {array} returns the new flattened array.
* @example
*
* _.flattendeep([1, [2, [3, [4]], 5]]);
* // => [1, 2, 3, 4, 5]
*/
function flattendeep(array) {
var length = array == null ? 0 : array.length;
return length ? baseflatten(array, infinity) : [];
}
/**
* recursively flatten `array` up to `depth` times.
*
* @static
* @memberof _
* @since 4.4.0
* @category array
* @param {array} array the array to flatten.
* @param {number} [depth=1] the maximum recursion depth.
* @returns {array} returns the new flattened array.
* @example
*
* var array = [1, [2, [3, [4]], 5]];
*
* _.flattendepth(array, 1);
* // => [1, 2, [3, [4]], 5]
*
* _.flattendepth(array, 2);
* // => [1, 2, 3, [4], 5]
*/
function flattendepth(array, depth) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
depth = depth === undefined ? 1 : tointeger(depth);
return baseflatten(array, depth);
}
/**
* the inverse of `_.topairs`; this method returns an object composed
* from key-value `pairs`.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} pairs the key-value pairs.
* @returns {object} returns the new object.
* @example
*
* _.frompairs([['a', 1], ['b', 2]]);
* // => { 'a': 1, 'b': 2 }
*/
function frompairs(pairs) {
var index = -1,
length = pairs == null ? 0 : pairs.length,
result = {};
while (++index < length) {
var pair = pairs[index];
result[pair[0]] = pair[1];
}
return result;
}
/**
* gets the first element of `array`.
*
* @static
* @memberof _
* @since 0.1.0
* @alias first
* @category array
* @param {array} array the array to query.
* @returns {*} returns the first element of `array`.
* @example
*
* _.head([1, 2, 3]);
* // => 1
*
* _.head([]);
* // => undefined
*/
function head(array) {
return (array && array.length) ? array[0] : undefined;
}
/**
* gets the index at which the first occurrence of `value` is found in `array`
* using [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons. if `fromindex` is negative, it's used as the
* offset from the end of `array`.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {array} array the array to inspect.
* @param {*} value the value to search for.
* @param {number} [fromindex=0] the index to search from.
* @returns {number} returns the index of the matched value, else `-1`.
* @example
*
* _.indexof([1, 2, 1, 2], 2);
* // => 1
*
* // search from the `fromindex`.
* _.indexof([1, 2, 1, 2], 2, 2);
* // => 3
*/
function indexof(array, value, fromindex) {
var length = array == null ? 0 : array.length;
if (!length) {
return -1;
}
var index = fromindex == null ? 0 : tointeger(fromindex);
if (index < 0) {
index = nativemax(length + index, 0);
}
return baseindexof(array, value, index);
}
/**
* gets all but the last element of `array`.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {array} array the array to query.
* @returns {array} returns the slice of `array`.
* @example
*
* _.initial([1, 2, 3]);
* // => [1, 2]
*/
function initial(array) {
var length = array == null ? 0 : array.length;
return length ? baseslice(array, 0, -1) : [];
}
/**
* creates an array of unique values that are included in all given arrays
* using [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons. the order and references of result values are
* determined by the first array.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {...array} [arrays] the arrays to inspect.
* @returns {array} returns the new array of intersecting values.
* @example
*
* _.intersection([2, 1], [2, 3]);
* // => [2]
*/
var intersection = baserest(function(arrays) {
var mapped = arraymap(arrays, castarraylikeobject);
return (mapped.length && mapped[0] === arrays[0])
? baseintersection(mapped)
: [];
});
/**
* this method is like `_.intersection` except that it accepts `iteratee`
* which is invoked for each element of each `arrays` to generate the criterion
* by which they're compared. the order and references of result values are
* determined by the first array. the iteratee is invoked with one argument:
* (value).
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {...array} [arrays] the arrays to inspect.
* @param {function} [iteratee=_.identity] the iteratee invoked per element.
* @returns {array} returns the new array of intersecting values.
* @example
*
* _.intersectionby([2.1, 1.2], [2.3, 3.4], math.floor);
* // => [2.1]
*
* // the `_.property` iteratee shorthand.
* _.intersectionby([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
* // => [{ 'x': 1 }]
*/
var intersectionby = baserest(function(arrays) {
var iteratee = last(arrays),
mapped = arraymap(arrays, castarraylikeobject);
if (iteratee === last(mapped)) {
iteratee = undefined;
} else {
mapped.pop();
}
return (mapped.length && mapped[0] === arrays[0])
? baseintersection(mapped, getiteratee(iteratee, 2))
: [];
});
/**
* this method is like `_.intersection` except that it accepts `comparator`
* which is invoked to compare elements of `arrays`. the order and references
* of result values are determined by the first array. the comparator is
* invoked with two arguments: (arrval, othval).
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {...array} [arrays] the arrays to inspect.
* @param {function} [comparator] the comparator invoked per element.
* @returns {array} returns the new array of intersecting values.
* @example
*
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
*
* _.intersectionwith(objects, others, _.isequal);
* // => [{ 'x': 1, 'y': 2 }]
*/
var intersectionwith = baserest(function(arrays) {
var comparator = last(arrays),
mapped = arraymap(arrays, castarraylikeobject);
comparator = typeof comparator == 'function' ? comparator : undefined;
if (comparator) {
mapped.pop();
}
return (mapped.length && mapped[0] === arrays[0])
? baseintersection(mapped, undefined, comparator)
: [];
});
/**
* converts all elements in `array` into a string separated by `separator`.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to convert.
* @param {string} [separator=','] the element separator.
* @returns {string} returns the joined string.
* @example
*
* _.join(['a', 'b', 'c'], '~');
* // => 'a~b~c'
*/
function join(array, separator) {
return array == null ? '' : nativejoin.call(array, separator);
}
/**
* gets the last element of `array`.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {array} array the array to query.
* @returns {*} returns the last element of `array`.
* @example
*
* _.last([1, 2, 3]);
* // => 3
*/
function last(array) {
var length = array == null ? 0 : array.length;
return length ? array[length - 1] : undefined;
}
/**
* this method is like `_.indexof` except that it iterates over elements of
* `array` from right to left.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {array} array the array to inspect.
* @param {*} value the value to search for.
* @param {number} [fromindex=array.length-1] the index to search from.
* @returns {number} returns the index of the matched value, else `-1`.
* @example
*
* _.lastindexof([1, 2, 1, 2], 2);
* // => 3
*
* // search from the `fromindex`.
* _.lastindexof([1, 2, 1, 2], 2, 2);
* // => 1
*/
function lastindexof(array, value, fromindex) {
var length = array == null ? 0 : array.length;
if (!length) {
return -1;
}
var index = length;
if (fromindex !== undefined) {
index = tointeger(fromindex);
index = index < 0 ? nativemax(length + index, 0) : nativemin(index, length - 1);
}
return value === value
? strictlastindexof(array, value, index)
: basefindindex(array, baseisnan, index, true);
}
/**
* gets the element at index `n` of `array`. if `n` is negative, the nth
* element from the end is returned.
*
* @static
* @memberof _
* @since 4.11.0
* @category array
* @param {array} array the array to query.
* @param {number} [n=0] the index of the element to return.
* @returns {*} returns the nth element of `array`.
* @example
*
* var array = ['a', 'b', 'c', 'd'];
*
* _.nth(array, 1);
* // => 'b'
*
* _.nth(array, -2);
* // => 'c';
*/
function nth(array, n) {
return (array && array.length) ? basenth(array, tointeger(n)) : undefined;
}
/**
* removes all given values from `array` using
* [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons.
*
* **note:** unlike `_.without`, this method mutates `array`. use `_.remove`
* to remove elements from an array by predicate.
*
* @static
* @memberof _
* @since 2.0.0
* @category array
* @param {array} array the array to modify.
* @param {...*} [values] the values to remove.
* @returns {array} returns `array`.
* @example
*
* var array = ['a', 'b', 'c', 'a', 'b', 'c'];
*
* _.pull(array, 'a', 'c');
* console.log(array);
* // => ['b', 'b']
*/
var pull = baserest(pullall);
/**
* this method is like `_.pull` except that it accepts an array of values to remove.
*
* **note:** unlike `_.difference`, this method mutates `array`.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to modify.
* @param {array} values the values to remove.
* @returns {array} returns `array`.
* @example
*
* var array = ['a', 'b', 'c', 'a', 'b', 'c'];
*
* _.pullall(array, ['a', 'c']);
* console.log(array);
* // => ['b', 'b']
*/
function pullall(array, values) {
return (array && array.length && values && values.length)
? basepullall(array, values)
: array;
}
/**
* this method is like `_.pullall` except that it accepts `iteratee` which is
* invoked for each element of `array` and `values` to generate the criterion
* by which they're compared. the iteratee is invoked with one argument: (value).
*
* **note:** unlike `_.differenceby`, this method mutates `array`.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to modify.
* @param {array} values the values to remove.
* @param {function} [iteratee=_.identity] the iteratee invoked per element.
* @returns {array} returns `array`.
* @example
*
* var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
*
* _.pullallby(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
* console.log(array);
* // => [{ 'x': 2 }]
*/
function pullallby(array, values, iteratee) {
return (array && array.length && values && values.length)
? basepullall(array, values, getiteratee(iteratee, 2))
: array;
}
/**
* this method is like `_.pullall` except that it accepts `comparator` which
* is invoked to compare elements of `array` to `values`. the comparator is
* invoked with two arguments: (arrval, othval).
*
* **note:** unlike `_.differencewith`, this method mutates `array`.
*
* @static
* @memberof _
* @since 4.6.0
* @category array
* @param {array} array the array to modify.
* @param {array} values the values to remove.
* @param {function} [comparator] the comparator invoked per element.
* @returns {array} returns `array`.
* @example
*
* var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
*
* _.pullallwith(array, [{ 'x': 3, 'y': 4 }], _.isequal);
* console.log(array);
* // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
*/
function pullallwith(array, values, comparator) {
return (array && array.length && values && values.length)
? basepullall(array, values, undefined, comparator)
: array;
}
/**
* removes elements from `array` corresponding to `indexes` and returns an
* array of removed elements.
*
* **note:** unlike `_.at`, this method mutates `array`.
*
* @static
* @memberof _
* @since 3.0.0
* @category array
* @param {array} array the array to modify.
* @param {...(number|number[])} [indexes] the indexes of elements to remove.
* @returns {array} returns the new array of removed elements.
* @example
*
* var array = ['a', 'b', 'c', 'd'];
* var pulled = _.pullat(array, [1, 3]);
*
* console.log(array);
* // => ['a', 'c']
*
* console.log(pulled);
* // => ['b', 'd']
*/
var pullat = flatrest(function(array, indexes) {
var length = array == null ? 0 : array.length,
result = baseat(array, indexes);
basepullat(array, arraymap(indexes, function(index) {
return isindex(index, length) ? +index : index;
}).sort(compareascending));
return result;
});
/**
* removes all elements from `array` that `predicate` returns truthy for
* and returns an array of the removed elements. the predicate is invoked
* with three arguments: (value, index, array).
*
* **note:** unlike `_.filter`, this method mutates `array`. use `_.pull`
* to pull elements from an array by value.
*
* @static
* @memberof _
* @since 2.0.0
* @category array
* @param {array} array the array to modify.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @returns {array} returns the new array of removed elements.
* @example
*
* var array = [1, 2, 3, 4];
* var evens = _.remove(array, function(n) {
* return n % 2 == 0;
* });
*
* console.log(array);
* // => [1, 3]
*
* console.log(evens);
* // => [2, 4]
*/
function remove(array, predicate) {
var result = [];
if (!(array && array.length)) {
return result;
}
var index = -1,
indexes = [],
length = array.length;
predicate = getiteratee(predicate, 3);
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
result.push(value);
indexes.push(index);
}
}
basepullat(array, indexes);
return result;
}
/**
* reverses `array` so that the first element becomes the last, the second
* element becomes the second to last, and so on.
*
* **note:** this method mutates `array` and is based on
* [`array#reverse`](https://mdn.io/array/reverse).
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to modify.
* @returns {array} returns `array`.
* @example
*
* var array = [1, 2, 3];
*
* _.reverse(array);
* // => [3, 2, 1]
*
* console.log(array);
* // => [3, 2, 1]
*/
function reverse(array) {
return array == null ? array : nativereverse.call(array);
}
/**
* creates a slice of `array` from `start` up to, but not including, `end`.
*
* **note:** this method is used instead of
* [`array#slice`](https://mdn.io/array/slice) to ensure dense arrays are
* returned.
*
* @static
* @memberof _
* @since 3.0.0
* @category array
* @param {array} array the array to slice.
* @param {number} [start=0] the start position.
* @param {number} [end=array.length] the end position.
* @returns {array} returns the slice of `array`.
*/
function slice(array, start, end) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
if (end && typeof end != 'number' && isiterateecall(array, start, end)) {
start = 0;
end = length;
}
else {
start = start == null ? 0 : tointeger(start);
end = end === undefined ? length : tointeger(end);
}
return baseslice(array, start, end);
}
/**
* uses a binary search to determine the lowest index at which `value`
* should be inserted into `array` in order to maintain its sort order.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {array} array the sorted array to inspect.
* @param {*} value the value to evaluate.
* @returns {number} returns the index at which `value` should be inserted
* into `array`.
* @example
*
* _.sortedindex([30, 50], 40);
* // => 1
*/
function sortedindex(array, value) {
return basesortedindex(array, value);
}
/**
* this method is like `_.sortedindex` except that it accepts `iteratee`
* which is invoked for `value` and each element of `array` to compute their
* sort ranking. the iteratee is invoked with one argument: (value).
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the sorted array to inspect.
* @param {*} value the value to evaluate.
* @param {function} [iteratee=_.identity] the iteratee invoked per element.
* @returns {number} returns the index at which `value` should be inserted
* into `array`.
* @example
*
* var objects = [{ 'x': 4 }, { 'x': 5 }];
*
* _.sortedindexby(objects, { 'x': 4 }, function(o) { return o.x; });
* // => 0
*
* // the `_.property` iteratee shorthand.
* _.sortedindexby(objects, { 'x': 4 }, 'x');
* // => 0
*/
function sortedindexby(array, value, iteratee) {
return basesortedindexby(array, value, getiteratee(iteratee, 2));
}
/**
* this method is like `_.indexof` except that it performs a binary
* search on a sorted `array`.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to inspect.
* @param {*} value the value to search for.
* @returns {number} returns the index of the matched value, else `-1`.
* @example
*
* _.sortedindexof([4, 5, 5, 5, 6], 5);
* // => 1
*/
function sortedindexof(array, value) {
var length = array == null ? 0 : array.length;
if (length) {
var index = basesortedindex(array, value);
if (index < length && eq(array[index], value)) {
return index;
}
}
return -1;
}
/**
* this method is like `_.sortedindex` except that it returns the highest
* index at which `value` should be inserted into `array` in order to
* maintain its sort order.
*
* @static
* @memberof _
* @since 3.0.0
* @category array
* @param {array} array the sorted array to inspect.
* @param {*} value the value to evaluate.
* @returns {number} returns the index at which `value` should be inserted
* into `array`.
* @example
*
* _.sortedlastindex([4, 5, 5, 5, 6], 5);
* // => 4
*/
function sortedlastindex(array, value) {
return basesortedindex(array, value, true);
}
/**
* this method is like `_.sortedlastindex` except that it accepts `iteratee`
* which is invoked for `value` and each element of `array` to compute their
* sort ranking. the iteratee is invoked with one argument: (value).
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the sorted array to inspect.
* @param {*} value the value to evaluate.
* @param {function} [iteratee=_.identity] the iteratee invoked per element.
* @returns {number} returns the index at which `value` should be inserted
* into `array`.
* @example
*
* var objects = [{ 'x': 4 }, { 'x': 5 }];
*
* _.sortedlastindexby(objects, { 'x': 4 }, function(o) { return o.x; });
* // => 1
*
* // the `_.property` iteratee shorthand.
* _.sortedlastindexby(objects, { 'x': 4 }, 'x');
* // => 1
*/
function sortedlastindexby(array, value, iteratee) {
return basesortedindexby(array, value, getiteratee(iteratee, 2), true);
}
/**
* this method is like `_.lastindexof` except that it performs a binary
* search on a sorted `array`.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to inspect.
* @param {*} value the value to search for.
* @returns {number} returns the index of the matched value, else `-1`.
* @example
*
* _.sortedlastindexof([4, 5, 5, 5, 6], 5);
* // => 3
*/
function sortedlastindexof(array, value) {
var length = array == null ? 0 : array.length;
if (length) {
var index = basesortedindex(array, value, true) - 1;
if (eq(array[index], value)) {
return index;
}
}
return -1;
}
/**
* this method is like `_.uniq` except that it's designed and optimized
* for sorted arrays.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to inspect.
* @returns {array} returns the new duplicate free array.
* @example
*
* _.sorteduniq([1, 1, 2]);
* // => [1, 2]
*/
function sorteduniq(array) {
return (array && array.length)
? basesorteduniq(array)
: [];
}
/**
* this method is like `_.uniqby` except that it's designed and optimized
* for sorted arrays.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to inspect.
* @param {function} [iteratee] the iteratee invoked per element.
* @returns {array} returns the new duplicate free array.
* @example
*
* _.sorteduniqby([1.1, 1.2, 2.3, 2.4], math.floor);
* // => [1.1, 2.3]
*/
function sorteduniqby(array, iteratee) {
return (array && array.length)
? basesorteduniq(array, getiteratee(iteratee, 2))
: [];
}
/**
* gets all but the first element of `array`.
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to query.
* @returns {array} returns the slice of `array`.
* @example
*
* _.tail([1, 2, 3]);
* // => [2, 3]
*/
function tail(array) {
var length = array == null ? 0 : array.length;
return length ? baseslice(array, 1, length) : [];
}
/**
* creates a slice of `array` with `n` elements taken from the beginning.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {array} array the array to query.
* @param {number} [n=1] the number of elements to take.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {array} returns the slice of `array`.
* @example
*
* _.take([1, 2, 3]);
* // => [1]
*
* _.take([1, 2, 3], 2);
* // => [1, 2]
*
* _.take([1, 2, 3], 5);
* // => [1, 2, 3]
*
* _.take([1, 2, 3], 0);
* // => []
*/
function take(array, n, guard) {
if (!(array && array.length)) {
return [];
}
n = (guard || n === undefined) ? 1 : tointeger(n);
return baseslice(array, 0, n < 0 ? 0 : n);
}
/**
* creates a slice of `array` with `n` elements taken from the end.
*
* @static
* @memberof _
* @since 3.0.0
* @category array
* @param {array} array the array to query.
* @param {number} [n=1] the number of elements to take.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {array} returns the slice of `array`.
* @example
*
* _.takeright([1, 2, 3]);
* // => [3]
*
* _.takeright([1, 2, 3], 2);
* // => [2, 3]
*
* _.takeright([1, 2, 3], 5);
* // => [1, 2, 3]
*
* _.takeright([1, 2, 3], 0);
* // => []
*/
function takeright(array, n, guard) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
n = (guard || n === undefined) ? 1 : tointeger(n);
n = length - n;
return baseslice(array, n < 0 ? 0 : n, length);
}
/**
* creates a slice of `array` with elements taken from the end. elements are
* taken until `predicate` returns falsey. the predicate is invoked with
* three arguments: (value, index, array).
*
* @static
* @memberof _
* @since 3.0.0
* @category array
* @param {array} array the array to query.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @returns {array} returns the slice of `array`.
* @example
*
* var users = [
* { 'user': 'barney', 'active': true },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': false }
* ];
*
* _.takerightwhile(users, function(o) { return !o.active; });
* // => objects for ['fred', 'pebbles']
*
* // the `_.matches` iteratee shorthand.
* _.takerightwhile(users, { 'user': 'pebbles', 'active': false });
* // => objects for ['pebbles']
*
* // the `_.matchesproperty` iteratee shorthand.
* _.takerightwhile(users, ['active', false]);
* // => objects for ['fred', 'pebbles']
*
* // the `_.property` iteratee shorthand.
* _.takerightwhile(users, 'active');
* // => []
*/
function takerightwhile(array, predicate) {
return (array && array.length)
? basewhile(array, getiteratee(predicate, 3), false, true)
: [];
}
/**
* creates a slice of `array` with elements taken from the beginning. elements
* are taken until `predicate` returns falsey. the predicate is invoked with
* three arguments: (value, index, array).
*
* @static
* @memberof _
* @since 3.0.0
* @category array
* @param {array} array the array to query.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @returns {array} returns the slice of `array`.
* @example
*
* var users = [
* { 'user': 'barney', 'active': false },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': true }
* ];
*
* _.takewhile(users, function(o) { return !o.active; });
* // => objects for ['barney', 'fred']
*
* // the `_.matches` iteratee shorthand.
* _.takewhile(users, { 'user': 'barney', 'active': false });
* // => objects for ['barney']
*
* // the `_.matchesproperty` iteratee shorthand.
* _.takewhile(users, ['active', false]);
* // => objects for ['barney', 'fred']
*
* // the `_.property` iteratee shorthand.
* _.takewhile(users, 'active');
* // => []
*/
function takewhile(array, predicate) {
return (array && array.length)
? basewhile(array, getiteratee(predicate, 3))
: [];
}
/**
* creates an array of unique values, in order, from all given arrays using
* [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {...array} [arrays] the arrays to inspect.
* @returns {array} returns the new array of combined values.
* @example
*
* _.union([2], [1, 2]);
* // => [2, 1]
*/
var union = baserest(function(arrays) {
return baseuniq(baseflatten(arrays, 1, isarraylikeobject, true));
});
/**
* this method is like `_.union` except that it accepts `iteratee` which is
* invoked for each element of each `arrays` to generate the criterion by
* which uniqueness is computed. result values are chosen from the first
* array in which the value occurs. the iteratee is invoked with one argument:
* (value).
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {...array} [arrays] the arrays to inspect.
* @param {function} [iteratee=_.identity] the iteratee invoked per element.
* @returns {array} returns the new array of combined values.
* @example
*
* _.unionby([2.1], [1.2, 2.3], math.floor);
* // => [2.1, 1.2]
*
* // the `_.property` iteratee shorthand.
* _.unionby([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
* // => [{ 'x': 1 }, { 'x': 2 }]
*/
var unionby = baserest(function(arrays) {
var iteratee = last(arrays);
if (isarraylikeobject(iteratee)) {
iteratee = undefined;
}
return baseuniq(baseflatten(arrays, 1, isarraylikeobject, true), getiteratee(iteratee, 2));
});
/**
* this method is like `_.union` except that it accepts `comparator` which
* is invoked to compare elements of `arrays`. result values are chosen from
* the first array in which the value occurs. the comparator is invoked
* with two arguments: (arrval, othval).
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {...array} [arrays] the arrays to inspect.
* @param {function} [comparator] the comparator invoked per element.
* @returns {array} returns the new array of combined values.
* @example
*
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
*
* _.unionwith(objects, others, _.isequal);
* // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
*/
var unionwith = baserest(function(arrays) {
var comparator = last(arrays);
comparator = typeof comparator == 'function' ? comparator : undefined;
return baseuniq(baseflatten(arrays, 1, isarraylikeobject, true), undefined, comparator);
});
/**
* creates a duplicate-free version of an array, using
* [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons, in which only the first occurrence of each element
* is kept. the order of result values is determined by the order they occur
* in the array.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {array} array the array to inspect.
* @returns {array} returns the new duplicate free array.
* @example
*
* _.uniq([2, 1, 2]);
* // => [2, 1]
*/
function uniq(array) {
return (array && array.length) ? baseuniq(array) : [];
}
/**
* this method is like `_.uniq` except that it accepts `iteratee` which is
* invoked for each element in `array` to generate the criterion by which
* uniqueness is computed. the order of result values is determined by the
* order they occur in the array. the iteratee is invoked with one argument:
* (value).
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to inspect.
* @param {function} [iteratee=_.identity] the iteratee invoked per element.
* @returns {array} returns the new duplicate free array.
* @example
*
* _.uniqby([2.1, 1.2, 2.3], math.floor);
* // => [2.1, 1.2]
*
* // the `_.property` iteratee shorthand.
* _.uniqby([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
* // => [{ 'x': 1 }, { 'x': 2 }]
*/
function uniqby(array, iteratee) {
return (array && array.length) ? baseuniq(array, getiteratee(iteratee, 2)) : [];
}
/**
* this method is like `_.uniq` except that it accepts `comparator` which
* is invoked to compare elements of `array`. the order of result values is
* determined by the order they occur in the array.the comparator is invoked
* with two arguments: (arrval, othval).
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {array} array the array to inspect.
* @param {function} [comparator] the comparator invoked per element.
* @returns {array} returns the new duplicate free array.
* @example
*
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
*
* _.uniqwith(objects, _.isequal);
* // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
*/
function uniqwith(array, comparator) {
comparator = typeof comparator == 'function' ? comparator : undefined;
return (array && array.length) ? baseuniq(array, undefined, comparator) : [];
}
/**
* this method is like `_.zip` except that it accepts an array of grouped
* elements and creates an array regrouping the elements to their pre-zip
* configuration.
*
* @static
* @memberof _
* @since 1.2.0
* @category array
* @param {array} array the array of grouped elements to process.
* @returns {array} returns the new array of regrouped elements.
* @example
*
* var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
* // => [['a', 1, true], ['b', 2, false]]
*
* _.unzip(zipped);
* // => [['a', 'b'], [1, 2], [true, false]]
*/
function unzip(array) {
if (!(array && array.length)) {
return [];
}
var length = 0;
array = arrayfilter(array, function(group) {
if (isarraylikeobject(group)) {
length = nativemax(group.length, length);
return true;
}
});
return basetimes(length, function(index) {
return arraymap(array, baseproperty(index));
});
}
/**
* this method is like `_.unzip` except that it accepts `iteratee` to specify
* how regrouped values should be combined. the iteratee is invoked with the
* elements of each group: (...group).
*
* @static
* @memberof _
* @since 3.8.0
* @category array
* @param {array} array the array of grouped elements to process.
* @param {function} [iteratee=_.identity] the function to combine
* regrouped values.
* @returns {array} returns the new array of regrouped elements.
* @example
*
* var zipped = _.zip([1, 2], [10, 20], [100, 200]);
* // => [[1, 10, 100], [2, 20, 200]]
*
* _.unzipwith(zipped, _.add);
* // => [3, 30, 300]
*/
function unzipwith(array, iteratee) {
if (!(array && array.length)) {
return [];
}
var result = unzip(array);
if (iteratee == null) {
return result;
}
return arraymap(result, function(group) {
return apply(iteratee, undefined, group);
});
}
/**
* creates an array excluding all given values using
* [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons.
*
* **note:** unlike `_.pull`, this method returns a new array.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {array} array the array to inspect.
* @param {...*} [values] the values to exclude.
* @returns {array} returns the new array of filtered values.
* @see _.difference, _.xor
* @example
*
* _.without([2, 1, 2, 3], 1, 2);
* // => [3]
*/
var without = baserest(function(array, values) {
return isarraylikeobject(array)
? basedifference(array, values)
: [];
});
/**
* creates an array of unique values that is the
* [symmetric difference](https://en.wikipedia.org/wiki/symmetric_difference)
* of the given arrays. the order of result values is determined by the order
* they occur in the arrays.
*
* @static
* @memberof _
* @since 2.4.0
* @category array
* @param {...array} [arrays] the arrays to inspect.
* @returns {array} returns the new array of filtered values.
* @see _.difference, _.without
* @example
*
* _.xor([2, 1], [2, 3]);
* // => [1, 3]
*/
var xor = baserest(function(arrays) {
return basexor(arrayfilter(arrays, isarraylikeobject));
});
/**
* this method is like `_.xor` except that it accepts `iteratee` which is
* invoked for each element of each `arrays` to generate the criterion by
* which by which they're compared. the order of result values is determined
* by the order they occur in the arrays. the iteratee is invoked with one
* argument: (value).
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {...array} [arrays] the arrays to inspect.
* @param {function} [iteratee=_.identity] the iteratee invoked per element.
* @returns {array} returns the new array of filtered values.
* @example
*
* _.xorby([2.1, 1.2], [2.3, 3.4], math.floor);
* // => [1.2, 3.4]
*
* // the `_.property` iteratee shorthand.
* _.xorby([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
* // => [{ 'x': 2 }]
*/
var xorby = baserest(function(arrays) {
var iteratee = last(arrays);
if (isarraylikeobject(iteratee)) {
iteratee = undefined;
}
return basexor(arrayfilter(arrays, isarraylikeobject), getiteratee(iteratee, 2));
});
/**
* this method is like `_.xor` except that it accepts `comparator` which is
* invoked to compare elements of `arrays`. the order of result values is
* determined by the order they occur in the arrays. the comparator is invoked
* with two arguments: (arrval, othval).
*
* @static
* @memberof _
* @since 4.0.0
* @category array
* @param {...array} [arrays] the arrays to inspect.
* @param {function} [comparator] the comparator invoked per element.
* @returns {array} returns the new array of filtered values.
* @example
*
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
* var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
*
* _.xorwith(objects, others, _.isequal);
* // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
*/
var xorwith = baserest(function(arrays) {
var comparator = last(arrays);
comparator = typeof comparator == 'function' ? comparator : undefined;
return basexor(arrayfilter(arrays, isarraylikeobject), undefined, comparator);
});
/**
* creates an array of grouped elements, the first of which contains the
* first elements of the given arrays, the second of which contains the
* second elements of the given arrays, and so on.
*
* @static
* @memberof _
* @since 0.1.0
* @category array
* @param {...array} [arrays] the arrays to process.
* @returns {array} returns the new array of grouped elements.
* @example
*
* _.zip(['a', 'b'], [1, 2], [true, false]);
* // => [['a', 1, true], ['b', 2, false]]
*/
var zip = baserest(unzip);
/**
* this method is like `_.frompairs` except that it accepts two arrays,
* one of property identifiers and one of corresponding values.
*
* @static
* @memberof _
* @since 0.4.0
* @category array
* @param {array} [props=[]] the property identifiers.
* @param {array} [values=[]] the property values.
* @returns {object} returns the new object.
* @example
*
* _.zipobject(['a', 'b'], [1, 2]);
* // => { 'a': 1, 'b': 2 }
*/
function zipobject(props, values) {
return basezipobject(props || [], values || [], assignvalue);
}
/**
* this method is like `_.zipobject` except that it supports property paths.
*
* @static
* @memberof _
* @since 4.1.0
* @category array
* @param {array} [props=[]] the property identifiers.
* @param {array} [values=[]] the property values.
* @returns {object} returns the new object.
* @example
*
* _.zipobjectdeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
* // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
*/
function zipobjectdeep(props, values) {
return basezipobject(props || [], values || [], baseset);
}
/**
* this method is like `_.zip` except that it accepts `iteratee` to specify
* how grouped values should be combined. the iteratee is invoked with the
* elements of each group: (...group).
*
* @static
* @memberof _
* @since 3.8.0
* @category array
* @param {...array} [arrays] the arrays to process.
* @param {function} [iteratee=_.identity] the function to combine
* grouped values.
* @returns {array} returns the new array of grouped elements.
* @example
*
* _.zipwith([1, 2], [10, 20], [100, 200], function(a, b, c) {
* return a + b + c;
* });
* // => [111, 222]
*/
var zipwith = baserest(function(arrays) {
var length = arrays.length,
iteratee = length > 1 ? arrays[length - 1] : undefined;
iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
return unzipwith(arrays, iteratee);
});
/*------------------------------------------------------------------------*/
/**
* creates a `lodash` wrapper instance that wraps `value` with explicit method
* chain sequences enabled. the result of such sequences must be unwrapped
* with `_#value`.
*
* @static
* @memberof _
* @since 1.3.0
* @category seq
* @param {*} value the value to wrap.
* @returns {object} returns the new `lodash` wrapper instance.
* @example
*
* var users = [
* { 'user': 'barney', 'age': 36 },
* { 'user': 'fred', 'age': 40 },
* { 'user': 'pebbles', 'age': 1 }
* ];
*
* var youngest = _
* .chain(users)
* .sortby('age')
* .map(function(o) {
* return o.user + ' is ' + o.age;
* })
* .head()
* .value();
* // => 'pebbles is 1'
*/
function chain(value) {
var result = lodash(value);
result.__chain__ = true;
return result;
}
/**
* this method invokes `interceptor` and returns `value`. the interceptor
* is invoked with one argument; (value). the purpose of this method is to
* "tap into" a method chain sequence in order to modify intermediate results.
*
* @static
* @memberof _
* @since 0.1.0
* @category seq
* @param {*} value the value to provide to `interceptor`.
* @param {function} interceptor the function to invoke.
* @returns {*} returns `value`.
* @example
*
* _([1, 2, 3])
* .tap(function(array) {
* // mutate input array.
* array.pop();
* })
* .reverse()
* .value();
* // => [2, 1]
*/
function tap(value, interceptor) {
interceptor(value);
return value;
}
/**
* this method is like `_.tap` except that it returns the result of `interceptor`.
* the purpose of this method is to "pass thru" values replacing intermediate
* results in a method chain sequence.
*
* @static
* @memberof _
* @since 3.0.0
* @category seq
* @param {*} value the value to provide to `interceptor`.
* @param {function} interceptor the function to invoke.
* @returns {*} returns the result of `interceptor`.
* @example
*
* _(' abc ')
* .chain()
* .trim()
* .thru(function(value) {
* return [value];
* })
* .value();
* // => ['abc']
*/
function thru(value, interceptor) {
return interceptor(value);
}
/**
* this method is the wrapper version of `_.at`.
*
* @name at
* @memberof _
* @since 1.0.0
* @category seq
* @param {...(string|string[])} [paths] the property paths to pick.
* @returns {object} returns the new `lodash` wrapper instance.
* @example
*
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
*
* _(object).at(['a[0].b.c', 'a[1]']).value();
* // => [3, 4]
*/
var wrapperat = flatrest(function(paths) {
var length = paths.length,
start = length ? paths[0] : 0,
value = this.__wrapped__,
interceptor = function(object) { return baseat(object, paths); };
if (length > 1 || this.__actions__.length ||
!(value instanceof lazywrapper) || !isindex(start)) {
return this.thru(interceptor);
}
value = value.slice(start, +start + (length ? 1 : 0));
value.__actions__.push({
'func': thru,
'args': [interceptor],
'thisarg': undefined
});
return new lodashwrapper(value, this.__chain__).thru(function(array) {
if (length && !array.length) {
array.push(undefined);
}
return array;
});
});
/**
* creates a `lodash` wrapper instance with explicit method chain sequences enabled.
*
* @name chain
* @memberof _
* @since 0.1.0
* @category seq
* @returns {object} returns the new `lodash` wrapper instance.
* @example
*
* var users = [
* { 'user': 'barney', 'age': 36 },
* { 'user': 'fred', 'age': 40 }
* ];
*
* // a sequence without explicit chaining.
* _(users).head();
* // => { 'user': 'barney', 'age': 36 }
*
* // a sequence with explicit chaining.
* _(users)
* .chain()
* .head()
* .pick('user')
* .value();
* // => { 'user': 'barney' }
*/
function wrapperchain() {
return chain(this);
}
/**
* executes the chain sequence and returns the wrapped result.
*
* @name commit
* @memberof _
* @since 3.2.0
* @category seq
* @returns {object} returns the new `lodash` wrapper instance.
* @example
*
* var array = [1, 2];
* var wrapped = _(array).push(3);
*
* console.log(array);
* // => [1, 2]
*
* wrapped = wrapped.commit();
* console.log(array);
* // => [1, 2, 3]
*
* wrapped.last();
* // => 3
*
* console.log(array);
* // => [1, 2, 3]
*/
function wrappercommit() {
return new lodashwrapper(this.value(), this.__chain__);
}
/**
* gets the next value on a wrapped object following the
* [iterator protocol](https://mdn.io/iteration_protocols#iterator).
*
* @name next
* @memberof _
* @since 4.0.0
* @category seq
* @returns {object} returns the next iterator value.
* @example
*
* var wrapped = _([1, 2]);
*
* wrapped.next();
* // => { 'done': false, 'value': 1 }
*
* wrapped.next();
* // => { 'done': false, 'value': 2 }
*
* wrapped.next();
* // => { 'done': true, 'value': undefined }
*/
function wrappernext() {
if (this.__values__ === undefined) {
this.__values__ = toarray(this.value());
}
var done = this.__index__ >= this.__values__.length,
value = done ? undefined : this.__values__[this.__index__++];
return { 'done': done, 'value': value };
}
/**
* enables the wrapper to be iterable.
*
* @name symbol.iterator
* @memberof _
* @since 4.0.0
* @category seq
* @returns {object} returns the wrapper object.
* @example
*
* var wrapped = _([1, 2]);
*
* wrapped[symbol.iterator]() === wrapped;
* // => true
*
* array.from(wrapped);
* // => [1, 2]
*/
function wrappertoiterator() {
return this;
}
/**
* creates a clone of the chain sequence planting `value` as the wrapped value.
*
* @name plant
* @memberof _
* @since 3.2.0
* @category seq
* @param {*} value the value to plant.
* @returns {object} returns the new `lodash` wrapper instance.
* @example
*
* function square(n) {
* return n * n;
* }
*
* var wrapped = _([1, 2]).map(square);
* var other = wrapped.plant([3, 4]);
*
* other.value();
* // => [9, 16]
*
* wrapped.value();
* // => [1, 4]
*/
function wrapperplant(value) {
var result,
parent = this;
while (parent instanceof baselodash) {
var clone = wrapperclone(parent);
clone.__index__ = 0;
clone.__values__ = undefined;
if (result) {
previous.__wrapped__ = clone;
} else {
result = clone;
}
var previous = clone;
parent = parent.__wrapped__;
}
previous.__wrapped__ = value;
return result;
}
/**
* this method is the wrapper version of `_.reverse`.
*
* **note:** this method mutates the wrapped array.
*
* @name reverse
* @memberof _
* @since 0.1.0
* @category seq
* @returns {object} returns the new `lodash` wrapper instance.
* @example
*
* var array = [1, 2, 3];
*
* _(array).reverse().value()
* // => [3, 2, 1]
*
* console.log(array);
* // => [3, 2, 1]
*/
function wrapperreverse() {
var value = this.__wrapped__;
if (value instanceof lazywrapper) {
var wrapped = value;
if (this.__actions__.length) {
wrapped = new lazywrapper(this);
}
wrapped = wrapped.reverse();
wrapped.__actions__.push({
'func': thru,
'args': [reverse],
'thisarg': undefined
});
return new lodashwrapper(wrapped, this.__chain__);
}
return this.thru(reverse);
}
/**
* executes the chain sequence to resolve the unwrapped value.
*
* @name value
* @memberof _
* @since 0.1.0
* @alias tojson, valueof
* @category seq
* @returns {*} returns the resolved unwrapped value.
* @example
*
* _([1, 2, 3]).value();
* // => [1, 2, 3]
*/
function wrappervalue() {
return basewrappervalue(this.__wrapped__, this.__actions__);
}
/*------------------------------------------------------------------------*/
/**
* creates an object composed of keys generated from the results of running
* each element of `collection` thru `iteratee`. the corresponding value of
* each key is the number of times the key was returned by `iteratee`. the
* iteratee is invoked with one argument: (value).
*
* @static
* @memberof _
* @since 0.5.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [iteratee=_.identity] the iteratee to transform keys.
* @returns {object} returns the composed aggregate object.
* @example
*
* _.countby([6.1, 4.2, 6.3], math.floor);
* // => { '4': 1, '6': 2 }
*
* // the `_.property` iteratee shorthand.
* _.countby(['one', 'two', 'three'], 'length');
* // => { '3': 2, '5': 1 }
*/
var countby = createaggregator(function(result, value, key) {
if (hasownproperty.call(result, key)) {
++result[key];
} else {
baseassignvalue(result, key, 1);
}
});
/**
* checks if `predicate` returns truthy for **all** elements of `collection`.
* iteration is stopped once `predicate` returns falsey. the predicate is
* invoked with three arguments: (value, index|key, collection).
*
* **note:** this method returns `true` for
* [empty collections](https://en.wikipedia.org/wiki/empty_set) because
* [everything is true](https://en.wikipedia.org/wiki/vacuous_truth) of
* elements of empty collections.
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {boolean} returns `true` if all elements pass the predicate check,
* else `false`.
* @example
*
* _.every([true, 1, null, 'yes'], boolean);
* // => false
*
* var users = [
* { 'user': 'barney', 'age': 36, 'active': false },
* { 'user': 'fred', 'age': 40, 'active': false }
* ];
*
* // the `_.matches` iteratee shorthand.
* _.every(users, { 'user': 'barney', 'active': false });
* // => false
*
* // the `_.matchesproperty` iteratee shorthand.
* _.every(users, ['active', false]);
* // => true
*
* // the `_.property` iteratee shorthand.
* _.every(users, 'active');
* // => false
*/
function every(collection, predicate, guard) {
var func = isarray(collection) ? arrayevery : baseevery;
if (guard && isiterateecall(collection, predicate, guard)) {
predicate = undefined;
}
return func(collection, getiteratee(predicate, 3));
}
/**
* iterates over elements of `collection`, returning an array of all elements
* `predicate` returns truthy for. the predicate is invoked with three
* arguments: (value, index|key, collection).
*
* **note:** unlike `_.remove`, this method returns a new array.
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @returns {array} returns the new filtered array.
* @see _.reject
* @example
*
* var users = [
* { 'user': 'barney', 'age': 36, 'active': true },
* { 'user': 'fred', 'age': 40, 'active': false }
* ];
*
* _.filter(users, function(o) { return !o.active; });
* // => objects for ['fred']
*
* // the `_.matches` iteratee shorthand.
* _.filter(users, { 'age': 36, 'active': true });
* // => objects for ['barney']
*
* // the `_.matchesproperty` iteratee shorthand.
* _.filter(users, ['active', false]);
* // => objects for ['fred']
*
* // the `_.property` iteratee shorthand.
* _.filter(users, 'active');
* // => objects for ['barney']
*
* // combining several predicates using `_.overevery` or `_.oversome`.
* _.filter(users, _.oversome([{ 'age': 36 }, ['age', 40]]));
* // => objects for ['fred', 'barney']
*/
function filter(collection, predicate) {
var func = isarray(collection) ? arrayfilter : basefilter;
return func(collection, getiteratee(predicate, 3));
}
/**
* iterates over elements of `collection`, returning the first element
* `predicate` returns truthy for. the predicate is invoked with three
* arguments: (value, index|key, collection).
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object} collection the collection to inspect.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @param {number} [fromindex=0] the index to search from.
* @returns {*} returns the matched element, else `undefined`.
* @example
*
* var users = [
* { 'user': 'barney', 'age': 36, 'active': true },
* { 'user': 'fred', 'age': 40, 'active': false },
* { 'user': 'pebbles', 'age': 1, 'active': true }
* ];
*
* _.find(users, function(o) { return o.age < 40; });
* // => object for 'barney'
*
* // the `_.matches` iteratee shorthand.
* _.find(users, { 'age': 1, 'active': true });
* // => object for 'pebbles'
*
* // the `_.matchesproperty` iteratee shorthand.
* _.find(users, ['active', false]);
* // => object for 'fred'
*
* // the `_.property` iteratee shorthand.
* _.find(users, 'active');
* // => object for 'barney'
*/
var find = createfind(findindex);
/**
* this method is like `_.find` except that it iterates over elements of
* `collection` from right to left.
*
* @static
* @memberof _
* @since 2.0.0
* @category collection
* @param {array|object} collection the collection to inspect.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @param {number} [fromindex=collection.length-1] the index to search from.
* @returns {*} returns the matched element, else `undefined`.
* @example
*
* _.findlast([1, 2, 3, 4], function(n) {
* return n % 2 == 1;
* });
* // => 3
*/
var findlast = createfind(findlastindex);
/**
* creates a flattened array of values by running each element in `collection`
* thru `iteratee` and flattening the mapped results. the iteratee is invoked
* with three arguments: (value, index|key, collection).
*
* @static
* @memberof _
* @since 4.0.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @returns {array} returns the new flattened array.
* @example
*
* function duplicate(n) {
* return [n, n];
* }
*
* _.flatmap([1, 2], duplicate);
* // => [1, 1, 2, 2]
*/
function flatmap(collection, iteratee) {
return baseflatten(map(collection, iteratee), 1);
}
/**
* this method is like `_.flatmap` except that it recursively flattens the
* mapped results.
*
* @static
* @memberof _
* @since 4.7.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @returns {array} returns the new flattened array.
* @example
*
* function duplicate(n) {
* return [[[n, n]]];
* }
*
* _.flatmapdeep([1, 2], duplicate);
* // => [1, 1, 2, 2]
*/
function flatmapdeep(collection, iteratee) {
return baseflatten(map(collection, iteratee), infinity);
}
/**
* this method is like `_.flatmap` except that it recursively flattens the
* mapped results up to `depth` times.
*
* @static
* @memberof _
* @since 4.7.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @param {number} [depth=1] the maximum recursion depth.
* @returns {array} returns the new flattened array.
* @example
*
* function duplicate(n) {
* return [[[n, n]]];
* }
*
* _.flatmapdepth([1, 2], duplicate, 2);
* // => [[1, 1], [2, 2]]
*/
function flatmapdepth(collection, iteratee, depth) {
depth = depth === undefined ? 1 : tointeger(depth);
return baseflatten(map(collection, iteratee), depth);
}
/**
* iterates over elements of `collection` and invokes `iteratee` for each element.
* the iteratee is invoked with three arguments: (value, index|key, collection).
* iteratee functions may exit iteration early by explicitly returning `false`.
*
* **note:** as with other "collections" methods, objects with a "length"
* property are iterated like arrays. to avoid this behavior use `_.forin`
* or `_.forown` for object iteration.
*
* @static
* @memberof _
* @since 0.1.0
* @alias each
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @returns {array|object} returns `collection`.
* @see _.foreachright
* @example
*
* _.foreach([1, 2], function(value) {
* console.log(value);
* });
* // => logs `1` then `2`.
*
* _.foreach({ 'a': 1, 'b': 2 }, function(value, key) {
* console.log(key);
* });
* // => logs 'a' then 'b' (iteration order is not guaranteed).
*/
function foreach(collection, iteratee) {
var func = isarray(collection) ? arrayeach : baseeach;
return func(collection, getiteratee(iteratee, 3));
}
/**
* this method is like `_.foreach` except that it iterates over elements of
* `collection` from right to left.
*
* @static
* @memberof _
* @since 2.0.0
* @alias eachright
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @returns {array|object} returns `collection`.
* @see _.foreach
* @example
*
* _.foreachright([1, 2], function(value) {
* console.log(value);
* });
* // => logs `2` then `1`.
*/
function foreachright(collection, iteratee) {
var func = isarray(collection) ? arrayeachright : baseeachright;
return func(collection, getiteratee(iteratee, 3));
}
/**
* creates an object composed of keys generated from the results of running
* each element of `collection` thru `iteratee`. the order of grouped values
* is determined by the order they occur in `collection`. the corresponding
* value of each key is an array of elements responsible for generating the
* key. the iteratee is invoked with one argument: (value).
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [iteratee=_.identity] the iteratee to transform keys.
* @returns {object} returns the composed aggregate object.
* @example
*
* _.groupby([6.1, 4.2, 6.3], math.floor);
* // => { '4': [4.2], '6': [6.1, 6.3] }
*
* // the `_.property` iteratee shorthand.
* _.groupby(['one', 'two', 'three'], 'length');
* // => { '3': ['one', 'two'], '5': ['three'] }
*/
var groupby = createaggregator(function(result, value, key) {
if (hasownproperty.call(result, key)) {
result[key].push(value);
} else {
baseassignvalue(result, key, [value]);
}
});
/**
* checks if `value` is in `collection`. if `collection` is a string, it's
* checked for a substring of `value`, otherwise
* [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* is used for equality comparisons. if `fromindex` is negative, it's used as
* the offset from the end of `collection`.
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object|string} collection the collection to inspect.
* @param {*} value the value to search for.
* @param {number} [fromindex=0] the index to search from.
* @param- {object} [guard] enables use as an iteratee for methods like `_.reduce`.
* @returns {boolean} returns `true` if `value` is found, else `false`.
* @example
*
* _.includes([1, 2, 3], 1);
* // => true
*
* _.includes([1, 2, 3], 1, 2);
* // => false
*
* _.includes({ 'a': 1, 'b': 2 }, 1);
* // => true
*
* _.includes('abcd', 'bc');
* // => true
*/
function includes(collection, value, fromindex, guard) {
collection = isarraylike(collection) ? collection : values(collection);
fromindex = (fromindex && !guard) ? tointeger(fromindex) : 0;
var length = collection.length;
if (fromindex < 0) {
fromindex = nativemax(length + fromindex, 0);
}
return isstring(collection)
? (fromindex <= length && collection.indexof(value, fromindex) > -1)
: (!!length && baseindexof(collection, value, fromindex) > -1);
}
/**
* invokes the method at `path` of each element in `collection`, returning
* an array of the results of each invoked method. any additional arguments
* are provided to each invoked method. if `path` is a function, it's invoked
* for, and `this` bound to, each element in `collection`.
*
* @static
* @memberof _
* @since 4.0.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {array|function|string} path the path of the method to invoke or
* the function invoked per iteration.
* @param {...*} [args] the arguments to invoke each method with.
* @returns {array} returns the array of results.
* @example
*
* _.invokemap([[5, 1, 7], [3, 2, 1]], 'sort');
* // => [[1, 5, 7], [1, 2, 3]]
*
* _.invokemap([123, 456], string.prototype.split, '');
* // => [['1', '2', '3'], ['4', '5', '6']]
*/
var invokemap = baserest(function(collection, path, args) {
var index = -1,
isfunc = typeof path == 'function',
result = isarraylike(collection) ? array(collection.length) : [];
baseeach(collection, function(value) {
result[++index] = isfunc ? apply(path, value, args) : baseinvoke(value, path, args);
});
return result;
});
/**
* creates an object composed of keys generated from the results of running
* each element of `collection` thru `iteratee`. the corresponding value of
* each key is the last element responsible for generating the key. the
* iteratee is invoked with one argument: (value).
*
* @static
* @memberof _
* @since 4.0.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [iteratee=_.identity] the iteratee to transform keys.
* @returns {object} returns the composed aggregate object.
* @example
*
* var array = [
* { 'dir': 'left', 'code': 97 },
* { 'dir': 'right', 'code': 100 }
* ];
*
* _.keyby(array, function(o) {
* return string.fromcharcode(o.code);
* });
* // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
*
* _.keyby(array, 'dir');
* // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
*/
var keyby = createaggregator(function(result, value, key) {
baseassignvalue(result, key, value);
});
/**
* creates an array of values by running each element in `collection` thru
* `iteratee`. the iteratee is invoked with three arguments:
* (value, index|key, collection).
*
* many lodash methods are guarded to work as iteratees for methods like
* `_.every`, `_.filter`, `_.map`, `_.mapvalues`, `_.reject`, and `_.some`.
*
* the guarded methods are:
* `ary`, `chunk`, `curry`, `curryright`, `drop`, `dropright`, `every`,
* `fill`, `invert`, `parseint`, `random`, `range`, `rangeright`, `repeat`,
* `samplesize`, `slice`, `some`, `sortby`, `split`, `take`, `takeright`,
* `template`, `trim`, `trimend`, `trimstart`, and `words`
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @returns {array} returns the new mapped array.
* @example
*
* function square(n) {
* return n * n;
* }
*
* _.map([4, 8], square);
* // => [16, 64]
*
* _.map({ 'a': 4, 'b': 8 }, square);
* // => [16, 64] (iteration order is not guaranteed)
*
* var users = [
* { 'user': 'barney' },
* { 'user': 'fred' }
* ];
*
* // the `_.property` iteratee shorthand.
* _.map(users, 'user');
* // => ['barney', 'fred']
*/
function map(collection, iteratee) {
var func = isarray(collection) ? arraymap : basemap;
return func(collection, getiteratee(iteratee, 3));
}
/**
* this method is like `_.sortby` except that it allows specifying the sort
* orders of the iteratees to sort by. if `orders` is unspecified, all values
* are sorted in ascending order. otherwise, specify an order of "desc" for
* descending or "asc" for ascending sort order of corresponding values.
*
* @static
* @memberof _
* @since 4.0.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {array[]|function[]|object[]|string[]} [iteratees=[_.identity]]
* the iteratees to sort by.
* @param {string[]} [orders] the sort orders of `iteratees`.
* @param- {object} [guard] enables use as an iteratee for methods like `_.reduce`.
* @returns {array} returns the new sorted array.
* @example
*
* var users = [
* { 'user': 'fred', 'age': 48 },
* { 'user': 'barney', 'age': 34 },
* { 'user': 'fred', 'age': 40 },
* { 'user': 'barney', 'age': 36 }
* ];
*
* // sort by `user` in ascending order and by `age` in descending order.
* _.orderby(users, ['user', 'age'], ['asc', 'desc']);
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
*/
function orderby(collection, iteratees, orders, guard) {
if (collection == null) {
return [];
}
if (!isarray(iteratees)) {
iteratees = iteratees == null ? [] : [iteratees];
}
orders = guard ? undefined : orders;
if (!isarray(orders)) {
orders = orders == null ? [] : [orders];
}
return baseorderby(collection, iteratees, orders);
}
/**
* creates an array of elements split into two groups, the first of which
* contains elements `predicate` returns truthy for, the second of which
* contains elements `predicate` returns falsey for. the predicate is
* invoked with one argument: (value).
*
* @static
* @memberof _
* @since 3.0.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @returns {array} returns the array of grouped elements.
* @example
*
* var users = [
* { 'user': 'barney', 'age': 36, 'active': false },
* { 'user': 'fred', 'age': 40, 'active': true },
* { 'user': 'pebbles', 'age': 1, 'active': false }
* ];
*
* _.partition(users, function(o) { return o.active; });
* // => objects for [['fred'], ['barney', 'pebbles']]
*
* // the `_.matches` iteratee shorthand.
* _.partition(users, { 'age': 1, 'active': false });
* // => objects for [['pebbles'], ['barney', 'fred']]
*
* // the `_.matchesproperty` iteratee shorthand.
* _.partition(users, ['active', false]);
* // => objects for [['barney', 'pebbles'], ['fred']]
*
* // the `_.property` iteratee shorthand.
* _.partition(users, 'active');
* // => objects for [['fred'], ['barney', 'pebbles']]
*/
var partition = createaggregator(function(result, value, key) {
result[key ? 0 : 1].push(value);
}, function() { return [[], []]; });
/**
* reduces `collection` to a value which is the accumulated result of running
* each element in `collection` thru `iteratee`, where each successive
* invocation is supplied the return value of the previous. if `accumulator`
* is not given, the first element of `collection` is used as the initial
* value. the iteratee is invoked with four arguments:
* (accumulator, value, index|key, collection).
*
* many lodash methods are guarded to work as iteratees for methods like
* `_.reduce`, `_.reduceright`, and `_.transform`.
*
* the guarded methods are:
* `assign`, `defaults`, `defaultsdeep`, `includes`, `merge`, `orderby`,
* and `sortby`
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @param {*} [accumulator] the initial value.
* @returns {*} returns the accumulated value.
* @see _.reduceright
* @example
*
* _.reduce([1, 2], function(sum, n) {
* return sum + n;
* }, 0);
* // => 3
*
* _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
* (result[value] || (result[value] = [])).push(key);
* return result;
* }, {});
* // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
*/
function reduce(collection, iteratee, accumulator) {
var func = isarray(collection) ? arrayreduce : basereduce,
initaccum = arguments.length < 3;
return func(collection, getiteratee(iteratee, 4), accumulator, initaccum, baseeach);
}
/**
* this method is like `_.reduce` except that it iterates over elements of
* `collection` from right to left.
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @param {*} [accumulator] the initial value.
* @returns {*} returns the accumulated value.
* @see _.reduce
* @example
*
* var array = [[0, 1], [2, 3], [4, 5]];
*
* _.reduceright(array, function(flattened, other) {
* return flattened.concat(other);
* }, []);
* // => [4, 5, 2, 3, 0, 1]
*/
function reduceright(collection, iteratee, accumulator) {
var func = isarray(collection) ? arrayreduceright : basereduce,
initaccum = arguments.length < 3;
return func(collection, getiteratee(iteratee, 4), accumulator, initaccum, baseeachright);
}
/**
* the opposite of `_.filter`; this method returns the elements of `collection`
* that `predicate` does **not** return truthy for.
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @returns {array} returns the new filtered array.
* @see _.filter
* @example
*
* var users = [
* { 'user': 'barney', 'age': 36, 'active': false },
* { 'user': 'fred', 'age': 40, 'active': true }
* ];
*
* _.reject(users, function(o) { return !o.active; });
* // => objects for ['fred']
*
* // the `_.matches` iteratee shorthand.
* _.reject(users, { 'age': 40, 'active': true });
* // => objects for ['barney']
*
* // the `_.matchesproperty` iteratee shorthand.
* _.reject(users, ['active', false]);
* // => objects for ['fred']
*
* // the `_.property` iteratee shorthand.
* _.reject(users, 'active');
* // => objects for ['barney']
*/
function reject(collection, predicate) {
var func = isarray(collection) ? arrayfilter : basefilter;
return func(collection, negate(getiteratee(predicate, 3)));
}
/**
* gets a random element from `collection`.
*
* @static
* @memberof _
* @since 2.0.0
* @category collection
* @param {array|object} collection the collection to sample.
* @returns {*} returns the random element.
* @example
*
* _.sample([1, 2, 3, 4]);
* // => 2
*/
function sample(collection) {
var func = isarray(collection) ? arraysample : basesample;
return func(collection);
}
/**
* gets `n` random elements at unique keys from `collection` up to the
* size of `collection`.
*
* @static
* @memberof _
* @since 4.0.0
* @category collection
* @param {array|object} collection the collection to sample.
* @param {number} [n=1] the number of elements to sample.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {array} returns the random elements.
* @example
*
* _.samplesize([1, 2, 3], 2);
* // => [3, 1]
*
* _.samplesize([1, 2, 3], 4);
* // => [2, 3, 1]
*/
function samplesize(collection, n, guard) {
if ((guard ? isiterateecall(collection, n, guard) : n === undefined)) {
n = 1;
} else {
n = tointeger(n);
}
var func = isarray(collection) ? arraysamplesize : basesamplesize;
return func(collection, n);
}
/**
* creates an array of shuffled values, using a version of the
* [fisher-yates shuffle](https://en.wikipedia.org/wiki/fisher-yates_shuffle).
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object} collection the collection to shuffle.
* @returns {array} returns the new shuffled array.
* @example
*
* _.shuffle([1, 2, 3, 4]);
* // => [4, 1, 3, 2]
*/
function shuffle(collection) {
var func = isarray(collection) ? arrayshuffle : baseshuffle;
return func(collection);
}
/**
* gets the size of `collection` by returning its length for array-like
* values or the number of own enumerable string keyed properties for objects.
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object|string} collection the collection to inspect.
* @returns {number} returns the collection size.
* @example
*
* _.size([1, 2, 3]);
* // => 3
*
* _.size({ 'a': 1, 'b': 2 });
* // => 2
*
* _.size('pebbles');
* // => 7
*/
function size(collection) {
if (collection == null) {
return 0;
}
if (isarraylike(collection)) {
return isstring(collection) ? stringsize(collection) : collection.length;
}
var tag = gettag(collection);
if (tag == maptag || tag == settag) {
return collection.size;
}
return basekeys(collection).length;
}
/**
* checks if `predicate` returns truthy for **any** element of `collection`.
* iteration is stopped once `predicate` returns truthy. the predicate is
* invoked with three arguments: (value, index|key, collection).
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {boolean} returns `true` if any element passes the predicate check,
* else `false`.
* @example
*
* _.some([null, 0, 'yes', false], boolean);
* // => true
*
* var users = [
* { 'user': 'barney', 'active': true },
* { 'user': 'fred', 'active': false }
* ];
*
* // the `_.matches` iteratee shorthand.
* _.some(users, { 'user': 'barney', 'active': false });
* // => false
*
* // the `_.matchesproperty` iteratee shorthand.
* _.some(users, ['active', false]);
* // => true
*
* // the `_.property` iteratee shorthand.
* _.some(users, 'active');
* // => true
*/
function some(collection, predicate, guard) {
var func = isarray(collection) ? arraysome : basesome;
if (guard && isiterateecall(collection, predicate, guard)) {
predicate = undefined;
}
return func(collection, getiteratee(predicate, 3));
}
/**
* creates an array of elements, sorted in ascending order by the results of
* running each element in a collection thru each iteratee. this method
* performs a stable sort, that is, it preserves the original sort order of
* equal elements. the iteratees are invoked with one argument: (value).
*
* @static
* @memberof _
* @since 0.1.0
* @category collection
* @param {array|object} collection the collection to iterate over.
* @param {...(function|function[])} [iteratees=[_.identity]]
* the iteratees to sort by.
* @returns {array} returns the new sorted array.
* @example
*
* var users = [
* { 'user': 'fred', 'age': 48 },
* { 'user': 'barney', 'age': 36 },
* { 'user': 'fred', 'age': 30 },
* { 'user': 'barney', 'age': 34 }
* ];
*
* _.sortby(users, [function(o) { return o.user; }]);
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
*
* _.sortby(users, ['user', 'age']);
* // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
*/
var sortby = baserest(function(collection, iteratees) {
if (collection == null) {
return [];
}
var length = iteratees.length;
if (length > 1 && isiterateecall(collection, iteratees[0], iteratees[1])) {
iteratees = [];
} else if (length > 2 && isiterateecall(iteratees[0], iteratees[1], iteratees[2])) {
iteratees = [iteratees[0]];
}
return baseorderby(collection, baseflatten(iteratees, 1), []);
});
/*------------------------------------------------------------------------*/
/**
* gets the timestamp of the number of milliseconds that have elapsed since
* the unix epoch (1 january 1970 00:00:00 utc).
*
* @static
* @memberof _
* @since 2.4.0
* @category date
* @returns {number} returns the timestamp.
* @example
*
* _.defer(function(stamp) {
* console.log(_.now() - stamp);
* }, _.now());
* // => logs the number of milliseconds it took for the deferred invocation.
*/
var now = ctxnow || function() {
return root.date.now();
};
/*------------------------------------------------------------------------*/
/**
* the opposite of `_.before`; this method creates a function that invokes
* `func` once it's called `n` or more times.
*
* @static
* @memberof _
* @since 0.1.0
* @category function
* @param {number} n the number of calls before `func` is invoked.
* @param {function} func the function to restrict.
* @returns {function} returns the new restricted function.
* @example
*
* var saves = ['profile', 'settings'];
*
* var done = _.after(saves.length, function() {
* console.log('done saving!');
* });
*
* _.foreach(saves, function(type) {
* asyncsave({ 'type': type, 'complete': done });
* });
* // => logs 'done saving!' after the two async saves have completed.
*/
function after(n, func) {
if (typeof func != 'function') {
throw new typeerror(func_error_text);
}
n = tointeger(n);
return function() {
if (--n < 1) {
return func.apply(this, arguments);
}
};
}
/**
* creates a function that invokes `func`, with up to `n` arguments,
* ignoring any additional arguments.
*
* @static
* @memberof _
* @since 3.0.0
* @category function
* @param {function} func the function to cap arguments for.
* @param {number} [n=func.length] the arity cap.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {function} returns the new capped function.
* @example
*
* _.map(['6', '8', '10'], _.ary(parseint, 1));
* // => [6, 8, 10]
*/
function ary(func, n, guard) {
n = guard ? undefined : n;
n = (func && n == null) ? func.length : n;
return createwrap(func, wrap_ary_flag, undefined, undefined, undefined, undefined, n);
}
/**
* creates a function that invokes `func`, with the `this` binding and arguments
* of the created function, while it's called less than `n` times. subsequent
* calls to the created function return the result of the last `func` invocation.
*
* @static
* @memberof _
* @since 3.0.0
* @category function
* @param {number} n the number of calls at which `func` is no longer invoked.
* @param {function} func the function to restrict.
* @returns {function} returns the new restricted function.
* @example
*
* jquery(element).on('click', _.before(5, addcontacttolist));
* // => allows adding up to 4 contacts to the list.
*/
function before(n, func) {
var result;
if (typeof func != 'function') {
throw new typeerror(func_error_text);
}
n = tointeger(n);
return function() {
if (--n > 0) {
result = func.apply(this, arguments);
}
if (n <= 1) {
func = undefined;
}
return result;
};
}
/**
* creates a function that invokes `func` with the `this` binding of `thisarg`
* and `partials` prepended to the arguments it receives.
*
* the `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for partially applied arguments.
*
* **note:** unlike native `function#bind`, this method doesn't set the "length"
* property of bound functions.
*
* @static
* @memberof _
* @since 0.1.0
* @category function
* @param {function} func the function to bind.
* @param {*} thisarg the `this` binding of `func`.
* @param {...*} [partials] the arguments to be partially applied.
* @returns {function} returns the new bound function.
* @example
*
* function greet(greeting, punctuation) {
* return greeting + ' ' + this.user + punctuation;
* }
*
* var object = { 'user': 'fred' };
*
* var bound = _.bind(greet, object, 'hi');
* bound('!');
* // => 'hi fred!'
*
* // bound with placeholders.
* var bound = _.bind(greet, object, _, '!');
* bound('hi');
* // => 'hi fred!'
*/
var bind = baserest(function(func, thisarg, partials) {
var bitmask = wrap_bind_flag;
if (partials.length) {
var holders = replaceholders(partials, getholder(bind));
bitmask |= wrap_partial_flag;
}
return createwrap(func, bitmask, thisarg, partials, holders);
});
/**
* creates a function that invokes the method at `object[key]` with `partials`
* prepended to the arguments it receives.
*
* this method differs from `_.bind` by allowing bound functions to reference
* methods that may be redefined or don't yet exist. see
* [peter michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
* for more details.
*
* the `_.bindkey.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
* @static
* @memberof _
* @since 0.10.0
* @category function
* @param {object} object the object to invoke the method on.
* @param {string} key the key of the method.
* @param {...*} [partials] the arguments to be partially applied.
* @returns {function} returns the new bound function.
* @example
*
* var object = {
* 'user': 'fred',
* 'greet': function(greeting, punctuation) {
* return greeting + ' ' + this.user + punctuation;
* }
* };
*
* var bound = _.bindkey(object, 'greet', 'hi');
* bound('!');
* // => 'hi fred!'
*
* object.greet = function(greeting, punctuation) {
* return greeting + 'ya ' + this.user + punctuation;
* };
*
* bound('!');
* // => 'hiya fred!'
*
* // bound with placeholders.
* var bound = _.bindkey(object, 'greet', _, '!');
* bound('hi');
* // => 'hiya fred!'
*/
var bindkey = baserest(function(object, key, partials) {
var bitmask = wrap_bind_flag | wrap_bind_key_flag;
if (partials.length) {
var holders = replaceholders(partials, getholder(bindkey));
bitmask |= wrap_partial_flag;
}
return createwrap(key, bitmask, object, partials, holders);
});
/**
* creates a function that accepts arguments of `func` and either invokes
* `func` returning its result, if at least `arity` number of arguments have
* been provided, or returns a function that accepts the remaining `func`
* arguments, and so on. the arity of `func` may be specified if `func.length`
* is not sufficient.
*
* the `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for provided arguments.
*
* **note:** this method doesn't set the "length" property of curried functions.
*
* @static
* @memberof _
* @since 2.0.0
* @category function
* @param {function} func the function to curry.
* @param {number} [arity=func.length] the arity of `func`.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {function} returns the new curried function.
* @example
*
* var abc = function(a, b, c) {
* return [a, b, c];
* };
*
* var curried = _.curry(abc);
*
* curried(1)(2)(3);
* // => [1, 2, 3]
*
* curried(1, 2)(3);
* // => [1, 2, 3]
*
* curried(1, 2, 3);
* // => [1, 2, 3]
*
* // curried with placeholders.
* curried(1)(_, 3)(2);
* // => [1, 2, 3]
*/
function curry(func, arity, guard) {
arity = guard ? undefined : arity;
var result = createwrap(func, wrap_curry_flag, undefined, undefined, undefined, undefined, undefined, arity);
result.placeholder = curry.placeholder;
return result;
}
/**
* this method is like `_.curry` except that arguments are applied to `func`
* in the manner of `_.partialright` instead of `_.partial`.
*
* the `_.curryright.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for provided arguments.
*
* **note:** this method doesn't set the "length" property of curried functions.
*
* @static
* @memberof _
* @since 3.0.0
* @category function
* @param {function} func the function to curry.
* @param {number} [arity=func.length] the arity of `func`.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {function} returns the new curried function.
* @example
*
* var abc = function(a, b, c) {
* return [a, b, c];
* };
*
* var curried = _.curryright(abc);
*
* curried(3)(2)(1);
* // => [1, 2, 3]
*
* curried(2, 3)(1);
* // => [1, 2, 3]
*
* curried(1, 2, 3);
* // => [1, 2, 3]
*
* // curried with placeholders.
* curried(3)(1, _)(2);
* // => [1, 2, 3]
*/
function curryright(func, arity, guard) {
arity = guard ? undefined : arity;
var result = createwrap(func, wrap_curry_right_flag, undefined, undefined, undefined, undefined, undefined, arity);
result.placeholder = curryright.placeholder;
return result;
}
/**
* creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked. the debounced function comes with a `cancel` method to cancel
* delayed `func` invocations and a `flush` method to immediately invoke them.
* provide `options` to indicate whether `func` should be invoked on the
* leading and/or trailing edge of the `wait` timeout. the `func` is invoked
* with the last arguments provided to the debounced function. subsequent
* calls to the debounced function return the result of the last `func`
* invocation.
*
* **note:** if `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the debounced function
* is invoked more than once during the `wait` timeout.
*
* if `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until to the next tick, similar to `settimeout` with a timeout of `0`.
*
* see [david corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `_.debounce` and `_.throttle`.
*
* @static
* @memberof _
* @since 0.1.0
* @category function
* @param {function} func the function to debounce.
* @param {number} [wait=0] the number of milliseconds to delay.
* @param {object} [options={}] the options object.
* @param {boolean} [options.leading=false]
* specify invoking on the leading edge of the timeout.
* @param {number} [options.maxwait]
* the maximum time `func` is allowed to be delayed before it's invoked.
* @param {boolean} [options.trailing=true]
* specify invoking on the trailing edge of the timeout.
* @returns {function} returns the new debounced function.
* @example
*
* // avoid costly calculations while the window size is in flux.
* jquery(window).on('resize', _.debounce(calculatelayout, 150));
*
* // invoke `sendmail` when clicked, debouncing subsequent calls.
* jquery(element).on('click', _.debounce(sendmail, 300, {
* 'leading': true,
* 'trailing': false
* }));
*
* // ensure `batchlog` is invoked once after 1 second of debounced calls.
* var debounced = _.debounce(batchlog, 250, { 'maxwait': 1000 });
* var source = new eventsource('/stream');
* jquery(source).on('message', debounced);
*
* // cancel the trailing debounced invocation.
* jquery(window).on('popstate', debounced.cancel);
*/
function debounce(func, wait, options) {
var lastargs,
lastthis,
maxwait,
result,
timerid,
lastcalltime,
lastinvoketime = 0,
leading = false,
maxing = false,
trailing = true;
if (typeof func != 'function') {
throw new typeerror(func_error_text);
}
wait = tonumber(wait) || 0;
if (isobject(options)) {
leading = !!options.leading;
maxing = 'maxwait' in options;
maxwait = maxing ? nativemax(tonumber(options.maxwait) || 0, wait) : maxwait;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
function invokefunc(time) {
var args = lastargs,
thisarg = lastthis;
lastargs = lastthis = undefined;
lastinvoketime = time;
result = func.apply(thisarg, args);
return result;
}
function leadingedge(time) {
// reset any `maxwait` timer.
lastinvoketime = time;
// start the timer for the trailing edge.
timerid = settimeout(timerexpired, wait);
// invoke the leading edge.
return leading ? invokefunc(time) : result;
}
function remainingwait(time) {
var timesincelastcall = time - lastcalltime,
timesincelastinvoke = time - lastinvoketime,
timewaiting = wait - timesincelastcall;
return maxing
? nativemin(timewaiting, maxwait - timesincelastinvoke)
: timewaiting;
}
function shouldinvoke(time) {
var timesincelastcall = time - lastcalltime,
timesincelastinvoke = time - lastinvoketime;
// either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxwait` limit.
return (lastcalltime === undefined || (timesincelastcall >= wait) ||
(timesincelastcall < 0) || (maxing && timesincelastinvoke >= maxwait));
}
function timerexpired() {
var time = now();
if (shouldinvoke(time)) {
return trailingedge(time);
}
// restart the timer.
timerid = settimeout(timerexpired, remainingwait(time));
}
function trailingedge(time) {
timerid = undefined;
// only invoke if we have `lastargs` which means `func` has been
// debounced at least once.
if (trailing && lastargs) {
return invokefunc(time);
}
lastargs = lastthis = undefined;
return result;
}
function cancel() {
if (timerid !== undefined) {
cleartimeout(timerid);
}
lastinvoketime = 0;
lastargs = lastcalltime = lastthis = timerid = undefined;
}
function flush() {
return timerid === undefined ? result : trailingedge(now());
}
function debounced() {
var time = now(),
isinvoking = shouldinvoke(time);
lastargs = arguments;
lastthis = this;
lastcalltime = time;
if (isinvoking) {
if (timerid === undefined) {
return leadingedge(lastcalltime);
}
if (maxing) {
// handle invocations in a tight loop.
cleartimeout(timerid);
timerid = settimeout(timerexpired, wait);
return invokefunc(lastcalltime);
}
}
if (timerid === undefined) {
timerid = settimeout(timerexpired, wait);
}
return result;
}
debounced.cancel = cancel;
debounced.flush = flush;
return debounced;
}
/**
* defers invoking the `func` until the current call stack has cleared. any
* additional arguments are provided to `func` when it's invoked.
*
* @static
* @memberof _
* @since 0.1.0
* @category function
* @param {function} func the function to defer.
* @param {...*} [args] the arguments to invoke `func` with.
* @returns {number} returns the timer id.
* @example
*
* _.defer(function(text) {
* console.log(text);
* }, 'deferred');
* // => logs 'deferred' after one millisecond.
*/
var defer = baserest(function(func, args) {
return basedelay(func, 1, args);
});
/**
* invokes `func` after `wait` milliseconds. any additional arguments are
* provided to `func` when it's invoked.
*
* @static
* @memberof _
* @since 0.1.0
* @category function
* @param {function} func the function to delay.
* @param {number} wait the number of milliseconds to delay invocation.
* @param {...*} [args] the arguments to invoke `func` with.
* @returns {number} returns the timer id.
* @example
*
* _.delay(function(text) {
* console.log(text);
* }, 1000, 'later');
* // => logs 'later' after one second.
*/
var delay = baserest(function(func, wait, args) {
return basedelay(func, tonumber(wait) || 0, args);
});
/**
* creates a function that invokes `func` with arguments reversed.
*
* @static
* @memberof _
* @since 4.0.0
* @category function
* @param {function} func the function to flip arguments for.
* @returns {function} returns the new flipped function.
* @example
*
* var flipped = _.flip(function() {
* return _.toarray(arguments);
* });
*
* flipped('a', 'b', 'c', 'd');
* // => ['d', 'c', 'b', 'a']
*/
function flip(func) {
return createwrap(func, wrap_flip_flag);
}
/**
* creates a function that memoizes the result of `func`. if `resolver` is
* provided, it determines the cache key for storing the result based on the
* arguments provided to the memoized function. by default, the first argument
* provided to the memoized function is used as the map cache key. the `func`
* is invoked with the `this` binding of the memoized function.
*
* **note:** the cache is exposed as the `cache` property on the memoized
* function. its creation may be customized by replacing the `_.memoize.cache`
* constructor with one whose instances implement the
* [`map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
* method interface of `clear`, `delete`, `get`, `has`, and `set`.
*
* @static
* @memberof _
* @since 0.1.0
* @category function
* @param {function} func the function to have its output memoized.
* @param {function} [resolver] the function to resolve the cache key.
* @returns {function} returns the new memoized function.
* @example
*
* var object = { 'a': 1, 'b': 2 };
* var other = { 'c': 3, 'd': 4 };
*
* var values = _.memoize(_.values);
* values(object);
* // => [1, 2]
*
* values(other);
* // => [3, 4]
*
* object.a = 2;
* values(object);
* // => [1, 2]
*
* // modify the result cache.
* values.cache.set(object, ['a', 'b']);
* values(object);
* // => ['a', 'b']
*
* // replace `_.memoize.cache`.
* _.memoize.cache = weakmap;
*/
function memoize(func, resolver) {
if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
throw new typeerror(func_error_text);
}
var memoized = function() {
var args = arguments,
key = resolver ? resolver.apply(this, args) : args[0],
cache = memoized.cache;
if (cache.has(key)) {
return cache.get(key);
}
var result = func.apply(this, args);
memoized.cache = cache.set(key, result) || cache;
return result;
};
memoized.cache = new (memoize.cache || mapcache);
return memoized;
}
// expose `mapcache`.
memoize.cache = mapcache;
/**
* creates a function that negates the result of the predicate `func`. the
* `func` predicate is invoked with the `this` binding and arguments of the
* created function.
*
* @static
* @memberof _
* @since 3.0.0
* @category function
* @param {function} predicate the predicate to negate.
* @returns {function} returns the new negated function.
* @example
*
* function iseven(n) {
* return n % 2 == 0;
* }
*
* _.filter([1, 2, 3, 4, 5, 6], _.negate(iseven));
* // => [1, 3, 5]
*/
function negate(predicate) {
if (typeof predicate != 'function') {
throw new typeerror(func_error_text);
}
return function() {
var args = arguments;
switch (args.length) {
case 0: return !predicate.call(this);
case 1: return !predicate.call(this, args[0]);
case 2: return !predicate.call(this, args[0], args[1]);
case 3: return !predicate.call(this, args[0], args[1], args[2]);
}
return !predicate.apply(this, args);
};
}
/**
* creates a function that is restricted to invoking `func` once. repeat calls
* to the function return the value of the first invocation. the `func` is
* invoked with the `this` binding and arguments of the created function.
*
* @static
* @memberof _
* @since 0.1.0
* @category function
* @param {function} func the function to restrict.
* @returns {function} returns the new restricted function.
* @example
*
* var initialize = _.once(createapplication);
* initialize();
* initialize();
* // => `createapplication` is invoked once
*/
function once(func) {
return before(2, func);
}
/**
* creates a function that invokes `func` with its arguments transformed.
*
* @static
* @since 4.0.0
* @memberof _
* @category function
* @param {function} func the function to wrap.
* @param {...(function|function[])} [transforms=[_.identity]]
* the argument transforms.
* @returns {function} returns the new function.
* @example
*
* function doubled(n) {
* return n * 2;
* }
*
* function square(n) {
* return n * n;
* }
*
* var func = _.overargs(function(x, y) {
* return [x, y];
* }, [square, doubled]);
*
* func(9, 3);
* // => [81, 6]
*
* func(10, 5);
* // => [100, 10]
*/
var overargs = castrest(function(func, transforms) {
transforms = (transforms.length == 1 && isarray(transforms[0]))
? arraymap(transforms[0], baseunary(getiteratee()))
: arraymap(baseflatten(transforms, 1), baseunary(getiteratee()));
var funcslength = transforms.length;
return baserest(function(args) {
var index = -1,
length = nativemin(args.length, funcslength);
while (++index < length) {
args[index] = transforms[index].call(this, args[index]);
}
return apply(func, this, args);
});
});
/**
* creates a function that invokes `func` with `partials` prepended to the
* arguments it receives. this method is like `_.bind` except it does **not**
* alter the `this` binding.
*
* the `_.partial.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
* **note:** this method doesn't set the "length" property of partially
* applied functions.
*
* @static
* @memberof _
* @since 0.2.0
* @category function
* @param {function} func the function to partially apply arguments to.
* @param {...*} [partials] the arguments to be partially applied.
* @returns {function} returns the new partially applied function.
* @example
*
* function greet(greeting, name) {
* return greeting + ' ' + name;
* }
*
* var sayhelloto = _.partial(greet, 'hello');
* sayhelloto('fred');
* // => 'hello fred'
*
* // partially applied with placeholders.
* var greetfred = _.partial(greet, _, 'fred');
* greetfred('hi');
* // => 'hi fred'
*/
var partial = baserest(function(func, partials) {
var holders = replaceholders(partials, getholder(partial));
return createwrap(func, wrap_partial_flag, undefined, partials, holders);
});
/**
* this method is like `_.partial` except that partially applied arguments
* are appended to the arguments it receives.
*
* the `_.partialright.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
* **note:** this method doesn't set the "length" property of partially
* applied functions.
*
* @static
* @memberof _
* @since 1.0.0
* @category function
* @param {function} func the function to partially apply arguments to.
* @param {...*} [partials] the arguments to be partially applied.
* @returns {function} returns the new partially applied function.
* @example
*
* function greet(greeting, name) {
* return greeting + ' ' + name;
* }
*
* var greetfred = _.partialright(greet, 'fred');
* greetfred('hi');
* // => 'hi fred'
*
* // partially applied with placeholders.
* var sayhelloto = _.partialright(greet, 'hello', _);
* sayhelloto('fred');
* // => 'hello fred'
*/
var partialright = baserest(function(func, partials) {
var holders = replaceholders(partials, getholder(partialright));
return createwrap(func, wrap_partial_right_flag, undefined, partials, holders);
});
/**
* creates a function that invokes `func` with arguments arranged according
* to the specified `indexes` where the argument value at the first index is
* provided as the first argument, the argument value at the second index is
* provided as the second argument, and so on.
*
* @static
* @memberof _
* @since 3.0.0
* @category function
* @param {function} func the function to rearrange arguments for.
* @param {...(number|number[])} indexes the arranged argument indexes.
* @returns {function} returns the new function.
* @example
*
* var rearged = _.rearg(function(a, b, c) {
* return [a, b, c];
* }, [2, 0, 1]);
*
* rearged('b', 'c', 'a')
* // => ['a', 'b', 'c']
*/
var rearg = flatrest(function(func, indexes) {
return createwrap(func, wrap_rearg_flag, undefined, undefined, undefined, indexes);
});
/**
* creates a function that invokes `func` with the `this` binding of the
* created function and arguments from `start` and beyond provided as
* an array.
*
* **note:** this method is based on the
* [rest parameter](https://mdn.io/rest_parameters).
*
* @static
* @memberof _
* @since 4.0.0
* @category function
* @param {function} func the function to apply a rest parameter to.
* @param {number} [start=func.length-1] the start position of the rest parameter.
* @returns {function} returns the new function.
* @example
*
* var say = _.rest(function(what, names) {
* return what + ' ' + _.initial(names).join(', ') +
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
* });
*
* say('hello', 'fred', 'barney', 'pebbles');
* // => 'hello fred, barney, & pebbles'
*/
function rest(func, start) {
if (typeof func != 'function') {
throw new typeerror(func_error_text);
}
start = start === undefined ? start : tointeger(start);
return baserest(func, start);
}
/**
* creates a function that invokes `func` with the `this` binding of the
* create function and an array of arguments much like
* [`function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
*
* **note:** this method is based on the
* [spread operator](https://mdn.io/spread_operator).
*
* @static
* @memberof _
* @since 3.2.0
* @category function
* @param {function} func the function to spread arguments over.
* @param {number} [start=0] the start position of the spread.
* @returns {function} returns the new function.
* @example
*
* var say = _.spread(function(who, what) {
* return who + ' says ' + what;
* });
*
* say(['fred', 'hello']);
* // => 'fred says hello'
*
* var numbers = promise.all([
* promise.resolve(40),
* promise.resolve(36)
* ]);
*
* numbers.then(_.spread(function(x, y) {
* return x + y;
* }));
* // => a promise of 76
*/
function spread(func, start) {
if (typeof func != 'function') {
throw new typeerror(func_error_text);
}
start = start == null ? 0 : nativemax(tointeger(start), 0);
return baserest(function(args) {
var array = args[start],
otherargs = castslice(args, 0, start);
if (array) {
arraypush(otherargs, array);
}
return apply(func, this, otherargs);
});
}
/**
* creates a throttled function that only invokes `func` at most once per
* every `wait` milliseconds. the throttled function comes with a `cancel`
* method to cancel delayed `func` invocations and a `flush` method to
* immediately invoke them. provide `options` to indicate whether `func`
* should be invoked on the leading and/or trailing edge of the `wait`
* timeout. the `func` is invoked with the last arguments provided to the
* throttled function. subsequent calls to the throttled function return the
* result of the last `func` invocation.
*
* **note:** if `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the throttled function
* is invoked more than once during the `wait` timeout.
*
* if `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until to the next tick, similar to `settimeout` with a timeout of `0`.
*
* see [david corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `_.throttle` and `_.debounce`.
*
* @static
* @memberof _
* @since 0.1.0
* @category function
* @param {function} func the function to throttle.
* @param {number} [wait=0] the number of milliseconds to throttle invocations to.
* @param {object} [options={}] the options object.
* @param {boolean} [options.leading=true]
* specify invoking on the leading edge of the timeout.
* @param {boolean} [options.trailing=true]
* specify invoking on the trailing edge of the timeout.
* @returns {function} returns the new throttled function.
* @example
*
* // avoid excessively updating the position while scrolling.
* jquery(window).on('scroll', _.throttle(updateposition, 100));
*
* // invoke `renewtoken` when the click event is fired, but not more than once every 5 minutes.
* var throttled = _.throttle(renewtoken, 300000, { 'trailing': false });
* jquery(element).on('click', throttled);
*
* // cancel the trailing throttled invocation.
* jquery(window).on('popstate', throttled.cancel);
*/
function throttle(func, wait, options) {
var leading = true,
trailing = true;
if (typeof func != 'function') {
throw new typeerror(func_error_text);
}
if (isobject(options)) {
leading = 'leading' in options ? !!options.leading : leading;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
return debounce(func, wait, {
'leading': leading,
'maxwait': wait,
'trailing': trailing
});
}
/**
* creates a function that accepts up to one argument, ignoring any
* additional arguments.
*
* @static
* @memberof _
* @since 4.0.0
* @category function
* @param {function} func the function to cap arguments for.
* @returns {function} returns the new capped function.
* @example
*
* _.map(['6', '8', '10'], _.unary(parseint));
* // => [6, 8, 10]
*/
function unary(func) {
return ary(func, 1);
}
/**
* creates a function that provides `value` to `wrapper` as its first
* argument. any additional arguments provided to the function are appended
* to those provided to the `wrapper`. the wrapper is invoked with the `this`
* binding of the created function.
*
* @static
* @memberof _
* @since 0.1.0
* @category function
* @param {*} value the value to wrap.
* @param {function} [wrapper=identity] the wrapper function.
* @returns {function} returns the new function.
* @example
*
* var p = _.wrap(_.escape, function(func, text) {
* return '' + func(text) + '
';
* });
*
* p('fred, barney, & pebbles');
* // => 'fred, barney, & pebbles
'
*/
function wrap(value, wrapper) {
return partial(castfunction(wrapper), value);
}
/*------------------------------------------------------------------------*/
/**
* casts `value` as an array if it's not one.
*
* @static
* @memberof _
* @since 4.4.0
* @category lang
* @param {*} value the value to inspect.
* @returns {array} returns the cast array.
* @example
*
* _.castarray(1);
* // => [1]
*
* _.castarray({ 'a': 1 });
* // => [{ 'a': 1 }]
*
* _.castarray('abc');
* // => ['abc']
*
* _.castarray(null);
* // => [null]
*
* _.castarray(undefined);
* // => [undefined]
*
* _.castarray();
* // => []
*
* var array = [1, 2, 3];
* console.log(_.castarray(array) === array);
* // => true
*/
function castarray() {
if (!arguments.length) {
return [];
}
var value = arguments[0];
return isarray(value) ? value : [value];
}
/**
* creates a shallow clone of `value`.
*
* **note:** this method is loosely based on the
* [structured clone algorithm](https://mdn.io/structured_clone_algorithm)
* and supports cloning arrays, array buffers, booleans, date objects, maps,
* numbers, `object` objects, regexes, sets, strings, symbols, and typed
* arrays. the own enumerable properties of `arguments` objects are cloned
* as plain objects. an empty object is returned for uncloneable values such
* as error objects, functions, dom nodes, and weakmaps.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to clone.
* @returns {*} returns the cloned value.
* @see _.clonedeep
* @example
*
* var objects = [{ 'a': 1 }, { 'b': 2 }];
*
* var shallow = _.clone(objects);
* console.log(shallow[0] === objects[0]);
* // => true
*/
function clone(value) {
return baseclone(value, clone_symbols_flag);
}
/**
* this method is like `_.clone` except that it accepts `customizer` which
* is invoked to produce the cloned value. if `customizer` returns `undefined`,
* cloning is handled by the method instead. the `customizer` is invoked with
* up to four arguments; (value [, index|key, object, stack]).
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to clone.
* @param {function} [customizer] the function to customize cloning.
* @returns {*} returns the cloned value.
* @see _.clonedeepwith
* @example
*
* function customizer(value) {
* if (_.iselement(value)) {
* return value.clonenode(false);
* }
* }
*
* var el = _.clonewith(document.body, customizer);
*
* console.log(el === document.body);
* // => false
* console.log(el.nodename);
* // => 'body'
* console.log(el.childnodes.length);
* // => 0
*/
function clonewith(value, customizer) {
customizer = typeof customizer == 'function' ? customizer : undefined;
return baseclone(value, clone_symbols_flag, customizer);
}
/**
* this method is like `_.clone` except that it recursively clones `value`.
*
* @static
* @memberof _
* @since 1.0.0
* @category lang
* @param {*} value the value to recursively clone.
* @returns {*} returns the deep cloned value.
* @see _.clone
* @example
*
* var objects = [{ 'a': 1 }, { 'b': 2 }];
*
* var deep = _.clonedeep(objects);
* console.log(deep[0] === objects[0]);
* // => false
*/
function clonedeep(value) {
return baseclone(value, clone_deep_flag | clone_symbols_flag);
}
/**
* this method is like `_.clonewith` except that it recursively clones `value`.
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to recursively clone.
* @param {function} [customizer] the function to customize cloning.
* @returns {*} returns the deep cloned value.
* @see _.clonewith
* @example
*
* function customizer(value) {
* if (_.iselement(value)) {
* return value.clonenode(true);
* }
* }
*
* var el = _.clonedeepwith(document.body, customizer);
*
* console.log(el === document.body);
* // => false
* console.log(el.nodename);
* // => 'body'
* console.log(el.childnodes.length);
* // => 20
*/
function clonedeepwith(value, customizer) {
customizer = typeof customizer == 'function' ? customizer : undefined;
return baseclone(value, clone_deep_flag | clone_symbols_flag, customizer);
}
/**
* checks if `object` conforms to `source` by invoking the predicate
* properties of `source` with the corresponding property values of `object`.
*
* **note:** this method is equivalent to `_.conforms` when `source` is
* partially applied.
*
* @static
* @memberof _
* @since 4.14.0
* @category lang
* @param {object} object the object to inspect.
* @param {object} source the object of property predicates to conform to.
* @returns {boolean} returns `true` if `object` conforms, else `false`.
* @example
*
* var object = { 'a': 1, 'b': 2 };
*
* _.conformsto(object, { 'b': function(n) { return n > 1; } });
* // => true
*
* _.conformsto(object, { 'b': function(n) { return n > 2; } });
* // => false
*/
function conformsto(object, source) {
return source == null || baseconformsto(object, source, keys(source));
}
/**
* performs a
* [`samevaluezero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* comparison between two values to determine if they are equivalent.
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to compare.
* @param {*} other the other value to compare.
* @returns {boolean} returns `true` if the values are equivalent, else `false`.
* @example
*
* var object = { 'a': 1 };
* var other = { 'a': 1 };
*
* _.eq(object, object);
* // => true
*
* _.eq(object, other);
* // => false
*
* _.eq('a', 'a');
* // => true
*
* _.eq('a', object('a'));
* // => false
*
* _.eq(nan, nan);
* // => true
*/
function eq(value, other) {
return value === other || (value !== value && other !== other);
}
/**
* checks if `value` is greater than `other`.
*
* @static
* @memberof _
* @since 3.9.0
* @category lang
* @param {*} value the value to compare.
* @param {*} other the other value to compare.
* @returns {boolean} returns `true` if `value` is greater than `other`,
* else `false`.
* @see _.lt
* @example
*
* _.gt(3, 1);
* // => true
*
* _.gt(3, 3);
* // => false
*
* _.gt(1, 3);
* // => false
*/
var gt = createrelationaloperation(basegt);
/**
* checks if `value` is greater than or equal to `other`.
*
* @static
* @memberof _
* @since 3.9.0
* @category lang
* @param {*} value the value to compare.
* @param {*} other the other value to compare.
* @returns {boolean} returns `true` if `value` is greater than or equal to
* `other`, else `false`.
* @see _.lte
* @example
*
* _.gte(3, 1);
* // => true
*
* _.gte(3, 3);
* // => true
*
* _.gte(1, 3);
* // => false
*/
var gte = createrelationaloperation(function(value, other) {
return value >= other;
});
/**
* checks if `value` is likely an `arguments` object.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is an `arguments` object,
* else `false`.
* @example
*
* _.isarguments(function() { return arguments; }());
* // => true
*
* _.isarguments([1, 2, 3]);
* // => false
*/
var isarguments = baseisarguments(function() { return arguments; }()) ? baseisarguments : function(value) {
return isobjectlike(value) && hasownproperty.call(value, 'callee') &&
!propertyisenumerable.call(value, 'callee');
};
/**
* checks if `value` is classified as an `array` object.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is an array, else `false`.
* @example
*
* _.isarray([1, 2, 3]);
* // => true
*
* _.isarray(document.body.children);
* // => false
*
* _.isarray('abc');
* // => false
*
* _.isarray(_.noop);
* // => false
*/
var isarray = array.isarray;
/**
* checks if `value` is classified as an `arraybuffer` object.
*
* @static
* @memberof _
* @since 4.3.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is an array buffer, else `false`.
* @example
*
* _.isarraybuffer(new arraybuffer(2));
* // => true
*
* _.isarraybuffer(new array(2));
* // => false
*/
var isarraybuffer = nodeisarraybuffer ? baseunary(nodeisarraybuffer) : baseisarraybuffer;
/**
* checks if `value` is array-like. a value is considered array-like if it's
* not a function and has a `value.length` that's an integer greater than or
* equal to `0` and less than or equal to `number.max_safe_integer`.
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is array-like, else `false`.
* @example
*
* _.isarraylike([1, 2, 3]);
* // => true
*
* _.isarraylike(document.body.children);
* // => true
*
* _.isarraylike('abc');
* // => true
*
* _.isarraylike(_.noop);
* // => false
*/
function isarraylike(value) {
return value != null && islength(value.length) && !isfunction(value);
}
/**
* this method is like `_.isarraylike` except that it also checks if `value`
* is an object.
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is an array-like object,
* else `false`.
* @example
*
* _.isarraylikeobject([1, 2, 3]);
* // => true
*
* _.isarraylikeobject(document.body.children);
* // => true
*
* _.isarraylikeobject('abc');
* // => false
*
* _.isarraylikeobject(_.noop);
* // => false
*/
function isarraylikeobject(value) {
return isobjectlike(value) && isarraylike(value);
}
/**
* checks if `value` is classified as a boolean primitive or object.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a boolean, else `false`.
* @example
*
* _.isboolean(false);
* // => true
*
* _.isboolean(null);
* // => false
*/
function isboolean(value) {
return value === true || value === false ||
(isobjectlike(value) && basegettag(value) == booltag);
}
/**
* checks if `value` is a buffer.
*
* @static
* @memberof _
* @since 4.3.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a buffer, else `false`.
* @example
*
* _.isbuffer(new buffer(2));
* // => true
*
* _.isbuffer(new uint8array(2));
* // => false
*/
var isbuffer = nativeisbuffer || stubfalse;
/**
* checks if `value` is classified as a `date` object.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a date object, else `false`.
* @example
*
* _.isdate(new date);
* // => true
*
* _.isdate('mon april 23 2012');
* // => false
*/
var isdate = nodeisdate ? baseunary(nodeisdate) : baseisdate;
/**
* checks if `value` is likely a dom element.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a dom element, else `false`.
* @example
*
* _.iselement(document.body);
* // => true
*
* _.iselement('');
* // => false
*/
function iselement(value) {
return isobjectlike(value) && value.nodetype === 1 && !isplainobject(value);
}
/**
* checks if `value` is an empty object, collection, map, or set.
*
* objects are considered empty if they have no own enumerable string keyed
* properties.
*
* array-like values such as `arguments` objects, arrays, buffers, strings, or
* jquery-like collections are considered empty if they have a `length` of `0`.
* similarly, maps and sets are considered empty if they have a `size` of `0`.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is empty, else `false`.
* @example
*
* _.isempty(null);
* // => true
*
* _.isempty(true);
* // => true
*
* _.isempty(1);
* // => true
*
* _.isempty([1, 2, 3]);
* // => false
*
* _.isempty({ 'a': 1 });
* // => false
*/
function isempty(value) {
if (value == null) {
return true;
}
if (isarraylike(value) &&
(isarray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
isbuffer(value) || istypedarray(value) || isarguments(value))) {
return !value.length;
}
var tag = gettag(value);
if (tag == maptag || tag == settag) {
return !value.size;
}
if (isprototype(value)) {
return !basekeys(value).length;
}
for (var key in value) {
if (hasownproperty.call(value, key)) {
return false;
}
}
return true;
}
/**
* performs a deep comparison between two values to determine if they are
* equivalent.
*
* **note:** this method supports comparing arrays, array buffers, booleans,
* date objects, error objects, maps, numbers, `object` objects, regexes,
* sets, strings, symbols, and typed arrays. `object` objects are compared
* by their own, not inherited, enumerable properties. functions and dom
* nodes are compared by strict equality, i.e. `===`.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to compare.
* @param {*} other the other value to compare.
* @returns {boolean} returns `true` if the values are equivalent, else `false`.
* @example
*
* var object = { 'a': 1 };
* var other = { 'a': 1 };
*
* _.isequal(object, other);
* // => true
*
* object === other;
* // => false
*/
function isequal(value, other) {
return baseisequal(value, other);
}
/**
* this method is like `_.isequal` except that it accepts `customizer` which
* is invoked to compare values. if `customizer` returns `undefined`, comparisons
* are handled by the method instead. the `customizer` is invoked with up to
* six arguments: (objvalue, othvalue [, index|key, object, other, stack]).
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to compare.
* @param {*} other the other value to compare.
* @param {function} [customizer] the function to customize comparisons.
* @returns {boolean} returns `true` if the values are equivalent, else `false`.
* @example
*
* function isgreeting(value) {
* return /^h(?:i|ello)$/.test(value);
* }
*
* function customizer(objvalue, othvalue) {
* if (isgreeting(objvalue) && isgreeting(othvalue)) {
* return true;
* }
* }
*
* var array = ['hello', 'goodbye'];
* var other = ['hi', 'goodbye'];
*
* _.isequalwith(array, other, customizer);
* // => true
*/
function isequalwith(value, other, customizer) {
customizer = typeof customizer == 'function' ? customizer : undefined;
var result = customizer ? customizer(value, other) : undefined;
return result === undefined ? baseisequal(value, other, undefined, customizer) : !!result;
}
/**
* checks if `value` is an `error`, `evalerror`, `rangeerror`, `referenceerror`,
* `syntaxerror`, `typeerror`, or `urierror` object.
*
* @static
* @memberof _
* @since 3.0.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is an error object, else `false`.
* @example
*
* _.iserror(new error);
* // => true
*
* _.iserror(error);
* // => false
*/
function iserror(value) {
if (!isobjectlike(value)) {
return false;
}
var tag = basegettag(value);
return tag == errortag || tag == domexctag ||
(typeof value.message == 'string' && typeof value.name == 'string' && !isplainobject(value));
}
/**
* checks if `value` is a finite primitive number.
*
* **note:** this method is based on
* [`number.isfinite`](https://mdn.io/number/isfinite).
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a finite number, else `false`.
* @example
*
* _.isfinite(3);
* // => true
*
* _.isfinite(number.min_value);
* // => true
*
* _.isfinite(infinity);
* // => false
*
* _.isfinite('3');
* // => false
*/
function isfinite(value) {
return typeof value == 'number' && nativeisfinite(value);
}
/**
* checks if `value` is classified as a `function` object.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a function, else `false`.
* @example
*
* _.isfunction(_);
* // => true
*
* _.isfunction(/abc/);
* // => false
*/
function isfunction(value) {
if (!isobject(value)) {
return false;
}
// the use of `object#tostring` avoids issues with the `typeof` operator
// in safari 9 which returns 'object' for typed arrays and other constructors.
var tag = basegettag(value);
return tag == functag || tag == gentag || tag == asynctag || tag == proxytag;
}
/**
* checks if `value` is an integer.
*
* **note:** this method is based on
* [`number.isinteger`](https://mdn.io/number/isinteger).
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is an integer, else `false`.
* @example
*
* _.isinteger(3);
* // => true
*
* _.isinteger(number.min_value);
* // => false
*
* _.isinteger(infinity);
* // => false
*
* _.isinteger('3');
* // => false
*/
function isinteger(value) {
return typeof value == 'number' && value == tointeger(value);
}
/**
* checks if `value` is a valid array-like length.
*
* **note:** this method is loosely based on
* [`tolength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a valid length, else `false`.
* @example
*
* _.islength(3);
* // => true
*
* _.islength(number.min_value);
* // => false
*
* _.islength(infinity);
* // => false
*
* _.islength('3');
* // => false
*/
function islength(value) {
return typeof value == 'number' &&
value > -1 && value % 1 == 0 && value <= max_safe_integer;
}
/**
* checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `object`. (e.g. arrays, functions, objects, regexes, `new number(0)`, and `new string('')`)
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is an object, else `false`.
* @example
*
* _.isobject({});
* // => true
*
* _.isobject([1, 2, 3]);
* // => true
*
* _.isobject(_.noop);
* // => true
*
* _.isobject(null);
* // => false
*/
function isobject(value) {
var type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
/**
* checks if `value` is object-like. a value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isobjectlike({});
* // => true
*
* _.isobjectlike([1, 2, 3]);
* // => true
*
* _.isobjectlike(_.noop);
* // => false
*
* _.isobjectlike(null);
* // => false
*/
function isobjectlike(value) {
return value != null && typeof value == 'object';
}
/**
* checks if `value` is classified as a `map` object.
*
* @static
* @memberof _
* @since 4.3.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a map, else `false`.
* @example
*
* _.ismap(new map);
* // => true
*
* _.ismap(new weakmap);
* // => false
*/
var ismap = nodeismap ? baseunary(nodeismap) : baseismap;
/**
* performs a partial deep comparison between `object` and `source` to
* determine if `object` contains equivalent property values.
*
* **note:** this method is equivalent to `_.matches` when `source` is
* partially applied.
*
* partial comparisons will match empty array and empty object `source`
* values against any array or object value, respectively. see `_.isequal`
* for a list of supported value comparisons.
*
* @static
* @memberof _
* @since 3.0.0
* @category lang
* @param {object} object the object to inspect.
* @param {object} source the object of property values to match.
* @returns {boolean} returns `true` if `object` is a match, else `false`.
* @example
*
* var object = { 'a': 1, 'b': 2 };
*
* _.ismatch(object, { 'b': 2 });
* // => true
*
* _.ismatch(object, { 'b': 1 });
* // => false
*/
function ismatch(object, source) {
return object === source || baseismatch(object, source, getmatchdata(source));
}
/**
* this method is like `_.ismatch` except that it accepts `customizer` which
* is invoked to compare values. if `customizer` returns `undefined`, comparisons
* are handled by the method instead. the `customizer` is invoked with five
* arguments: (objvalue, srcvalue, index|key, object, source).
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {object} object the object to inspect.
* @param {object} source the object of property values to match.
* @param {function} [customizer] the function to customize comparisons.
* @returns {boolean} returns `true` if `object` is a match, else `false`.
* @example
*
* function isgreeting(value) {
* return /^h(?:i|ello)$/.test(value);
* }
*
* function customizer(objvalue, srcvalue) {
* if (isgreeting(objvalue) && isgreeting(srcvalue)) {
* return true;
* }
* }
*
* var object = { 'greeting': 'hello' };
* var source = { 'greeting': 'hi' };
*
* _.ismatchwith(object, source, customizer);
* // => true
*/
function ismatchwith(object, source, customizer) {
customizer = typeof customizer == 'function' ? customizer : undefined;
return baseismatch(object, source, getmatchdata(source), customizer);
}
/**
* checks if `value` is `nan`.
*
* **note:** this method is based on
* [`number.isnan`](https://mdn.io/number/isnan) and is not the same as
* global [`isnan`](https://mdn.io/isnan) which returns `true` for
* `undefined` and other non-number values.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is `nan`, else `false`.
* @example
*
* _.isnan(nan);
* // => true
*
* _.isnan(new number(nan));
* // => true
*
* isnan(undefined);
* // => true
*
* _.isnan(undefined);
* // => false
*/
function isnan(value) {
// an `nan` primitive is the only value that is not equal to itself.
// perform the `tostringtag` check first to avoid errors with some
// activex objects in ie.
return isnumber(value) && value != +value;
}
/**
* checks if `value` is a pristine native function.
*
* **note:** this method can't reliably detect native functions in the presence
* of the core-js package because core-js circumvents this kind of detection.
* despite multiple requests, the core-js maintainer has made it clear: any
* attempt to fix the detection will be obstructed. as a result, we're left
* with little choice but to throw an error. unfortunately, this also affects
* packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
* which rely on core-js.
*
* @static
* @memberof _
* @since 3.0.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a native function,
* else `false`.
* @example
*
* _.isnative(array.prototype.push);
* // => true
*
* _.isnative(_);
* // => false
*/
function isnative(value) {
if (ismaskable(value)) {
throw new error(core_error_text);
}
return baseisnative(value);
}
/**
* checks if `value` is `null`.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is `null`, else `false`.
* @example
*
* _.isnull(null);
* // => true
*
* _.isnull(void 0);
* // => false
*/
function isnull(value) {
return value === null;
}
/**
* checks if `value` is `null` or `undefined`.
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is nullish, else `false`.
* @example
*
* _.isnil(null);
* // => true
*
* _.isnil(void 0);
* // => true
*
* _.isnil(nan);
* // => false
*/
function isnil(value) {
return value == null;
}
/**
* checks if `value` is classified as a `number` primitive or object.
*
* **note:** to exclude `infinity`, `-infinity`, and `nan`, which are
* classified as numbers, use the `_.isfinite` method.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a number, else `false`.
* @example
*
* _.isnumber(3);
* // => true
*
* _.isnumber(number.min_value);
* // => true
*
* _.isnumber(infinity);
* // => true
*
* _.isnumber('3');
* // => false
*/
function isnumber(value) {
return typeof value == 'number' ||
(isobjectlike(value) && basegettag(value) == numbertag);
}
/**
* checks if `value` is a plain object, that is, an object created by the
* `object` constructor or one with a `[[prototype]]` of `null`.
*
* @static
* @memberof _
* @since 0.8.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a plain object, else `false`.
* @example
*
* function foo() {
* this.a = 1;
* }
*
* _.isplainobject(new foo);
* // => false
*
* _.isplainobject([1, 2, 3]);
* // => false
*
* _.isplainobject({ 'x': 0, 'y': 0 });
* // => true
*
* _.isplainobject(object.create(null));
* // => true
*/
function isplainobject(value) {
if (!isobjectlike(value) || basegettag(value) != objecttag) {
return false;
}
var proto = getprototype(value);
if (proto === null) {
return true;
}
var ctor = hasownproperty.call(proto, 'constructor') && proto.constructor;
return typeof ctor == 'function' && ctor instanceof ctor &&
functostring.call(ctor) == objectctorstring;
}
/**
* checks if `value` is classified as a `regexp` object.
*
* @static
* @memberof _
* @since 0.1.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a regexp, else `false`.
* @example
*
* _.isregexp(/abc/);
* // => true
*
* _.isregexp('/abc/');
* // => false
*/
var isregexp = nodeisregexp ? baseunary(nodeisregexp) : baseisregexp;
/**
* checks if `value` is a safe integer. an integer is safe if it's an ieee-754
* double precision number which isn't the result of a rounded unsafe integer.
*
* **note:** this method is based on
* [`number.issafeinteger`](https://mdn.io/number/issafeinteger).
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a safe integer, else `false`.
* @example
*
* _.issafeinteger(3);
* // => true
*
* _.issafeinteger(number.min_value);
* // => false
*
* _.issafeinteger(infinity);
* // => false
*
* _.issafeinteger('3');
* // => false
*/
function issafeinteger(value) {
return isinteger(value) && value >= -max_safe_integer && value <= max_safe_integer;
}
/**
* checks if `value` is classified as a `set` object.
*
* @static
* @memberof _
* @since 4.3.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a set, else `false`.
* @example
*
* _.isset(new set);
* // => true
*
* _.isset(new weakset);
* // => false
*/
var isset = nodeisset ? baseunary(nodeisset) : baseisset;
/**
* checks if `value` is classified as a `string` primitive or object.
*
* @static
* @since 0.1.0
* @memberof _
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a string, else `false`.
* @example
*
* _.isstring('abc');
* // => true
*
* _.isstring(1);
* // => false
*/
function isstring(value) {
return typeof value == 'string' ||
(!isarray(value) && isobjectlike(value) && basegettag(value) == stringtag);
}
/**
* checks if `value` is classified as a `symbol` primitive or object.
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.issymbol(symbol.iterator);
* // => true
*
* _.issymbol('abc');
* // => false
*/
function issymbol(value) {
return typeof value == 'symbol' ||
(isobjectlike(value) && basegettag(value) == symboltag);
}
/**
* checks if `value` is classified as a typed array.
*
* @static
* @memberof _
* @since 3.0.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a typed array, else `false`.
* @example
*
* _.istypedarray(new uint8array);
* // => true
*
* _.istypedarray([]);
* // => false
*/
var istypedarray = nodeistypedarray ? baseunary(nodeistypedarray) : baseistypedarray;
/**
* checks if `value` is `undefined`.
*
* @static
* @since 0.1.0
* @memberof _
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is `undefined`, else `false`.
* @example
*
* _.isundefined(void 0);
* // => true
*
* _.isundefined(null);
* // => false
*/
function isundefined(value) {
return value === undefined;
}
/**
* checks if `value` is classified as a `weakmap` object.
*
* @static
* @memberof _
* @since 4.3.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a weak map, else `false`.
* @example
*
* _.isweakmap(new weakmap);
* // => true
*
* _.isweakmap(new map);
* // => false
*/
function isweakmap(value) {
return isobjectlike(value) && gettag(value) == weakmaptag;
}
/**
* checks if `value` is classified as a `weakset` object.
*
* @static
* @memberof _
* @since 4.3.0
* @category lang
* @param {*} value the value to check.
* @returns {boolean} returns `true` if `value` is a weak set, else `false`.
* @example
*
* _.isweakset(new weakset);
* // => true
*
* _.isweakset(new set);
* // => false
*/
function isweakset(value) {
return isobjectlike(value) && basegettag(value) == weaksettag;
}
/**
* checks if `value` is less than `other`.
*
* @static
* @memberof _
* @since 3.9.0
* @category lang
* @param {*} value the value to compare.
* @param {*} other the other value to compare.
* @returns {boolean} returns `true` if `value` is less than `other`,
* else `false`.
* @see _.gt
* @example
*
* _.lt(1, 3);
* // => true
*
* _.lt(3, 3);
* // => false
*
* _.lt(3, 1);
* // => false
*/
var lt = createrelationaloperation(baselt);
/**
* checks if `value` is less than or equal to `other`.
*
* @static
* @memberof _
* @since 3.9.0
* @category lang
* @param {*} value the value to compare.
* @param {*} other the other value to compare.
* @returns {boolean} returns `true` if `value` is less than or equal to
* `other`, else `false`.
* @see _.gte
* @example
*
* _.lte(1, 3);
* // => true
*
* _.lte(3, 3);
* // => true
*
* _.lte(3, 1);
* // => false
*/
var lte = createrelationaloperation(function(value, other) {
return value <= other;
});
/**
* converts `value` to an array.
*
* @static
* @since 0.1.0
* @memberof _
* @category lang
* @param {*} value the value to convert.
* @returns {array} returns the converted array.
* @example
*
* _.toarray({ 'a': 1, 'b': 2 });
* // => [1, 2]
*
* _.toarray('abc');
* // => ['a', 'b', 'c']
*
* _.toarray(1);
* // => []
*
* _.toarray(null);
* // => []
*/
function toarray(value) {
if (!value) {
return [];
}
if (isarraylike(value)) {
return isstring(value) ? stringtoarray(value) : copyarray(value);
}
if (symiterator && value[symiterator]) {
return iteratortoarray(value[symiterator]());
}
var tag = gettag(value),
func = tag == maptag ? maptoarray : (tag == settag ? settoarray : values);
return func(value);
}
/**
* converts `value` to a finite number.
*
* @static
* @memberof _
* @since 4.12.0
* @category lang
* @param {*} value the value to convert.
* @returns {number} returns the converted number.
* @example
*
* _.tofinite(3.2);
* // => 3.2
*
* _.tofinite(number.min_value);
* // => 5e-324
*
* _.tofinite(infinity);
* // => 1.7976931348623157e+308
*
* _.tofinite('3.2');
* // => 3.2
*/
function tofinite(value) {
if (!value) {
return value === 0 ? value : 0;
}
value = tonumber(value);
if (value === infinity || value === -infinity) {
var sign = (value < 0 ? -1 : 1);
return sign * max_integer;
}
return value === value ? value : 0;
}
/**
* converts `value` to an integer.
*
* **note:** this method is loosely based on
* [`tointeger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to convert.
* @returns {number} returns the converted integer.
* @example
*
* _.tointeger(3.2);
* // => 3
*
* _.tointeger(number.min_value);
* // => 0
*
* _.tointeger(infinity);
* // => 1.7976931348623157e+308
*
* _.tointeger('3.2');
* // => 3
*/
function tointeger(value) {
var result = tofinite(value),
remainder = result % 1;
return result === result ? (remainder ? result - remainder : result) : 0;
}
/**
* converts `value` to an integer suitable for use as the length of an
* array-like object.
*
* **note:** this method is based on
* [`tolength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to convert.
* @returns {number} returns the converted integer.
* @example
*
* _.tolength(3.2);
* // => 3
*
* _.tolength(number.min_value);
* // => 0
*
* _.tolength(infinity);
* // => 4294967295
*
* _.tolength('3.2');
* // => 3
*/
function tolength(value) {
return value ? baseclamp(tointeger(value), 0, max_array_length) : 0;
}
/**
* converts `value` to a number.
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to process.
* @returns {number} returns the number.
* @example
*
* _.tonumber(3.2);
* // => 3.2
*
* _.tonumber(number.min_value);
* // => 5e-324
*
* _.tonumber(infinity);
* // => infinity
*
* _.tonumber('3.2');
* // => 3.2
*/
function tonumber(value) {
if (typeof value == 'number') {
return value;
}
if (issymbol(value)) {
return nan;
}
if (isobject(value)) {
var other = typeof value.valueof == 'function' ? value.valueof() : value;
value = isobject(other) ? (other + '') : other;
}
if (typeof value != 'string') {
return value === 0 ? value : +value;
}
value = basetrim(value);
var isbinary = reisbinary.test(value);
return (isbinary || reisoctal.test(value))
? freeparseint(value.slice(2), isbinary ? 2 : 8)
: (reisbadhex.test(value) ? nan : +value);
}
/**
* converts `value` to a plain object flattening inherited enumerable string
* keyed properties of `value` to own properties of the plain object.
*
* @static
* @memberof _
* @since 3.0.0
* @category lang
* @param {*} value the value to convert.
* @returns {object} returns the converted plain object.
* @example
*
* function foo() {
* this.b = 2;
* }
*
* foo.prototype.c = 3;
*
* _.assign({ 'a': 1 }, new foo);
* // => { 'a': 1, 'b': 2 }
*
* _.assign({ 'a': 1 }, _.toplainobject(new foo));
* // => { 'a': 1, 'b': 2, 'c': 3 }
*/
function toplainobject(value) {
return copyobject(value, keysin(value));
}
/**
* converts `value` to a safe integer. a safe integer can be compared and
* represented correctly.
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to convert.
* @returns {number} returns the converted integer.
* @example
*
* _.tosafeinteger(3.2);
* // => 3
*
* _.tosafeinteger(number.min_value);
* // => 0
*
* _.tosafeinteger(infinity);
* // => 9007199254740991
*
* _.tosafeinteger('3.2');
* // => 3
*/
function tosafeinteger(value) {
return value
? baseclamp(tointeger(value), -max_safe_integer, max_safe_integer)
: (value === 0 ? value : 0);
}
/**
* converts `value` to a string. an empty string is returned for `null`
* and `undefined` values. the sign of `-0` is preserved.
*
* @static
* @memberof _
* @since 4.0.0
* @category lang
* @param {*} value the value to convert.
* @returns {string} returns the converted string.
* @example
*
* _.tostring(null);
* // => ''
*
* _.tostring(-0);
* // => '-0'
*
* _.tostring([1, 2, 3]);
* // => '1,2,3'
*/
function tostring(value) {
return value == null ? '' : basetostring(value);
}
/*------------------------------------------------------------------------*/
/**
* assigns own enumerable string keyed properties of source objects to the
* destination object. source objects are applied from left to right.
* subsequent sources overwrite property assignments of previous sources.
*
* **note:** this method mutates `object` and is loosely based on
* [`object.assign`](https://mdn.io/object/assign).
*
* @static
* @memberof _
* @since 0.10.0
* @category object
* @param {object} object the destination object.
* @param {...object} [sources] the source objects.
* @returns {object} returns `object`.
* @see _.assignin
* @example
*
* function foo() {
* this.a = 1;
* }
*
* function bar() {
* this.c = 3;
* }
*
* foo.prototype.b = 2;
* bar.prototype.d = 4;
*
* _.assign({ 'a': 0 }, new foo, new bar);
* // => { 'a': 1, 'c': 3 }
*/
var assign = createassigner(function(object, source) {
if (isprototype(source) || isarraylike(source)) {
copyobject(source, keys(source), object);
return;
}
for (var key in source) {
if (hasownproperty.call(source, key)) {
assignvalue(object, key, source[key]);
}
}
});
/**
* this method is like `_.assign` except that it iterates over own and
* inherited source properties.
*
* **note:** this method mutates `object`.
*
* @static
* @memberof _
* @since 4.0.0
* @alias extend
* @category object
* @param {object} object the destination object.
* @param {...object} [sources] the source objects.
* @returns {object} returns `object`.
* @see _.assign
* @example
*
* function foo() {
* this.a = 1;
* }
*
* function bar() {
* this.c = 3;
* }
*
* foo.prototype.b = 2;
* bar.prototype.d = 4;
*
* _.assignin({ 'a': 0 }, new foo, new bar);
* // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
*/
var assignin = createassigner(function(object, source) {
copyobject(source, keysin(source), object);
});
/**
* this method is like `_.assignin` except that it accepts `customizer`
* which is invoked to produce the assigned values. if `customizer` returns
* `undefined`, assignment is handled by the method instead. the `customizer`
* is invoked with five arguments: (objvalue, srcvalue, key, object, source).
*
* **note:** this method mutates `object`.
*
* @static
* @memberof _
* @since 4.0.0
* @alias extendwith
* @category object
* @param {object} object the destination object.
* @param {...object} sources the source objects.
* @param {function} [customizer] the function to customize assigned values.
* @returns {object} returns `object`.
* @see _.assignwith
* @example
*
* function customizer(objvalue, srcvalue) {
* return _.isundefined(objvalue) ? srcvalue : objvalue;
* }
*
* var defaults = _.partialright(_.assigninwith, customizer);
*
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
* // => { 'a': 1, 'b': 2 }
*/
var assigninwith = createassigner(function(object, source, srcindex, customizer) {
copyobject(source, keysin(source), object, customizer);
});
/**
* this method is like `_.assign` except that it accepts `customizer`
* which is invoked to produce the assigned values. if `customizer` returns
* `undefined`, assignment is handled by the method instead. the `customizer`
* is invoked with five arguments: (objvalue, srcvalue, key, object, source).
*
* **note:** this method mutates `object`.
*
* @static
* @memberof _
* @since 4.0.0
* @category object
* @param {object} object the destination object.
* @param {...object} sources the source objects.
* @param {function} [customizer] the function to customize assigned values.
* @returns {object} returns `object`.
* @see _.assigninwith
* @example
*
* function customizer(objvalue, srcvalue) {
* return _.isundefined(objvalue) ? srcvalue : objvalue;
* }
*
* var defaults = _.partialright(_.assignwith, customizer);
*
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
* // => { 'a': 1, 'b': 2 }
*/
var assignwith = createassigner(function(object, source, srcindex, customizer) {
copyobject(source, keys(source), object, customizer);
});
/**
* creates an array of values corresponding to `paths` of `object`.
*
* @static
* @memberof _
* @since 1.0.0
* @category object
* @param {object} object the object to iterate over.
* @param {...(string|string[])} [paths] the property paths to pick.
* @returns {array} returns the picked values.
* @example
*
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
*
* _.at(object, ['a[0].b.c', 'a[1]']);
* // => [3, 4]
*/
var at = flatrest(baseat);
/**
* creates an object that inherits from the `prototype` object. if a
* `properties` object is given, its own enumerable string keyed properties
* are assigned to the created object.
*
* @static
* @memberof _
* @since 2.3.0
* @category object
* @param {object} prototype the object to inherit from.
* @param {object} [properties] the properties to assign to the object.
* @returns {object} returns the new object.
* @example
*
* function shape() {
* this.x = 0;
* this.y = 0;
* }
*
* function circle() {
* shape.call(this);
* }
*
* circle.prototype = _.create(shape.prototype, {
* 'constructor': circle
* });
*
* var circle = new circle;
* circle instanceof circle;
* // => true
*
* circle instanceof shape;
* // => true
*/
function create(prototype, properties) {
var result = basecreate(prototype);
return properties == null ? result : baseassign(result, properties);
}
/**
* assigns own and inherited enumerable string keyed properties of source
* objects to the destination object for all destination properties that
* resolve to `undefined`. source objects are applied from left to right.
* once a property is set, additional values of the same property are ignored.
*
* **note:** this method mutates `object`.
*
* @static
* @since 0.1.0
* @memberof _
* @category object
* @param {object} object the destination object.
* @param {...object} [sources] the source objects.
* @returns {object} returns `object`.
* @see _.defaultsdeep
* @example
*
* _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
* // => { 'a': 1, 'b': 2 }
*/
var defaults = baserest(function(object, sources) {
object = object(object);
var index = -1;
var length = sources.length;
var guard = length > 2 ? sources[2] : undefined;
if (guard && isiterateecall(sources[0], sources[1], guard)) {
length = 1;
}
while (++index < length) {
var source = sources[index];
var props = keysin(source);
var propsindex = -1;
var propslength = props.length;
while (++propsindex < propslength) {
var key = props[propsindex];
var value = object[key];
if (value === undefined ||
(eq(value, objectproto[key]) && !hasownproperty.call(object, key))) {
object[key] = source[key];
}
}
}
return object;
});
/**
* this method is like `_.defaults` except that it recursively assigns
* default properties.
*
* **note:** this method mutates `object`.
*
* @static
* @memberof _
* @since 3.10.0
* @category object
* @param {object} object the destination object.
* @param {...object} [sources] the source objects.
* @returns {object} returns `object`.
* @see _.defaults
* @example
*
* _.defaultsdeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
* // => { 'a': { 'b': 2, 'c': 3 } }
*/
var defaultsdeep = baserest(function(args) {
args.push(undefined, customdefaultsmerge);
return apply(mergewith, undefined, args);
});
/**
* this method is like `_.find` except that it returns the key of the first
* element `predicate` returns truthy for instead of the element itself.
*
* @static
* @memberof _
* @since 1.1.0
* @category object
* @param {object} object the object to inspect.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @returns {string|undefined} returns the key of the matched element,
* else `undefined`.
* @example
*
* var users = {
* 'barney': { 'age': 36, 'active': true },
* 'fred': { 'age': 40, 'active': false },
* 'pebbles': { 'age': 1, 'active': true }
* };
*
* _.findkey(users, function(o) { return o.age < 40; });
* // => 'barney' (iteration order is not guaranteed)
*
* // the `_.matches` iteratee shorthand.
* _.findkey(users, { 'age': 1, 'active': true });
* // => 'pebbles'
*
* // the `_.matchesproperty` iteratee shorthand.
* _.findkey(users, ['active', false]);
* // => 'fred'
*
* // the `_.property` iteratee shorthand.
* _.findkey(users, 'active');
* // => 'barney'
*/
function findkey(object, predicate) {
return basefindkey(object, getiteratee(predicate, 3), baseforown);
}
/**
* this method is like `_.findkey` except that it iterates over elements of
* a collection in the opposite order.
*
* @static
* @memberof _
* @since 2.0.0
* @category object
* @param {object} object the object to inspect.
* @param {function} [predicate=_.identity] the function invoked per iteration.
* @returns {string|undefined} returns the key of the matched element,
* else `undefined`.
* @example
*
* var users = {
* 'barney': { 'age': 36, 'active': true },
* 'fred': { 'age': 40, 'active': false },
* 'pebbles': { 'age': 1, 'active': true }
* };
*
* _.findlastkey(users, function(o) { return o.age < 40; });
* // => returns 'pebbles' assuming `_.findkey` returns 'barney'
*
* // the `_.matches` iteratee shorthand.
* _.findlastkey(users, { 'age': 36, 'active': true });
* // => 'barney'
*
* // the `_.matchesproperty` iteratee shorthand.
* _.findlastkey(users, ['active', false]);
* // => 'fred'
*
* // the `_.property` iteratee shorthand.
* _.findlastkey(users, 'active');
* // => 'pebbles'
*/
function findlastkey(object, predicate) {
return basefindkey(object, getiteratee(predicate, 3), baseforownright);
}
/**
* iterates over own and inherited enumerable string keyed properties of an
* object and invokes `iteratee` for each property. the iteratee is invoked
* with three arguments: (value, key, object). iteratee functions may exit
* iteration early by explicitly returning `false`.
*
* @static
* @memberof _
* @since 0.3.0
* @category object
* @param {object} object the object to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @returns {object} returns `object`.
* @see _.forinright
* @example
*
* function foo() {
* this.a = 1;
* this.b = 2;
* }
*
* foo.prototype.c = 3;
*
* _.forin(new foo, function(value, key) {
* console.log(key);
* });
* // => logs 'a', 'b', then 'c' (iteration order is not guaranteed).
*/
function forin(object, iteratee) {
return object == null
? object
: basefor(object, getiteratee(iteratee, 3), keysin);
}
/**
* this method is like `_.forin` except that it iterates over properties of
* `object` in the opposite order.
*
* @static
* @memberof _
* @since 2.0.0
* @category object
* @param {object} object the object to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @returns {object} returns `object`.
* @see _.forin
* @example
*
* function foo() {
* this.a = 1;
* this.b = 2;
* }
*
* foo.prototype.c = 3;
*
* _.forinright(new foo, function(value, key) {
* console.log(key);
* });
* // => logs 'c', 'b', then 'a' assuming `_.forin` logs 'a', 'b', then 'c'.
*/
function forinright(object, iteratee) {
return object == null
? object
: baseforright(object, getiteratee(iteratee, 3), keysin);
}
/**
* iterates over own enumerable string keyed properties of an object and
* invokes `iteratee` for each property. the iteratee is invoked with three
* arguments: (value, key, object). iteratee functions may exit iteration
* early by explicitly returning `false`.
*
* @static
* @memberof _
* @since 0.3.0
* @category object
* @param {object} object the object to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @returns {object} returns `object`.
* @see _.forownright
* @example
*
* function foo() {
* this.a = 1;
* this.b = 2;
* }
*
* foo.prototype.c = 3;
*
* _.forown(new foo, function(value, key) {
* console.log(key);
* });
* // => logs 'a' then 'b' (iteration order is not guaranteed).
*/
function forown(object, iteratee) {
return object && baseforown(object, getiteratee(iteratee, 3));
}
/**
* this method is like `_.forown` except that it iterates over properties of
* `object` in the opposite order.
*
* @static
* @memberof _
* @since 2.0.0
* @category object
* @param {object} object the object to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @returns {object} returns `object`.
* @see _.forown
* @example
*
* function foo() {
* this.a = 1;
* this.b = 2;
* }
*
* foo.prototype.c = 3;
*
* _.forownright(new foo, function(value, key) {
* console.log(key);
* });
* // => logs 'b' then 'a' assuming `_.forown` logs 'a' then 'b'.
*/
function forownright(object, iteratee) {
return object && baseforownright(object, getiteratee(iteratee, 3));
}
/**
* creates an array of function property names from own enumerable properties
* of `object`.
*
* @static
* @since 0.1.0
* @memberof _
* @category object
* @param {object} object the object to inspect.
* @returns {array} returns the function names.
* @see _.functionsin
* @example
*
* function foo() {
* this.a = _.constant('a');
* this.b = _.constant('b');
* }
*
* foo.prototype.c = _.constant('c');
*
* _.functions(new foo);
* // => ['a', 'b']
*/
function functions(object) {
return object == null ? [] : basefunctions(object, keys(object));
}
/**
* creates an array of function property names from own and inherited
* enumerable properties of `object`.
*
* @static
* @memberof _
* @since 4.0.0
* @category object
* @param {object} object the object to inspect.
* @returns {array} returns the function names.
* @see _.functions
* @example
*
* function foo() {
* this.a = _.constant('a');
* this.b = _.constant('b');
* }
*
* foo.prototype.c = _.constant('c');
*
* _.functionsin(new foo);
* // => ['a', 'b', 'c']
*/
function functionsin(object) {
return object == null ? [] : basefunctions(object, keysin(object));
}
/**
* gets the value at `path` of `object`. if the resolved value is
* `undefined`, the `defaultvalue` is returned in its place.
*
* @static
* @memberof _
* @since 3.7.0
* @category object
* @param {object} object the object to query.
* @param {array|string} path the path of the property to get.
* @param {*} [defaultvalue] the value returned for `undefined` resolved values.
* @returns {*} returns the resolved value.
* @example
*
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
*
* _.get(object, 'a[0].b.c');
* // => 3
*
* _.get(object, ['a', '0', 'b', 'c']);
* // => 3
*
* _.get(object, 'a.b.c', 'default');
* // => 'default'
*/
function get(object, path, defaultvalue) {
var result = object == null ? undefined : baseget(object, path);
return result === undefined ? defaultvalue : result;
}
/**
* checks if `path` is a direct property of `object`.
*
* @static
* @since 0.1.0
* @memberof _
* @category object
* @param {object} object the object to query.
* @param {array|string} path the path to check.
* @returns {boolean} returns `true` if `path` exists, else `false`.
* @example
*
* var object = { 'a': { 'b': 2 } };
* var other = _.create({ 'a': _.create({ 'b': 2 }) });
*
* _.has(object, 'a');
* // => true
*
* _.has(object, 'a.b');
* // => true
*
* _.has(object, ['a', 'b']);
* // => true
*
* _.has(other, 'a');
* // => false
*/
function has(object, path) {
return object != null && haspath(object, path, basehas);
}
/**
* checks if `path` is a direct or inherited property of `object`.
*
* @static
* @memberof _
* @since 4.0.0
* @category object
* @param {object} object the object to query.
* @param {array|string} path the path to check.
* @returns {boolean} returns `true` if `path` exists, else `false`.
* @example
*
* var object = _.create({ 'a': _.create({ 'b': 2 }) });
*
* _.hasin(object, 'a');
* // => true
*
* _.hasin(object, 'a.b');
* // => true
*
* _.hasin(object, ['a', 'b']);
* // => true
*
* _.hasin(object, 'b');
* // => false
*/
function hasin(object, path) {
return object != null && haspath(object, path, basehasin);
}
/**
* creates an object composed of the inverted keys and values of `object`.
* if `object` contains duplicate values, subsequent values overwrite
* property assignments of previous values.
*
* @static
* @memberof _
* @since 0.7.0
* @category object
* @param {object} object the object to invert.
* @returns {object} returns the new inverted object.
* @example
*
* var object = { 'a': 1, 'b': 2, 'c': 1 };
*
* _.invert(object);
* // => { '1': 'c', '2': 'b' }
*/
var invert = createinverter(function(result, value, key) {
if (value != null &&
typeof value.tostring != 'function') {
value = nativeobjecttostring.call(value);
}
result[value] = key;
}, constant(identity));
/**
* this method is like `_.invert` except that the inverted object is generated
* from the results of running each element of `object` thru `iteratee`. the
* corresponding inverted value of each inverted key is an array of keys
* responsible for generating the inverted value. the iteratee is invoked
* with one argument: (value).
*
* @static
* @memberof _
* @since 4.1.0
* @category object
* @param {object} object the object to invert.
* @param {function} [iteratee=_.identity] the iteratee invoked per element.
* @returns {object} returns the new inverted object.
* @example
*
* var object = { 'a': 1, 'b': 2, 'c': 1 };
*
* _.invertby(object);
* // => { '1': ['a', 'c'], '2': ['b'] }
*
* _.invertby(object, function(value) {
* return 'group' + value;
* });
* // => { 'group1': ['a', 'c'], 'group2': ['b'] }
*/
var invertby = createinverter(function(result, value, key) {
if (value != null &&
typeof value.tostring != 'function') {
value = nativeobjecttostring.call(value);
}
if (hasownproperty.call(result, value)) {
result[value].push(key);
} else {
result[value] = [key];
}
}, getiteratee);
/**
* invokes the method at `path` of `object`.
*
* @static
* @memberof _
* @since 4.0.0
* @category object
* @param {object} object the object to query.
* @param {array|string} path the path of the method to invoke.
* @param {...*} [args] the arguments to invoke the method with.
* @returns {*} returns the result of the invoked method.
* @example
*
* var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
*
* _.invoke(object, 'a[0].b.c.slice', 1, 3);
* // => [2, 3]
*/
var invoke = baserest(baseinvoke);
/**
* creates an array of the own enumerable property names of `object`.
*
* **note:** non-object values are coerced to objects. see the
* [es spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
* for more details.
*
* @static
* @since 0.1.0
* @memberof _
* @category object
* @param {object} object the object to query.
* @returns {array} returns the array of property names.
* @example
*
* function foo() {
* this.a = 1;
* this.b = 2;
* }
*
* foo.prototype.c = 3;
*
* _.keys(new foo);
* // => ['a', 'b'] (iteration order is not guaranteed)
*
* _.keys('hi');
* // => ['0', '1']
*/
function keys(object) {
return isarraylike(object) ? arraylikekeys(object) : basekeys(object);
}
/**
* creates an array of the own and inherited enumerable property names of `object`.
*
* **note:** non-object values are coerced to objects.
*
* @static
* @memberof _
* @since 3.0.0
* @category object
* @param {object} object the object to query.
* @returns {array} returns the array of property names.
* @example
*
* function foo() {
* this.a = 1;
* this.b = 2;
* }
*
* foo.prototype.c = 3;
*
* _.keysin(new foo);
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
*/
function keysin(object) {
return isarraylike(object) ? arraylikekeys(object, true) : basekeysin(object);
}
/**
* the opposite of `_.mapvalues`; this method creates an object with the
* same values as `object` and keys generated by running each own enumerable
* string keyed property of `object` thru `iteratee`. the iteratee is invoked
* with three arguments: (value, key, object).
*
* @static
* @memberof _
* @since 3.8.0
* @category object
* @param {object} object the object to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @returns {object} returns the new mapped object.
* @see _.mapvalues
* @example
*
* _.mapkeys({ 'a': 1, 'b': 2 }, function(value, key) {
* return key + value;
* });
* // => { 'a1': 1, 'b2': 2 }
*/
function mapkeys(object, iteratee) {
var result = {};
iteratee = getiteratee(iteratee, 3);
baseforown(object, function(value, key, object) {
baseassignvalue(result, iteratee(value, key, object), value);
});
return result;
}
/**
* creates an object with the same keys as `object` and values generated
* by running each own enumerable string keyed property of `object` thru
* `iteratee`. the iteratee is invoked with three arguments:
* (value, key, object).
*
* @static
* @memberof _
* @since 2.4.0
* @category object
* @param {object} object the object to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @returns {object} returns the new mapped object.
* @see _.mapkeys
* @example
*
* var users = {
* 'fred': { 'user': 'fred', 'age': 40 },
* 'pebbles': { 'user': 'pebbles', 'age': 1 }
* };
*
* _.mapvalues(users, function(o) { return o.age; });
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
*
* // the `_.property` iteratee shorthand.
* _.mapvalues(users, 'age');
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
*/
function mapvalues(object, iteratee) {
var result = {};
iteratee = getiteratee(iteratee, 3);
baseforown(object, function(value, key, object) {
baseassignvalue(result, key, iteratee(value, key, object));
});
return result;
}
/**
* this method is like `_.assign` except that it recursively merges own and
* inherited enumerable string keyed properties of source objects into the
* destination object. source properties that resolve to `undefined` are
* skipped if a destination value exists. array and plain object properties
* are merged recursively. other objects and value types are overridden by
* assignment. source objects are applied from left to right. subsequent
* sources overwrite property assignments of previous sources.
*
* **note:** this method mutates `object`.
*
* @static
* @memberof _
* @since 0.5.0
* @category object
* @param {object} object the destination object.
* @param {...object} [sources] the source objects.
* @returns {object} returns `object`.
* @example
*
* var object = {
* 'a': [{ 'b': 2 }, { 'd': 4 }]
* };
*
* var other = {
* 'a': [{ 'c': 3 }, { 'e': 5 }]
* };
*
* _.merge(object, other);
* // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
*/
var merge = createassigner(function(object, source, srcindex) {
basemerge(object, source, srcindex);
});
/**
* this method is like `_.merge` except that it accepts `customizer` which
* is invoked to produce the merged values of the destination and source
* properties. if `customizer` returns `undefined`, merging is handled by the
* method instead. the `customizer` is invoked with six arguments:
* (objvalue, srcvalue, key, object, source, stack).
*
* **note:** this method mutates `object`.
*
* @static
* @memberof _
* @since 4.0.0
* @category object
* @param {object} object the destination object.
* @param {...object} sources the source objects.
* @param {function} customizer the function to customize assigned values.
* @returns {object} returns `object`.
* @example
*
* function customizer(objvalue, srcvalue) {
* if (_.isarray(objvalue)) {
* return objvalue.concat(srcvalue);
* }
* }
*
* var object = { 'a': [1], 'b': [2] };
* var other = { 'a': [3], 'b': [4] };
*
* _.mergewith(object, other, customizer);
* // => { 'a': [1, 3], 'b': [2, 4] }
*/
var mergewith = createassigner(function(object, source, srcindex, customizer) {
basemerge(object, source, srcindex, customizer);
});
/**
* the opposite of `_.pick`; this method creates an object composed of the
* own and inherited enumerable property paths of `object` that are not omitted.
*
* **note:** this method is considerably slower than `_.pick`.
*
* @static
* @since 0.1.0
* @memberof _
* @category object
* @param {object} object the source object.
* @param {...(string|string[])} [paths] the property paths to omit.
* @returns {object} returns the new object.
* @example
*
* var object = { 'a': 1, 'b': '2', 'c': 3 };
*
* _.omit(object, ['a', 'c']);
* // => { 'b': '2' }
*/
var omit = flatrest(function(object, paths) {
var result = {};
if (object == null) {
return result;
}
var isdeep = false;
paths = arraymap(paths, function(path) {
path = castpath(path, object);
isdeep || (isdeep = path.length > 1);
return path;
});
copyobject(object, getallkeysin(object), result);
if (isdeep) {
result = baseclone(result, clone_deep_flag | clone_flat_flag | clone_symbols_flag, customomitclone);
}
var length = paths.length;
while (length--) {
baseunset(result, paths[length]);
}
return result;
});
/**
* the opposite of `_.pickby`; this method creates an object composed of
* the own and inherited enumerable string keyed properties of `object` that
* `predicate` doesn't return truthy for. the predicate is invoked with two
* arguments: (value, key).
*
* @static
* @memberof _
* @since 4.0.0
* @category object
* @param {object} object the source object.
* @param {function} [predicate=_.identity] the function invoked per property.
* @returns {object} returns the new object.
* @example
*
* var object = { 'a': 1, 'b': '2', 'c': 3 };
*
* _.omitby(object, _.isnumber);
* // => { 'b': '2' }
*/
function omitby(object, predicate) {
return pickby(object, negate(getiteratee(predicate)));
}
/**
* creates an object composed of the picked `object` properties.
*
* @static
* @since 0.1.0
* @memberof _
* @category object
* @param {object} object the source object.
* @param {...(string|string[])} [paths] the property paths to pick.
* @returns {object} returns the new object.
* @example
*
* var object = { 'a': 1, 'b': '2', 'c': 3 };
*
* _.pick(object, ['a', 'c']);
* // => { 'a': 1, 'c': 3 }
*/
var pick = flatrest(function(object, paths) {
return object == null ? {} : basepick(object, paths);
});
/**
* creates an object composed of the `object` properties `predicate` returns
* truthy for. the predicate is invoked with two arguments: (value, key).
*
* @static
* @memberof _
* @since 4.0.0
* @category object
* @param {object} object the source object.
* @param {function} [predicate=_.identity] the function invoked per property.
* @returns {object} returns the new object.
* @example
*
* var object = { 'a': 1, 'b': '2', 'c': 3 };
*
* _.pickby(object, _.isnumber);
* // => { 'a': 1, 'c': 3 }
*/
function pickby(object, predicate) {
if (object == null) {
return {};
}
var props = arraymap(getallkeysin(object), function(prop) {
return [prop];
});
predicate = getiteratee(predicate);
return basepickby(object, props, function(value, path) {
return predicate(value, path[0]);
});
}
/**
* this method is like `_.get` except that if the resolved value is a
* function it's invoked with the `this` binding of its parent object and
* its result is returned.
*
* @static
* @since 0.1.0
* @memberof _
* @category object
* @param {object} object the object to query.
* @param {array|string} path the path of the property to resolve.
* @param {*} [defaultvalue] the value returned for `undefined` resolved values.
* @returns {*} returns the resolved value.
* @example
*
* var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
*
* _.result(object, 'a[0].b.c1');
* // => 3
*
* _.result(object, 'a[0].b.c2');
* // => 4
*
* _.result(object, 'a[0].b.c3', 'default');
* // => 'default'
*
* _.result(object, 'a[0].b.c3', _.constant('default'));
* // => 'default'
*/
function result(object, path, defaultvalue) {
path = castpath(path, object);
var index = -1,
length = path.length;
// ensure the loop is entered when path is empty.
if (!length) {
length = 1;
object = undefined;
}
while (++index < length) {
var value = object == null ? undefined : object[tokey(path[index])];
if (value === undefined) {
index = length;
value = defaultvalue;
}
object = isfunction(value) ? value.call(object) : value;
}
return object;
}
/**
* sets the value at `path` of `object`. if a portion of `path` doesn't exist,
* it's created. arrays are created for missing index properties while objects
* are created for all other missing properties. use `_.setwith` to customize
* `path` creation.
*
* **note:** this method mutates `object`.
*
* @static
* @memberof _
* @since 3.7.0
* @category object
* @param {object} object the object to modify.
* @param {array|string} path the path of the property to set.
* @param {*} value the value to set.
* @returns {object} returns `object`.
* @example
*
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
*
* _.set(object, 'a[0].b.c', 4);
* console.log(object.a[0].b.c);
* // => 4
*
* _.set(object, ['x', '0', 'y', 'z'], 5);
* console.log(object.x[0].y.z);
* // => 5
*/
function set(object, path, value) {
return object == null ? object : baseset(object, path, value);
}
/**
* this method is like `_.set` except that it accepts `customizer` which is
* invoked to produce the objects of `path`. if `customizer` returns `undefined`
* path creation is handled by the method instead. the `customizer` is invoked
* with three arguments: (nsvalue, key, nsobject).
*
* **note:** this method mutates `object`.
*
* @static
* @memberof _
* @since 4.0.0
* @category object
* @param {object} object the object to modify.
* @param {array|string} path the path of the property to set.
* @param {*} value the value to set.
* @param {function} [customizer] the function to customize assigned values.
* @returns {object} returns `object`.
* @example
*
* var object = {};
*
* _.setwith(object, '[0][1]', 'a', object);
* // => { '0': { '1': 'a' } }
*/
function setwith(object, path, value, customizer) {
customizer = typeof customizer == 'function' ? customizer : undefined;
return object == null ? object : baseset(object, path, value, customizer);
}
/**
* creates an array of own enumerable string keyed-value pairs for `object`
* which can be consumed by `_.frompairs`. if `object` is a map or set, its
* entries are returned.
*
* @static
* @memberof _
* @since 4.0.0
* @alias entries
* @category object
* @param {object} object the object to query.
* @returns {array} returns the key-value pairs.
* @example
*
* function foo() {
* this.a = 1;
* this.b = 2;
* }
*
* foo.prototype.c = 3;
*
* _.topairs(new foo);
* // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
*/
var topairs = createtopairs(keys);
/**
* creates an array of own and inherited enumerable string keyed-value pairs
* for `object` which can be consumed by `_.frompairs`. if `object` is a map
* or set, its entries are returned.
*
* @static
* @memberof _
* @since 4.0.0
* @alias entriesin
* @category object
* @param {object} object the object to query.
* @returns {array} returns the key-value pairs.
* @example
*
* function foo() {
* this.a = 1;
* this.b = 2;
* }
*
* foo.prototype.c = 3;
*
* _.topairsin(new foo);
* // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
*/
var topairsin = createtopairs(keysin);
/**
* an alternative to `_.reduce`; this method transforms `object` to a new
* `accumulator` object which is the result of running each of its own
* enumerable string keyed properties thru `iteratee`, with each invocation
* potentially mutating the `accumulator` object. if `accumulator` is not
* provided, a new object with the same `[[prototype]]` will be used. the
* iteratee is invoked with four arguments: (accumulator, value, key, object).
* iteratee functions may exit iteration early by explicitly returning `false`.
*
* @static
* @memberof _
* @since 1.3.0
* @category object
* @param {object} object the object to iterate over.
* @param {function} [iteratee=_.identity] the function invoked per iteration.
* @param {*} [accumulator] the custom accumulator value.
* @returns {*} returns the accumulated value.
* @example
*
* _.transform([2, 3, 4], function(result, n) {
* result.push(n *= n);
* return n % 2 == 0;
* }, []);
* // => [4, 9]
*
* _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
* (result[value] || (result[value] = [])).push(key);
* }, {});
* // => { '1': ['a', 'c'], '2': ['b'] }
*/
function transform(object, iteratee, accumulator) {
var isarr = isarray(object),
isarrlike = isarr || isbuffer(object) || istypedarray(object);
iteratee = getiteratee(iteratee, 4);
if (accumulator == null) {
var ctor = object && object.constructor;
if (isarrlike) {
accumulator = isarr ? new ctor : [];
}
else if (isobject(object)) {
accumulator = isfunction(ctor) ? basecreate(getprototype(object)) : {};
}
else {
accumulator = {};
}
}
(isarrlike ? arrayeach : baseforown)(object, function(value, index, object) {
return iteratee(accumulator, value, index, object);
});
return accumulator;
}
/**
* removes the property at `path` of `object`.
*
* **note:** this method mutates `object`.
*
* @static
* @memberof _
* @since 4.0.0
* @category object
* @param {object} object the object to modify.
* @param {array|string} path the path of the property to unset.
* @returns {boolean} returns `true` if the property is deleted, else `false`.
* @example
*
* var object = { 'a': [{ 'b': { 'c': 7 } }] };
* _.unset(object, 'a[0].b.c');
* // => true
*
* console.log(object);
* // => { 'a': [{ 'b': {} }] };
*
* _.unset(object, ['a', '0', 'b', 'c']);
* // => true
*
* console.log(object);
* // => { 'a': [{ 'b': {} }] };
*/
function unset(object, path) {
return object == null ? true : baseunset(object, path);
}
/**
* this method is like `_.set` except that accepts `updater` to produce the
* value to set. use `_.updatewith` to customize `path` creation. the `updater`
* is invoked with one argument: (value).
*
* **note:** this method mutates `object`.
*
* @static
* @memberof _
* @since 4.6.0
* @category object
* @param {object} object the object to modify.
* @param {array|string} path the path of the property to set.
* @param {function} updater the function to produce the updated value.
* @returns {object} returns `object`.
* @example
*
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
*
* _.update(object, 'a[0].b.c', function(n) { return n * n; });
* console.log(object.a[0].b.c);
* // => 9
*
* _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
* console.log(object.x[0].y.z);
* // => 0
*/
function update(object, path, updater) {
return object == null ? object : baseupdate(object, path, castfunction(updater));
}
/**
* this method is like `_.update` except that it accepts `customizer` which is
* invoked to produce the objects of `path`. if `customizer` returns `undefined`
* path creation is handled by the method instead. the `customizer` is invoked
* with three arguments: (nsvalue, key, nsobject).
*
* **note:** this method mutates `object`.
*
* @static
* @memberof _
* @since 4.6.0
* @category object
* @param {object} object the object to modify.
* @param {array|string} path the path of the property to set.
* @param {function} updater the function to produce the updated value.
* @param {function} [customizer] the function to customize assigned values.
* @returns {object} returns `object`.
* @example
*
* var object = {};
*
* _.updatewith(object, '[0][1]', _.constant('a'), object);
* // => { '0': { '1': 'a' } }
*/
function updatewith(object, path, updater, customizer) {
customizer = typeof customizer == 'function' ? customizer : undefined;
return object == null ? object : baseupdate(object, path, castfunction(updater), customizer);
}
/**
* creates an array of the own enumerable string keyed property values of `object`.
*
* **note:** non-object values are coerced to objects.
*
* @static
* @since 0.1.0
* @memberof _
* @category object
* @param {object} object the object to query.
* @returns {array} returns the array of property values.
* @example
*
* function foo() {
* this.a = 1;
* this.b = 2;
* }
*
* foo.prototype.c = 3;
*
* _.values(new foo);
* // => [1, 2] (iteration order is not guaranteed)
*
* _.values('hi');
* // => ['h', 'i']
*/
function values(object) {
return object == null ? [] : basevalues(object, keys(object));
}
/**
* creates an array of the own and inherited enumerable string keyed property
* values of `object`.
*
* **note:** non-object values are coerced to objects.
*
* @static
* @memberof _
* @since 3.0.0
* @category object
* @param {object} object the object to query.
* @returns {array} returns the array of property values.
* @example
*
* function foo() {
* this.a = 1;
* this.b = 2;
* }
*
* foo.prototype.c = 3;
*
* _.valuesin(new foo);
* // => [1, 2, 3] (iteration order is not guaranteed)
*/
function valuesin(object) {
return object == null ? [] : basevalues(object, keysin(object));
}
/*------------------------------------------------------------------------*/
/**
* clamps `number` within the inclusive `lower` and `upper` bounds.
*
* @static
* @memberof _
* @since 4.0.0
* @category number
* @param {number} number the number to clamp.
* @param {number} [lower] the lower bound.
* @param {number} upper the upper bound.
* @returns {number} returns the clamped number.
* @example
*
* _.clamp(-10, -5, 5);
* // => -5
*
* _.clamp(10, -5, 5);
* // => 5
*/
function clamp(number, lower, upper) {
if (upper === undefined) {
upper = lower;
lower = undefined;
}
if (upper !== undefined) {
upper = tonumber(upper);
upper = upper === upper ? upper : 0;
}
if (lower !== undefined) {
lower = tonumber(lower);
lower = lower === lower ? lower : 0;
}
return baseclamp(tonumber(number), lower, upper);
}
/**
* checks if `n` is between `start` and up to, but not including, `end`. if
* `end` is not specified, it's set to `start` with `start` then set to `0`.
* if `start` is greater than `end` the params are swapped to support
* negative ranges.
*
* @static
* @memberof _
* @since 3.3.0
* @category number
* @param {number} number the number to check.
* @param {number} [start=0] the start of the range.
* @param {number} end the end of the range.
* @returns {boolean} returns `true` if `number` is in the range, else `false`.
* @see _.range, _.rangeright
* @example
*
* _.inrange(3, 2, 4);
* // => true
*
* _.inrange(4, 8);
* // => true
*
* _.inrange(4, 2);
* // => false
*
* _.inrange(2, 2);
* // => false
*
* _.inrange(1.2, 2);
* // => true
*
* _.inrange(5.2, 4);
* // => false
*
* _.inrange(-3, -2, -6);
* // => true
*/
function inrange(number, start, end) {
start = tofinite(start);
if (end === undefined) {
end = start;
start = 0;
} else {
end = tofinite(end);
}
number = tonumber(number);
return baseinrange(number, start, end);
}
/**
* produces a random number between the inclusive `lower` and `upper` bounds.
* if only one argument is provided a number between `0` and the given number
* is returned. if `floating` is `true`, or either `lower` or `upper` are
* floats, a floating-point number is returned instead of an integer.
*
* **note:** javascript follows the ieee-754 standard for resolving
* floating-point values which can produce unexpected results.
*
* @static
* @memberof _
* @since 0.7.0
* @category number
* @param {number} [lower=0] the lower bound.
* @param {number} [upper=1] the upper bound.
* @param {boolean} [floating] specify returning a floating-point number.
* @returns {number} returns the random number.
* @example
*
* _.random(0, 5);
* // => an integer between 0 and 5
*
* _.random(5);
* // => also an integer between 0 and 5
*
* _.random(5, true);
* // => a floating-point number between 0 and 5
*
* _.random(1.2, 5.2);
* // => a floating-point number between 1.2 and 5.2
*/
function random(lower, upper, floating) {
if (floating && typeof floating != 'boolean' && isiterateecall(lower, upper, floating)) {
upper = floating = undefined;
}
if (floating === undefined) {
if (typeof upper == 'boolean') {
floating = upper;
upper = undefined;
}
else if (typeof lower == 'boolean') {
floating = lower;
lower = undefined;
}
}
if (lower === undefined && upper === undefined) {
lower = 0;
upper = 1;
}
else {
lower = tofinite(lower);
if (upper === undefined) {
upper = lower;
lower = 0;
} else {
upper = tofinite(upper);
}
}
if (lower > upper) {
var temp = lower;
lower = upper;
upper = temp;
}
if (floating || lower % 1 || upper % 1) {
var rand = nativerandom();
return nativemin(lower + (rand * (upper - lower + freeparsefloat('1e-' + ((rand + '').length - 1)))), upper);
}
return baserandom(lower, upper);
}
/*------------------------------------------------------------------------*/
/**
* converts `string` to [camel case](https://en.wikipedia.org/wiki/camelcase).
*
* @static
* @memberof _
* @since 3.0.0
* @category string
* @param {string} [string=''] the string to convert.
* @returns {string} returns the camel cased string.
* @example
*
* _.camelcase('foo bar');
* // => 'foobar'
*
* _.camelcase('--foo-bar--');
* // => 'foobar'
*
* _.camelcase('__foo_bar__');
* // => 'foobar'
*/
var camelcase = createcompounder(function(result, word, index) {
word = word.tolowercase();
return result + (index ? capitalize(word) : word);
});
/**
* converts the first character of `string` to upper case and the remaining
* to lower case.
*
* @static
* @memberof _
* @since 3.0.0
* @category string
* @param {string} [string=''] the string to capitalize.
* @returns {string} returns the capitalized string.
* @example
*
* _.capitalize('fred');
* // => 'fred'
*/
function capitalize(string) {
return upperfirst(tostring(string).tolowercase());
}
/**
* deburrs `string` by converting
* [latin-1 supplement](https://en.wikipedia.org/wiki/latin-1_supplement_(unicode_block)#character_table)
* and [latin extended-a](https://en.wikipedia.org/wiki/latin_extended-a)
* letters to basic latin letters and removing
* [combining diacritical marks](https://en.wikipedia.org/wiki/combining_diacritical_marks).
*
* @static
* @memberof _
* @since 3.0.0
* @category string
* @param {string} [string=''] the string to deburr.
* @returns {string} returns the deburred string.
* @example
*
* _.deburr('déjà vu');
* // => 'deja vu'
*/
function deburr(string) {
string = tostring(string);
return string && string.replace(relatin, deburrletter).replace(recombomark, '');
}
/**
* checks if `string` ends with the given target string.
*
* @static
* @memberof _
* @since 3.0.0
* @category string
* @param {string} [string=''] the string to inspect.
* @param {string} [target] the string to search for.
* @param {number} [position=string.length] the position to search up to.
* @returns {boolean} returns `true` if `string` ends with `target`,
* else `false`.
* @example
*
* _.endswith('abc', 'c');
* // => true
*
* _.endswith('abc', 'b');
* // => false
*
* _.endswith('abc', 'b', 2);
* // => true
*/
function endswith(string, target, position) {
string = tostring(string);
target = basetostring(target);
var length = string.length;
position = position === undefined
? length
: baseclamp(tointeger(position), 0, length);
var end = position;
position -= target.length;
return position >= 0 && string.slice(position, end) == target;
}
/**
* converts the characters "&", "<", ">", '"', and "'" in `string` to their
* corresponding html entities.
*
* **note:** no other characters are escaped. to escape additional
* characters use a third-party library like [_he_](https://mths.be/he).
*
* though the ">" character is escaped for symmetry, characters like
* ">" and "/" don't need escaping in html and have no special meaning
* unless they're part of a tag or unquoted attribute value. see
* [mathias bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
* (under "semi-related fun fact") for more details.
*
* when working with html you should always
* [quote attribute values](http://wonko.com/post/html-escaping) to reduce
* xss vectors.
*
* @static
* @since 0.1.0
* @memberof _
* @category string
* @param {string} [string=''] the string to escape.
* @returns {string} returns the escaped string.
* @example
*
* _.escape('fred, barney, & pebbles');
* // => 'fred, barney, & pebbles'
*/
function escape(string) {
string = tostring(string);
return (string && rehasunescapedhtml.test(string))
? string.replace(reunescapedhtml, escapehtmlchar)
: string;
}
/**
* escapes the `regexp` special characters "^", "$", "\", ".", "*", "+",
* "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
*
* @static
* @memberof _
* @since 3.0.0
* @category string
* @param {string} [string=''] the string to escape.
* @returns {string} returns the escaped string.
* @example
*
* _.escaperegexp('[lodash](https://lodash.com/)');
* // => '\[lodash\]\(https://lodash\.com/\)'
*/
function escaperegexp(string) {
string = tostring(string);
return (string && rehasregexpchar.test(string))
? string.replace(reregexpchar, '\\$&')
: string;
}
/**
* converts `string` to
* [kebab case](https://en.wikipedia.org/wiki/letter_case#special_case_styles).
*
* @static
* @memberof _
* @since 3.0.0
* @category string
* @param {string} [string=''] the string to convert.
* @returns {string} returns the kebab cased string.
* @example
*
* _.kebabcase('foo bar');
* // => 'foo-bar'
*
* _.kebabcase('foobar');
* // => 'foo-bar'
*
* _.kebabcase('__foo_bar__');
* // => 'foo-bar'
*/
var kebabcase = createcompounder(function(result, word, index) {
return result + (index ? '-' : '') + word.tolowercase();
});
/**
* converts `string`, as space separated words, to lower case.
*
* @static
* @memberof _
* @since 4.0.0
* @category string
* @param {string} [string=''] the string to convert.
* @returns {string} returns the lower cased string.
* @example
*
* _.lowercase('--foo-bar--');
* // => 'foo bar'
*
* _.lowercase('foobar');
* // => 'foo bar'
*
* _.lowercase('__foo_bar__');
* // => 'foo bar'
*/
var lowercase = createcompounder(function(result, word, index) {
return result + (index ? ' ' : '') + word.tolowercase();
});
/**
* converts the first character of `string` to lower case.
*
* @static
* @memberof _
* @since 4.0.0
* @category string
* @param {string} [string=''] the string to convert.
* @returns {string} returns the converted string.
* @example
*
* _.lowerfirst('fred');
* // => 'fred'
*
* _.lowerfirst('fred');
* // => 'fred'
*/
var lowerfirst = createcasefirst('tolowercase');
/**
* pads `string` on the left and right sides if it's shorter than `length`.
* padding characters are truncated if they can't be evenly divided by `length`.
*
* @static
* @memberof _
* @since 3.0.0
* @category string
* @param {string} [string=''] the string to pad.
* @param {number} [length=0] the padding length.
* @param {string} [chars=' '] the string used as padding.
* @returns {string} returns the padded string.
* @example
*
* _.pad('abc', 8);
* // => ' abc '
*
* _.pad('abc', 8, '_-');
* // => '_-abc_-_'
*
* _.pad('abc', 3);
* // => 'abc'
*/
function pad(string, length, chars) {
string = tostring(string);
length = tointeger(length);
var strlength = length ? stringsize(string) : 0;
if (!length || strlength >= length) {
return string;
}
var mid = (length - strlength) / 2;
return (
createpadding(nativefloor(mid), chars) +
string +
createpadding(nativeceil(mid), chars)
);
}
/**
* pads `string` on the right side if it's shorter than `length`. padding
* characters are truncated if they exceed `length`.
*
* @static
* @memberof _
* @since 4.0.0
* @category string
* @param {string} [string=''] the string to pad.
* @param {number} [length=0] the padding length.
* @param {string} [chars=' '] the string used as padding.
* @returns {string} returns the padded string.
* @example
*
* _.padend('abc', 6);
* // => 'abc '
*
* _.padend('abc', 6, '_-');
* // => 'abc_-_'
*
* _.padend('abc', 3);
* // => 'abc'
*/
function padend(string, length, chars) {
string = tostring(string);
length = tointeger(length);
var strlength = length ? stringsize(string) : 0;
return (length && strlength < length)
? (string + createpadding(length - strlength, chars))
: string;
}
/**
* pads `string` on the left side if it's shorter than `length`. padding
* characters are truncated if they exceed `length`.
*
* @static
* @memberof _
* @since 4.0.0
* @category string
* @param {string} [string=''] the string to pad.
* @param {number} [length=0] the padding length.
* @param {string} [chars=' '] the string used as padding.
* @returns {string} returns the padded string.
* @example
*
* _.padstart('abc', 6);
* // => ' abc'
*
* _.padstart('abc', 6, '_-');
* // => '_-_abc'
*
* _.padstart('abc', 3);
* // => 'abc'
*/
function padstart(string, length, chars) {
string = tostring(string);
length = tointeger(length);
var strlength = length ? stringsize(string) : 0;
return (length && strlength < length)
? (createpadding(length - strlength, chars) + string)
: string;
}
/**
* converts `string` to an integer of the specified radix. if `radix` is
* `undefined` or `0`, a `radix` of `10` is used unless `value` is a
* hexadecimal, in which case a `radix` of `16` is used.
*
* **note:** this method aligns with the
* [es5 implementation](https://es5.github.io/#x15.1.2.2) of `parseint`.
*
* @static
* @memberof _
* @since 1.1.0
* @category string
* @param {string} string the string to convert.
* @param {number} [radix=10] the radix to interpret `value` by.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {number} returns the converted integer.
* @example
*
* _.parseint('08');
* // => 8
*
* _.map(['6', '08', '10'], _.parseint);
* // => [6, 8, 10]
*/
function parseint(string, radix, guard) {
if (guard || radix == null) {
radix = 0;
} else if (radix) {
radix = +radix;
}
return nativeparseint(tostring(string).replace(retrimstart, ''), radix || 0);
}
/**
* repeats the given string `n` times.
*
* @static
* @memberof _
* @since 3.0.0
* @category string
* @param {string} [string=''] the string to repeat.
* @param {number} [n=1] the number of times to repeat the string.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {string} returns the repeated string.
* @example
*
* _.repeat('*', 3);
* // => '***'
*
* _.repeat('abc', 2);
* // => 'abcabc'
*
* _.repeat('abc', 0);
* // => ''
*/
function repeat(string, n, guard) {
if ((guard ? isiterateecall(string, n, guard) : n === undefined)) {
n = 1;
} else {
n = tointeger(n);
}
return baserepeat(tostring(string), n);
}
/**
* replaces matches for `pattern` in `string` with `replacement`.
*
* **note:** this method is based on
* [`string#replace`](https://mdn.io/string/replace).
*
* @static
* @memberof _
* @since 4.0.0
* @category string
* @param {string} [string=''] the string to modify.
* @param {regexp|string} pattern the pattern to replace.
* @param {function|string} replacement the match replacement.
* @returns {string} returns the modified string.
* @example
*
* _.replace('hi fred', 'fred', 'barney');
* // => 'hi barney'
*/
function replace() {
var args = arguments,
string = tostring(args[0]);
return args.length < 3 ? string : string.replace(args[1], args[2]);
}
/**
* converts `string` to
* [snake case](https://en.wikipedia.org/wiki/snake_case).
*
* @static
* @memberof _
* @since 3.0.0
* @category string
* @param {string} [string=''] the string to convert.
* @returns {string} returns the snake cased string.
* @example
*
* _.snakecase('foo bar');
* // => 'foo_bar'
*
* _.snakecase('foobar');
* // => 'foo_bar'
*
* _.snakecase('--foo-bar--');
* // => 'foo_bar'
*/
var snakecase = createcompounder(function(result, word, index) {
return result + (index ? '_' : '') + word.tolowercase();
});
/**
* splits `string` by `separator`.
*
* **note:** this method is based on
* [`string#split`](https://mdn.io/string/split).
*
* @static
* @memberof _
* @since 4.0.0
* @category string
* @param {string} [string=''] the string to split.
* @param {regexp|string} separator the separator pattern to split by.
* @param {number} [limit] the length to truncate results to.
* @returns {array} returns the string segments.
* @example
*
* _.split('a-b-c', '-', 2);
* // => ['a', 'b']
*/
function split(string, separator, limit) {
if (limit && typeof limit != 'number' && isiterateecall(string, separator, limit)) {
separator = limit = undefined;
}
limit = limit === undefined ? max_array_length : limit >>> 0;
if (!limit) {
return [];
}
string = tostring(string);
if (string && (
typeof separator == 'string' ||
(separator != null && !isregexp(separator))
)) {
separator = basetostring(separator);
if (!separator && hasunicode(string)) {
return castslice(stringtoarray(string), 0, limit);
}
}
return string.split(separator, limit);
}
/**
* converts `string` to
* [start case](https://en.wikipedia.org/wiki/letter_case#stylistic_or_specialised_usage).
*
* @static
* @memberof _
* @since 3.1.0
* @category string
* @param {string} [string=''] the string to convert.
* @returns {string} returns the start cased string.
* @example
*
* _.startcase('--foo-bar--');
* // => 'foo bar'
*
* _.startcase('foobar');
* // => 'foo bar'
*
* _.startcase('__foo_bar__');
* // => 'foo bar'
*/
var startcase = createcompounder(function(result, word, index) {
return result + (index ? ' ' : '') + upperfirst(word);
});
/**
* checks if `string` starts with the given target string.
*
* @static
* @memberof _
* @since 3.0.0
* @category string
* @param {string} [string=''] the string to inspect.
* @param {string} [target] the string to search for.
* @param {number} [position=0] the position to search from.
* @returns {boolean} returns `true` if `string` starts with `target`,
* else `false`.
* @example
*
* _.startswith('abc', 'a');
* // => true
*
* _.startswith('abc', 'b');
* // => false
*
* _.startswith('abc', 'b', 1);
* // => true
*/
function startswith(string, target, position) {
string = tostring(string);
position = position == null
? 0
: baseclamp(tointeger(position), 0, string.length);
target = basetostring(target);
return string.slice(position, position + target.length) == target;
}
/**
* creates a compiled template function that can interpolate data properties
* in "interpolate" delimiters, html-escape interpolated data properties in
* "escape" delimiters, and execute javascript in "evaluate" delimiters. data
* properties may be accessed as free variables in the template. if a setting
* object is given, it takes precedence over `_.templatesettings` values.
*
* **note:** in the development build `_.template` utilizes
* [sourceurls](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
* for easier debugging.
*
* for more information on precompiling templates see
* [lodash's custom builds documentation](https://lodash.com/custom-builds).
*
* for more information on chrome extension sandboxes see
* [chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingeval).
*
* @static
* @since 0.1.0
* @memberof _
* @category string
* @param {string} [string=''] the template string.
* @param {object} [options={}] the options object.
* @param {regexp} [options.escape=_.templatesettings.escape]
* the html "escape" delimiter.
* @param {regexp} [options.evaluate=_.templatesettings.evaluate]
* the "evaluate" delimiter.
* @param {object} [options.imports=_.templatesettings.imports]
* an object to import into the template as free variables.
* @param {regexp} [options.interpolate=_.templatesettings.interpolate]
* the "interpolate" delimiter.
* @param {string} [options.sourceurl='lodash.templatesources[n]']
* the sourceurl of the compiled template.
* @param {string} [options.variable='obj']
* the data object variable name.
* @param- {object} [guard] enables use as an iteratee for methods like `_.map`.
* @returns {function} returns the compiled template function.
* @example
*
* // use the "interpolate" delimiter to create a compiled template.
* var compiled = _.template('hello <%= user %>!');
* compiled({ 'user': 'fred' });
* // => 'hello fred!'
*
* // use the html "escape" delimiter to escape data property values.
* var compiled = _.template('<%- value %>');
* compiled({ 'value': '