From e4fece62919d563646c1077b22f99d91637d9507 Mon Sep 17 00:00:00 2001 From: Andrea Scartabelli Date: Thu, 7 Mar 2019 15:34:21 +0100 Subject: [PATCH] - Updated jest-cli to avoid errors with Node >= 11.11.0 (see https://github.com/facebook/jest/pull/8050) - Updated eslint rules - Removed `gulp-jest` --- .eslintrc.json | 6 +- .eslintrc.test.json | 4 + dist/lamb.js | 8 +- dist/lamb.min.js | 2 +- dist/lamb.min.js.map | 2 +- gulpfile.js | 106 ++-- package-lock.json | 1136 ++++++++++++++++++++++++++++------------ package.json | 7 +- src/object/updateIn.js | 6 +- 9 files changed, 869 insertions(+), 408 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index f1eeca5..8b481b5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -220,7 +220,11 @@ ], "operator-linebreak": [ "error", - "after" + "before", { + "overrides": { + "=": "after" + } + } ], "padded-blocks": [ "error", diff --git a/.eslintrc.test.json b/.eslintrc.test.json index 66060b3..4e9c865 100644 --- a/.eslintrc.test.json +++ b/.eslintrc.test.json @@ -1,11 +1,15 @@ { "env": { + "es6": true, "jest" : true, "node": true }, "extends": [ ".eslintrc.json" ], + "parserOptions": { + "ecmaVersion": 9 + }, "rules": { "brace-style": [ "error", diff --git a/dist/lamb.js b/dist/lamb.js index b5ddcf8..5850128 100644 --- a/dist/lamb.js +++ b/dist/lamb.js @@ -1,7 +1,7 @@ /** * @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming. * @author Andrea Scartabelli -* @version 0.58.0-alpha.1 +* @version 0.58.0-alpha.2 * @module lamb * @license MIT * @preserve @@ -6374,9 +6374,9 @@ * @returns {Object} */ function updateIn (source, key, updater) { - return _isEnumerable(source, key) ? - _setIn(source, key, updater(source[key])) : - _merge(enumerables, source, {}); + return _isEnumerable(source, key) + ? _setIn(source, key, updater(source[key])) + : _merge(enumerables, source, {}); } /** diff --git a/dist/lamb.min.js b/dist/lamb.min.js index d76c08d..eb21dc7 100644 --- a/dist/lamb.min.js +++ b/dist/lamb.min.js @@ -1,7 +1,7 @@ /** * @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming. * @author Andrea Scartabelli -* @version 0.58.0-alpha.1 +* @version 0.58.0-alpha.2 * @module lamb * @license MIT * @preserve diff --git a/dist/lamb.min.js.map b/dist/lamb.min.js.map index 35042ae..0bca32a 100644 --- a/dist/lamb.min.js.map +++ b/dist/lamb.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["lamb.js"],"names":["global","factory","exports","module","define","amd","self","lamb","this","__","areSVZ","a","b","binary","fn","call","clamp","n","min","max","NaN","partial","args","Array","isArray","apply","arguments","boundArg","lastIdx","newArgs","argsLen","length","i","len","_makePartial3","shouldAritize","clampWithin","identity","value","compose","MAX_ARRAY_LENGTH","_toArrayLength","forEach","arrayLike","iteratee","generic","Function","bind","isNull","isUndefined","isNil","_curry2","isRightCurry","isSVZ","map","result","mapWith","_makeReducer","step","accumulator","initialValue","nCalls","idx","TypeError","reduce","reduceWith","_toInteger","Math","floor","abs","slice","start","end","begin","upTo","resultLen","sliceAt","objectProtoToString","Object","prototype","toString","type","appendTo","concat","append","isIn","contains","_groupWith","makeValue","element","key","count","countBy","filter","predicate","push","not","uniquesBy","seen","uniques","dropFrom","drop","_getNumConsecutiveHits","_makeArrayChecker","defaultResult","everyIn","every","filterWith","findIndex","find","findWhere","findIndexWhere","flatMap","array","el","arr","v","rLen","flatMapWith","_makeArrayFlattener","isDeep","_flatten","output","j","vLen","flatten","_toNaturalIndex","getIndex","index","getAt","group","groupBy","head","indexBy","init","insert","splice","insertAt","join","separator","String","joinWith","last","_argsToArrayFrom","list","partition","partitionWith","getIn","obj","getKey","pluckKey","pullFrom","values","pull","reduceRight","reduceRightWith","rotate","amount","shift","rotateBy","_setIndex","updater","setAt","aritize","arity","setIndex","shallowFlatten","someIn","some","_compareWith","criteria","criterion","compare","isDescending","_comparer","_sorter","reader","comparer","_makeCriterion","_makeCriteria","sorters","sort","sorter","sorterDesc","sortWith","tail","takeFrom","take","transpose","minLen","elementLen","_makeTypeErrorFor","desiredType","toLowerCase","pipe","functions","unionBy","union","updateIndex","zipWithIndex","application","applyTo","_curry","isAutoCurry","_currier","argsHolder","holderLen","newArgsLen","reverse","c","_argsTail","_invoker","boundArgs","methodName","target","method","boundArgsLen","ofs","_checkPredicates","checkAll","predicates","allOf","anyOf","areSame","gt","gte","is","isGT","isGTE","lt","isLT","lte","isLTE","sum","add","subtract","deduct","divide","divideBy","isInteger","multiply","multiplyBy","_forceToNumber","_isOwnEnumerable","propertyIsEnumerable","_safeEnumerables","_isEnumerable","indexOf","_getPathKey","includeNonEnumerables","_getPathInfo","parts","walkNonEnumerables","isValid","_toPathParts","path","split","getPathIn","_unsafeKeyListFrom","getKeys","enumerables","getPath","has","hasKey","hasOwn","hasOwnProperty","hasOwnKey","keys","make","names","valuesLen","mapValues","source","mapValuesWith","_merge","merge","mergeOwn","_keyToPairIn","_pairsFrom","ownPairs","_valuesFrom","ownValues","pairs","pathExistsIn","pathExists","pick","whitelist","pickIf","pickKeys","rename","keysMap","oldKeys","prop","renameKeys","_setIn","setIn","setKey","_setPathIn","partsLen","targetKey","setPathIn","skip","blacklist","props","skipIf","skipKeys","_tearFrom","tear","tearOwn","updateIn","updateKey","updatePathIn","pathInfo","validate","checkers","errors","_checker","validateWith","_repeat","times","_getPadding","char","ceil","_search","search","always","partialRight","difference","other","isNotInOther","dropWhile","intersection","lenA","pluck","sortedInsert","_getInsertionIndex","pivot","takeWhile","updateAt","zip","asPartial","_asPartial","collect","curry","curryable","curryableRight","curryRight","debounce","timespan","timeoutID","debounced","clearTimeout","setTimeout","flip","getArgAt","invoker","invokerOn","mapArgs","mapper","tapArgs","tappers","tappersLen","throttle","lastCall","now","Date","unary","adapter","case","condition","trueFn","falseFn","unless","when","generate","limit","isFinite","isSafeInteger","modulo","randomInt","random","range","remainder","checker","message","keyPaths","pathSeparator","getValues","fromPairs","pairsList","pair","hasKeyValue","hasPathValue","immutable","_immutable","freeze","getOwnPropertyNames","keySatisfies","pathSatisfies","renameWith","setPath","updatePath","padLeft","padRight","repeat","testWith","pattern","s","isInstanceOf","constructor","isType","typeName","defineProperty"],"mappings":"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","file":"lamb.min.js","sourcesContent":["/**\n* @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming.\n* @author Andrea Scartabelli \n* @version 0.58.0-alpha.1\n* @module lamb\n* @license MIT\n* @preserve\n*/\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define(['exports'], factory) :\n (global = global || self, factory(global.lamb = {}));\n}(this, function (exports) { 'use strict';\n\n /**\n * The placeholder object used in partial application.\n * @memberof module:lamb\n * @alias module:lamb.__\n * @category Special properties\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.57.0\n * @type {Object}\n */\n var __ = {};\n\n /**\n * Builds a function that returns a constant value.\n * It's actually the simplest form of the K combinator or Kestrel.\n * @example\n * var truth = _.always(true);\n *\n * truth() // => true\n * truth(false) // => true\n * truth(1, 2) // => true\n *\n * // the value being returned is actually the\n * // very same value passed to the function\n * var foo = {bar: \"baz\"};\n * var alwaysFoo = _.always(foo);\n *\n * alwaysFoo() === foo // => true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n function always (value) {\n return function () {\n return value;\n };\n }\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValueZero\" comparison.
\n * With this comparison NaN is equal to itself, but 0 and -0 are\n * considered the same value.
\n * See also {@link module:lamb.isSVZ|isSVZ} for a curried version building a predicate and\n * {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is} to perform a \"SameValue\" comparison.\n * @example\n * var testObject = {};\n *\n * _.areSVZ({}, testObject) // => false\n * _.areSVZ(testObject, testObject) // => true\n * _.areSVZ(\"foo\", \"foo\") // => true\n * _.areSVZ(0, -0) // => true\n * _.areSVZ(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.isSVZ|isSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSVZ (a, b) {\n return a !== a ? b !== b : a === b; // eslint-disable-line no-self-compare\n }\n\n /**\n * Builds a function that passes only two arguments to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * _.list(1, 2, 3, 4, 5) // => [1, 2, 3, 4, 5]\n * _.binary(_.list)(1, 2, 3, 4, 5) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.unary|unary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function binary (fn) {\n return function (a, b) {\n return fn.call(this, a, b);\n };\n }\n\n /**\n * \"Clamps\" a number within the given limits, both included.
\n * The function will convert to number all its parameters before starting any\n * evaluation, and will return NaN if min is greater\n * than max.\n * @example\n * _.clamp(-5, 0, 10) // => 0\n * _.clamp(5, 0, 10) // => 5\n * _.clamp(15, 0, 10) // => 10\n * _.clamp(0, 0, 10) // => 0\n * _.clamp(10, 0, 10) // => 10\n * _.is(_.clamp(-0, 0, 10), -0) // => true\n * _.clamp(10, 20, 15) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.clampWithin|clampWithin}\n * @since 0.13.0\n * @param {Number} n\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function clamp (n, min, max) {\n n = +n;\n min = +min;\n max = +max;\n\n if (min > max) {\n return NaN;\n } else {\n return n < min ? min : n > max ? max : n;\n }\n }\n\n /**\n * Builds a partially applied function.
\n * The {@link module:lamb.__|__} object can be used as a placeholder for arguments.
\n * @example\n * var __ = _.__;\n * var users = [\n * {id: 1, name: \"John\", active: true, confirmedMail: true},\n * {id: 2, name: \"Jane\", active: true, confirmedMail: false},\n * {id: 3, name: \"Mario\", active: false, confirmedMail: false}\n * ];\n * var isKeyTrue = _.partial(_.hasKeyValue, [__, true]);\n * var isActive = isKeyTrue(\"active\");\n * var hasConfirmedMail = isKeyTrue(\"confirmedMail\");\n *\n * _.map(users, isActive) // => [true, true, false]\n * _.map(users, hasConfirmedMail) // => [true, false, false]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.1.0\n * @param {Function} fn\n * @param {Array} args\n * @returns {Function}\n */\n function partial (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = 0;\n var newArgs = [];\n var argsLen = args.length;\n\n for (var i = 0, boundArg; i < argsLen; i++) {\n boundArg = args[i];\n newArgs[i] = boundArg === __ ? arguments[lastIdx++] : boundArg;\n }\n\n for (var len = arguments.length; lastIdx < len; lastIdx++) {\n newArgs[i++] = arguments[lastIdx];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Builds a partial application of a ternary function so that its first parameter\n * is expected as the last one.
\n * The shouldAritize parameter is for the \"reduce\" functions, where\n * the absence of the initialValue transforms a \"fold\" operation into a\n * \"reduce\" one.\n * @private\n * @param {Function} fn\n * @param {Boolean} shouldAritize\n * @returns {Function}\n */\n function _makePartial3 (fn, shouldAritize) {\n return function (a, b) {\n var f = shouldAritize && arguments.length !== 2 ? binary(fn) : fn;\n\n return partial(f, [__, a, b]);\n };\n }\n\n /**\n * A curried version of {@link module:lamb.clamp|clamp}, expecting a min\n * and a max value, that builds a function waiting for the number to clamp.\n * @example\n * _.clampWithin(0, 10)(-5) // => 0\n * _.clampWithin(0, 10)(5) // => 5\n * _.clampWithin(0, 10)(15) // => 10\n * _.clampWithin(0, 10)(0) // => 0\n * _.clampWithin(0, 10)(10) // => 10\n * _.is(_.clampWithin(0, 10)(-0), -0) // => true\n * _.clampWithin(20, 15)(10) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.clamp|clamp}\n * @since 0.47.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Function}\n */\n var clampWithin = _makePartial3(clamp);\n\n /**\n * The I combinator. Any value passed to the function is simply returned as it is.\n * @example\n * var foo = {bar: \"baz\"};\n *\n * _.identity(foo) === foo // true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {*} The value passed as parameter.\n */\n function identity (value) {\n return value;\n }\n\n /**\n * Returns a function that is the composition of the functions given as parameters.\n * The first function consumes the result of the function that follows.\n * @example\n * var sayHi = function (name) { return \"Hi, \" + name; };\n * var capitalize = function (s) {\n * return s[0].toUpperCase() + s.substr(1).toLowerCase();\n * };\n * var fixNameAndSayHi = _.compose(sayHi, capitalize);\n *\n * sayHi(\"bOb\") // => \"Hi, bOb\"\n * fixNameAndSayHi(\"bOb\") // \"Hi, Bob\"\n *\n * var users = [{name: \"fred\"}, {name: \"bOb\"}];\n * var sayHiToUser = _.compose(fixNameAndSayHi, _.getKey(\"name\"));\n *\n * _.map(users, sayHiToUser) // [\"Hi, Fred\", \"Hi, Bob\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.pipe|pipe}\n * @since 0.1.0\n * @param {Function} a\n * @param {Function} b\n * @returns {Function}\n */\n function compose (a, b) {\n return arguments.length ? function () {\n return a.call(this, b.apply(this, arguments));\n } : identity;\n }\n\n var MAX_ARRAY_LENGTH = 4294967295;\n var MAX_SAFE_INTEGER = 9007199254740991;\n\n /**\n * Converts a value to a valid array length, thus an integer within\n * 0 and 232 - 1 (both included).\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toArrayLength (value) {\n return clamp(value, 0, MAX_ARRAY_LENGTH) >>> 0;\n }\n\n /**\n * Executes the provided iteratee for each element of the given array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example Adding a CSS class to all elements of a NodeList in a browser environment:\n * var addClass = _.curry(function (className, element) {\n * element.classList.add(className);\n * });\n * var paragraphs = document.querySelectorAll(\"#some-container p\");\n *\n * _.forEach(paragraphs, addClass(\"main\"));\n * // each \"p\" element in the container will have the \"main\" class now\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Undefined}\n */\n function forEach (arrayLike, iteratee) {\n for (var i = 0, len = _toArrayLength(arrayLike.length); i < len; i++) {\n iteratee(arrayLike[i], i, arrayLike);\n }\n }\n\n /**\n * Creates generic functions out of methods.\n * @author A very little change on a great idea by [Irakli Gozalishvili]{@link https://github.com/Gozala/}.\n * Thanks for this *beautiful* one-liner (never liked your \"unbind\" naming choice, though).\n * @memberof module:lamb\n * @category Function\n * @function\n * @example\n * var join = _.generic(Array.prototype.join);\n *\n * join([1, 2, 3, 4, 5], \"-\") // => \"1-2-3-4-5\"\n *\n * // the function will work with any array-like object\n * join(\"hello\", \"-\") // => \"h-e-l-l-o\"\n *\n * @since 0.1.0\n * @param {Function} method\n * @returns {Function}\n */\n var generic = Function.bind.bind(Function.call);\n\n /**\n * Verifies if a value is null.\n * @example\n * _.isNull(null) // => true\n * _.isNull(void 0) // => false\n * _.isNull(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for undefined too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNull (value) {\n return value === null;\n }\n\n /**\n * Verifies if a value is undefined.\n * @example\n * _.isUndefined(null) // => false\n * _.isUndefined(void 0) // => true\n * _.isUndefined(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for null too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isUndefined (value) {\n return value === void 0;\n }\n\n /**\n * Verifies if a value is null or undefined.\n * @example\n * _.isNil(NaN) // => false\n * _.isNil({}) // => false\n * _.isNil(null) // => true\n * _.isNil(void 0) // => true\n * _.isNil() // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNull|isNull}\n * @see {@link module:lamb.isUndefined|isUndefined}\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNil (value) {\n return isNull(value) || isUndefined(value);\n }\n\n /**\n * Curries a function of arity 2.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry2 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return isRightCurry ? fn.call(this, b, a) : fn.call(this, a, b);\n };\n };\n }\n\n /**\n * A curried version of {@link module:lamb.areSVZ|areSVZ}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValueZero\"\n * comparison.
\n * See also {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is}\n * to perform a \"SameValue\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.isSVZ(john);\n * var isZero = _.isSVZ(0);\n * var isReallyNaN = _.isSVZ(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isZero(0) // => true\n * isZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSVZ|areSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var isSVZ = _curry2(areSVZ);\n\n /**\n * Builds a new array by applying the iteratee function to each element of the\n * received array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.map([\"Joe\", \"Mario\", \"Jane\"], _.invoker(\"toUpperCase\")) // => [\"JOE\", \"MARIO\", \"JANE\"]\n *\n * _.map([4, 9, 16], Math.sqrt); // => [2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.mapWith|mapWith}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function map (arrayLike, iteratee) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = iteratee(arrayLike[i], i, arrayLike);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.map|map} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var square = function (n) { return n * n; };\n * var getSquares = _.mapWith(square);\n *\n * getSquares([1, 2, 3, 4, 5]) // => [1, 4, 9, 16, 25]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.map|map}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ListIteratorCallback} iteratee\n * @returns {function}\n */\n var mapWith = _curry2(map, true);\n\n /**\n * Like {@link module:lamb.partial|partial} will build a partially applied function and\n * it will accept placeholders.
\n * The difference is that the bound arguments will be appended to the ones received by\n * the resulting function.\n * @example\n * Explaining the difference with partial:\n * var f1 = _.partial(_.list, [\"a\", \"b\", \"c\"]);\n * var f2 = _.partialRight(_.list, [\"a\", \"b\", \"c\"]);\n *\n * f1(\"d\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"d\", \"e\") // => [\"d\", \"e\", \"a\", \"b\", \"c\"]\n *\n * @example\n * Explaining placeholder substitutions:\n * var __ = _.__;\n * var f1 = _.partial(_.list, [\"a\", __, __, \"d\"]);\n * var f2 = _.partialRight(_.list, [\"a\", __, __, \"d\"]);\n *\n * f1(\"b\", \"c\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"b\", \"c\", \"e\") // => [\"b\", \"a\", \"c\", \"e\", \"d\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @param {Function} fn\n * @param {Array} args\n * @since 0.52.0\n * @returns {Function}\n */\n function partialRight (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = arguments.length - 1;\n var argsLen = args.length;\n var boundArgs = Array(argsLen);\n var newArgs = [];\n\n for (var i = argsLen - 1, boundArg; i > -1; i--) {\n boundArg = args[i];\n boundArgs[i] = boundArg === __ ? arguments[lastIdx--] : boundArg;\n }\n\n for (i = 0; i <= lastIdx; i++) {\n newArgs[i] = arguments[i];\n }\n\n for (var j = 0; j < argsLen; j++) {\n newArgs[i++] = boundArgs[j];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Builds a reduce function. The step parameter must be 1\n * to build {@link module:lamb.reduce|reduce} and -1 to build\n * {@link module:lamb.reduceRight|reduceRight}.\n * @private\n * @param {Number} step\n * @returns {Function}\n */\n function _makeReducer (step) {\n return function (arrayLike, accumulator, initialValue) {\n var len = _toArrayLength(arrayLike.length);\n var idx = step === 1 ? 0 : len - 1;\n var nCalls;\n var result;\n\n if (arguments.length === 3) {\n nCalls = len;\n result = initialValue;\n } else {\n if (len === 0) {\n throw new TypeError(\"Reduce of empty array-like with no initial value\");\n }\n\n result = arrayLike[idx];\n idx += step;\n nCalls = len - 1;\n }\n\n for (; nCalls--; idx += step) {\n result = accumulator(result, arrayLike[idx], idx, arrayLike);\n }\n\n return result;\n };\n }\n\n /**\n * Reduces (or folds) the values of an array-like object, starting from the first, to a new\n * value using the provided accumulator function.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.reduce([1, 2, 3, 4], _.sum) // => 10\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRight|reduceRight}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduce = _makeReducer(1);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduce} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceWith(_.sum)(arr) // => 15\n * _.reduceWith(_.subtract)(arr) // => -13\n * _.reduceWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRightWith|reduceRightWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceWith = _makePartial3(reduce, true);\n\n /**\n * Converts a value to an integer.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toInteger (value) {\n var n = +value;\n\n if (n !== n) { // eslint-disable-line no-self-compare\n return 0;\n } else if (n % 1 === 0) {\n return n;\n } else {\n return Math.floor(Math.abs(n)) * (n < 0 ? -1 : 1);\n }\n }\n\n /**\n * Builds an array by extracting a portion of an array-like object.
\n * Note that unlike the native array method this function ensures that dense\n * arrays are returned.
\n * Also, unlike the native method, the start and end\n * parameters aren't optional and will be simply converted to integer.
\n * See {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.slice(arr, 0, 2) // => [1, 2]\n * _.slice(arr, 2, -1) // => [3, 4]\n * _.slice(arr, -3, 5) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sliceAt|sliceAt}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike - Any array like object.\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Array}\n */\n function slice (arrayLike, start, end) {\n var len = _toArrayLength(arrayLike.length);\n var begin = _toInteger(start);\n var upTo = _toInteger(end);\n\n if (begin < 0) {\n begin = begin < -len ? 0 : begin + len;\n }\n\n if (upTo < 0) {\n upTo = upTo < -len ? 0 : upTo + len;\n } else if (upTo > len) {\n upTo = len;\n }\n\n var resultLen = upTo - begin;\n var result = resultLen > 0 ? Array(resultLen) : [];\n\n for (var i = 0; i < resultLen; i++) {\n result[i] = arrayLike[begin + i];\n }\n\n return result;\n }\n\n /**\n * Given the start and end bounds, builds a partial application\n * of {@link module:lamb.slice|slice} expecting the array-like object to slice.
\n * See also {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var s = \"hello\";\n * var dropFirstAndLast = _.sliceAt(1, -1);\n *\n * dropFirstAndLast(arr) // => [2, 3, 4]\n * dropFirstAndLast(s) // => [\"e\", \"l\", \"l\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.slice|slice}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.48.0\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Function}\n */\n var sliceAt = _makePartial3(slice);\n\n var objectProtoToString = Object.prototype.toString;\n\n /**\n * Retrieves the \"type tag\" from the given value.\n * @example\n * var x = 5;\n * var y = new Number(5);\n *\n * typeof x // => \"number\"\n * typeof y // => \"object\"\n * _.type(x) // => \"Number\"\n * _.type(y) // => \"Number\"\n *\n * _.type(Object.prototype.toString) // => \"Function\"\n * _.type(/a/) // => \"RegExp\"\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.9.0\n * @param {*} value\n * @returns {String}\n */\n function type (value) {\n return objectProtoToString.call(value).slice(8, -1);\n }\n\n /**\n * Appends the given value at the end of a copy of the provided array-like object.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.appendTo(arr, 5) // => [1, 2, 3, 4, 5]\n * _.appendTo(arr, [5]) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.append|append}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Array}\n */\n function appendTo (arrayLike, value) {\n return slice(arrayLike, 0, arrayLike.length).concat([value]);\n }\n\n /**\n * A curried version of {@link module:lamb.appendTo|appendTo} that uses the value to append\n * to build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.append(5)(arr) // => [1, 2, 3, 4, 5]\n * _.append([5])(arr) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.appendTo|appendTo}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {*} value\n * @returns {Function}\n */\n var append = _curry2(appendTo, true);\n\n /**\n * Checks if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.contains|contains} for a curried version building a predicate.\n * @example\n * var numbers = [0, 1, 2, 3, NaN];\n *\n * _.isIn(numbers, 1) // => true\n * _.isIn(numbers, 0) // => true\n * _.isIn(numbers, -0) // => true\n * _.isIn(numbers, NaN) // => true\n * _.isIn(numbers, 5) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.contains|contains}\n * @since 0.13.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Boolean}\n */\n function isIn (arrayLike, value) {\n var result = false;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (areSVZ(value, arrayLike[i])) {\n result = true;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Builds a predicate to check if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.isIn|isIn} for an uncurried version.\n * @example\n * var containsNaN = _.contains(NaN);\n *\n * containsNaN([0, 1, 2, 3, NaN]) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.isIn|isIn}\n * @since 0.13.0\n * @param {*} value\n * @returns {Function}\n */\n var contains = _curry2(isIn, true);\n\n /**\n * Builds a \"grouping function\" for an array-like object.\n * @private\n * @param {Function} makeValue\n * @returns {Function}\n */\n function _groupWith (makeValue) {\n return function (arrayLike, iteratee) {\n var result = {};\n var len = arrayLike.length;\n\n for (var i = 0, element, key; i < len; i++) {\n element = arrayLike[i];\n key = iteratee(element, i, arrayLike);\n result[key] = makeValue(result[key], element);\n }\n\n return result;\n };\n }\n\n /**\n * Transforms an array-like object in a lookup table with the keys generated by the provided\n * iteratee, having as values the count of matches for the key.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 17},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n * var getAgeStatus = function (person) { return person.age >= 18 ? \"adult\" : \"minor\"; };\n *\n * _.count(persons, getAgeStatus) // => {\"adult\": 1, \"minor\": 3}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var count = _groupWith(function (a) {\n return a ? ++a : 1;\n });\n\n /**\n * A curried version of {@link module:lamb.count|count} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCityOrUnknown = _.adapter([_.getKey(\"city\"), _.always(\"Unknown\")]);\n * var countByCity = _.countBy(getCityOrUnknown);\n *\n * countByCity(persons) // => {\"New York\": 2, \"Rome\": 1, \"Unknown\": 1}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.count|count}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var countBy = _curry2(count, true);\n\n /**\n * Builds an array comprised of all values of the array-like object passing the predicate\n * test.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n *\n * _.filter([\"Foo\", \"bar\", \"baZ\"], isLowerCase) // => [\"bar\"]\n *\n * // the function will work with any array-like object\n * _.filter(\"fooBAR\", isLowerCase) // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.filterWith|filterWith}\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @since 0.1.0\n * @returns {Array}\n */\n function filter (arrayLike, predicate) {\n var len = arrayLike.length;\n var result = [];\n\n for (var i = 0; i < len; i++) {\n predicate(arrayLike[i], i, arrayLike) && result.push(arrayLike[i]);\n }\n\n return result;\n }\n\n /**\n * Returns a predicate that negates the given one.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isOdd = _.not(isEven);\n *\n * isOdd(5) // => true\n * isOdd(4) // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @since 0.1.0\n * @param {Function} predicate\n * @returns {Function}\n */\n function not (predicate) {\n return function () {\n return !predicate.apply(this, arguments);\n };\n }\n\n /**\n * Using the provided iteratee, builds a function that will return an array comprised of the\n * unique elements of an array-like object. The values being compared are the ones returned by\n * the iteratee.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniques|uniques} if you don't need to transform your values before the\n * comparison.\n * @example\n * var data = [\n * {id: \"1\", name: \"John\"},\n * {id: \"4\", name: \"Jane\"},\n * {id: \"5\", name: \"Joe\"},\n * {id: \"1\", name: \"Mario\"},\n * {id: \"5\", name: \"Paolo\"},\n * ];\n * var uniquesById = _.uniquesBy(_.getKey(\"id\"));\n *\n * uniquesById(data) // => [{id: \"1\", name: \"John\"}, {id: \"4\", name: \"Jane\"}, {id: \"5\", name: \"Joe\"}]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.uniques|uniques}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function uniquesBy (iteratee) {\n return function (arrayLike) {\n var result = [];\n\n for (var i = 0, len = arrayLike.length, seen = [], value; i < len; i++) {\n value = iteratee(arrayLike[i], i, arrayLike);\n\n if (!isIn(seen, value)) {\n seen.push(value);\n result.push(arrayLike[i]);\n }\n }\n\n return result;\n };\n }\n\n /**\n * Returns an array comprised of the unique elements of the given array-like object.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniquesBy|uniquesBy} if you need to transform your values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.uniques([-0, 1, 2, 0, 2, 3, 4, 3, 5, 1]) // => [-0, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.uniquesBy|uniquesBy}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var uniques = uniquesBy(identity);\n\n /**\n * Returns an array of unique items present only in the first of the two given\n * array-like objects. To determine uniqueness the function uses the\n * [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 1, 3, 4];\n * var a2 = [2, 4, 5, 6];\n * var a3 = [3, 4, 5, 2, 1];\n *\n * _.difference(a1, a2) // => [1, 3]\n * _.difference(a2, a3) // => [6]\n * _.difference(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.intersection|intersection}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.pull|pull}, {@link module:lamb.pullFrom|pullFrom}\n * @since 0.6.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} other\n * @returns {Array}\n */\n function difference (arrayLike, other) {\n var isNotInOther = partial(not(isIn), [other]);\n\n return uniques(filter(arrayLike, isNotInOther));\n }\n\n /**\n * Builds an array without the first n elements of the given array or array-like object.\n * Note that, being this only a shortcut for a specific use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.dropFrom(arr, 2) // => [3, 4, 5]\n * _.dropFrom(arr, -1) // => [5]\n * _.dropFrom(arr, -10) // => [1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function dropFrom (arrayLike, n) {\n return slice(arrayLike, n, arrayLike.length);\n }\n\n /**\n * A curried version of {@link module:lamb.dropFrom|dropFrom} that expects the number of elements\n * to drop to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.dropFrom|dropFrom} about passing a\n * negative n.\n * @example\n * var drop2 = _.drop(2);\n *\n * drop2([1, 2, 3, 4, 5]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.5.0\n * @see {@link module:lamb.dropFrom|dropFrom}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {Number} n\n * @returns {Function}\n */\n var drop = _curry2(dropFrom, true);\n\n /**\n * Gets the number of consecutive elements satisfying a predicate in an array-like object.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function _getNumConsecutiveHits (arrayLike, predicate) {\n var idx = 0;\n var len = arrayLike.length;\n\n while (idx < len && predicate(arrayLike[idx], idx, arrayLike)) {\n idx++;\n }\n\n return idx;\n }\n\n /**\n * Builds a function that drops the first n elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropWhileIsEven = _.dropWhile(isEven);\n *\n * dropWhileIsEven([2, 4, 6, 8]) // => []\n * dropWhileIsEven([2, 4, 7, 8]) // => [7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.takeWhile|takeWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n function dropWhile (predicate) {\n return function (arrayLike) {\n return slice(arrayLike, _getNumConsecutiveHits(arrayLike, predicate), arrayLike.length);\n };\n }\n\n /**\n * Helper to build the {@link module:lamb.everyIn|everyIn} or the\n * {@link module:lamb.someIn|someIn} function.\n * @private\n * @param {Boolean} defaultResult\n * @returns {Function}\n */\n function _makeArrayChecker (defaultResult) {\n return function (arrayLike, predicate) {\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (defaultResult ^ !!predicate(arrayLike[i], i, arrayLike)) {\n return !defaultResult;\n }\n }\n\n return defaultResult;\n };\n }\n\n /**\n * Checks if all the elements in an array-like object satisfy the given predicate.
\n * The function will stop calling the predicate as soon as it returns a falsy value.
\n * Note that an empty array-like will always produce a true result regardless of the\n * predicate because of [vacuous truth]{@link https://en.wikipedia.org/wiki/Vacuous_truth}.
\n * Also note that unlike the native\n * [Array.prototype.every]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: true},\n * {\"name\": \"John\", \"age\": 40, active: true},\n * {\"name\": \"Mario\", \"age\": 17, active: true},\n * {\"name\": \"Paolo\", \"age\": 15, active: true}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.everyIn(persons, isAdult) // => false\n * _.everyIn(persons, isActive) // => true\n *\n * @example Showing the difference with Array.prototype.every:\n * var isDefined = _.not(_.isUndefined);\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.every(isDefined) // => true\n * _.everyIn(arr, isDefined) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.every|every}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var everyIn = _makeArrayChecker(true);\n\n /**\n * A curried version of {@link module:lamb.everyIn|everyIn} that expects a predicate\n * to build a function waiting for the array-like to act upon.\n * @example\n * var data = [2, 3, 5, 6, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var allEvens = _.every(isEven);\n * var allIntegers = _.every(_.isInteger);\n *\n * allEvens(data) // => false\n * allIntegers(data) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.everyIn|everyIn}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var every = _curry2(everyIn, true);\n\n /**\n * A curried version of {@link module:lamb.filter|filter} that uses the given predicate\n * to build a function expecting the array-like object to act upon.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n * var getLowerCaseEntries = _.filterWith(isLowerCase);\n *\n * getLowerCaseEntries([\"Foo\", \"bar\", \"baZ\"]) // => [\"bar\"]\n *\n * // array-like objects can be used as well\n * getLowerCaseEntries(\"fooBAR\") // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.filter|filter}\n * @since 0.9.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var filterWith = _curry2(filter, true);\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns its\n * index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findIndex(persons, _.hasKeyValue(\"age\", 40)) // => 1\n * _.findIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function findIndex (arrayLike, predicate) {\n var result = -1;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (predicate(arrayLike[i], i, arrayLike)) {\n result = i;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns it if\n * the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.find(persons, _.hasKeyValue(\"age\", 40)) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.find(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\n function find (arrayLike, predicate) {\n var idx = findIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n }\n\n /**\n * A curried version of {@link module:lamb.find|find} expecting the array-like object\n * to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 7]) // => 4\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.find|find}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findWhere = _curry2(find, true);\n\n /**\n * A curried version of {@link module:lamb.findIndex|findIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEvenIdx = _.findIndexWhere(isEven);\n *\n * findEvenIdx([1, 3, 4, 5, 7]) // => 2\n * findEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findIndex|findIndex}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findIndexWhere = _curry2(findIndex, true);\n\n /**\n * Similar to {@link module:lamb.map|map}, but if the mapping function returns an array this will\n * be concatenated, rather than pushed, to the final result.\n * @example Showing the difference with map:\n * var words = [\"foo\", \"bar\"];\n * var toCharArray = function (s) { return s.split(\"\"); };\n *\n * _.map(words, toCharArray) // => [[\"f\", \"o\", \"o\"], [\"b\", \"a\", \"r\"]]\n * _.flatMap(words, toCharArray) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.flatMapWith|flatMapWith}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.1.0\n * @param {Array} array\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function flatMap (array, iteratee) {\n return reduce(array, function (result, el, idx, arr) {\n var v = iteratee(el, idx, arr);\n\n if (!Array.isArray(v)) {\n v = [v];\n }\n\n for (var i = 0, len = v.length, rLen = result.length; i < len; i++) {\n result[rLen + i] = v[i];\n }\n\n return result;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.flatMap|flatMap} that uses provided iteratee\n * to build a function expecting the array to act upon.\n * @example\n * var toCharArray = function (s) { return s.split(\"\"); };\n * var wordsToCharArray = _.flatMapWith(toCharArray);\n *\n * wordsToCharArray([\"foo\", \"bar\"]) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatMap|flatMap}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.11.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var flatMapWith = _curry2(flatMap, true);\n\n /**\n * Flattens an array.\n * @private\n * @param {Array} array - The source array\n * @param {Boolean} isDeep - Whether to perform a deep flattening or not\n * @param {Array} output - An array to collect the result\n * @param {Number} idx - The next index to be filled in the output\n * @returns {Array} The output array filled with the results\n */\n function _flatten (array, isDeep, output, idx) {\n for (var i = 0, len = array.length, value, j, vLen; i < len; i++) {\n value = array[i];\n\n if (!Array.isArray(value)) {\n output[idx++] = value;\n } else if (isDeep) {\n _flatten(value, true, output, idx);\n idx = output.length;\n } else {\n vLen = value.length;\n output.length += vLen;\n\n for (j = 0; j < vLen; j++) {\n output[idx++] = value[j];\n }\n }\n }\n\n return output;\n }\n\n /**\n * Helper to build the {@link module:lamb.flatten|flatten} and\n * {@link module:lamb.shallowFlatten|shallowFlatten} functions.\n * @private\n * @function\n * @param {Boolean} isDeep\n * @returns {Function}\n */\n var _makeArrayFlattener = _curry2(function (isDeep, array) {\n return Array.isArray(array) ? _flatten(array, isDeep, [], 0) : slice(array, 0, array.length);\n });\n\n /**\n * Flattens an array.\n * @example Showing the difference with shallowFlatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.shallowFlatten|shallowFlatten}\n * @since 0.1.0\n * @param {Array} array\n * @returns {Array}\n */\n var flatten = _makeArrayFlattener(true);\n\n /**\n * Checks if the given number, even negative, represents an array-like index\n * within the provided length. If so returns its natural number equivalent.
\n * Returns NaN otherwise.\n * @private\n * @param {Number} idx\n * @param {Number} len\n * @returns {Number}\n */\n function _toNaturalIndex (idx, len) {\n idx = _toInteger(idx);\n\n return idx >= -len && idx < len ? idx < 0 ? idx + len : idx : NaN;\n }\n\n /**\n * Retrieves the element at the given index in an array-like object.
\n * Like {@link module:lamb.slice|slice} the index can be negative.
\n * If the index isn't supplied, or if its value isn't an integer within the array-like bounds,\n * the function will return undefined.
\n * getIndex will throw an exception when receives null or\n * undefined in place of an array-like object, but returns undefined\n * for any other value.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.getIndex(arr, 1) // => 2\n * _.getIndex(arr, -1) // => 5\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.getAt|getAt}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @returns {*}\n */\n function getIndex (arrayLike, index) {\n var idx = _toNaturalIndex(index, _toArrayLength(arrayLike.length));\n\n return idx === idx ? arrayLike[idx] : void 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * A curried version of {@link module:lamb.getIndex|getIndex} that uses the provided index\n * to build a function expecting the array-like object holding the element we want to retrieve.\n * @example\n * var getFifthElement = _.getAt(4);\n *\n * getFifthElement([1, 2, 3, 4, 5]) // => 5\n * getFifthElement(\"foo bar\") // => \"b\"\n * getFifthElement([]) // => undefined\n * getFifthElement(\"foo\") // => undefined\n *\n * @example Using negative indexes:\n * _.getAt(-2)([1, 2, 3]) // => 2\n * _.getAt(-3)(\"foo\") // => \"f\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.16.0\n * @see {@link module:lamb.getIndex|getIndex}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @param {Number} index\n * @returns {Function}\n */\n var getAt = _curry2(getIndex, true);\n\n /**\n * Transforms an array-like object into a lookup table using the provided iteratee as a grouping\n * criterion to generate keys and values.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCity = _.getKey(\"city\");\n * var personsByCity = _.group(persons, getCity);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"undefined\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @example Adding a custom value for missing keys:\n *\n * var getCityOrUnknown = _.adapter([getCity, _.always(\"Unknown\")]);\n *\n * var personsByCity = _.group(persons, getCityOrUnknown);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"Unknown\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var group = _groupWith(function (a, b) {\n if (!a) {\n return [b];\n }\n\n a[a.length] = b;\n\n return a;\n });\n\n /**\n * A curried version of {@link module:lamb.group|group} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 18},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n *\n * var getAgeStatus = function (person) { return person.age > 20 ? \"over 20\" : \"under 20\"; };\n * var groupByAgeStatus = _.groupBy(getAgeStatus);\n *\n * var personsByAgeStatus = groupByAgeStatus(persons);\n *\n * // \"personsByAgeStatus\" holds:\n * // {\n * // \"under 20\": [\n * // {\"name\": \"Jane\", \"age\": 12},\n * // {\"name\": \"Mario\", \"age\": 18},\n * // {\"name\": \"Paolo\", \"age\": 15}\n * // ],\n * // \"over 20\": [\n * // {\"name\": \"John\", \"age\": 40}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.group|group}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var groupBy = _curry2(group, true);\n\n /**\n * Retrieves the first element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.head([1, 2, 3]) // => 1\n * _.head(\"hello\") // => \"h\"\n * _.head([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.last|last}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var head = getAt(0);\n\n /**\n * Similar to {@link module:lamb.group|group}, but the generated lookup table will have\n * only one element of the original array-like object for each value.
\n * Should be used only when you're sure that your iteratee won't produce\n * duplicate keys, otherwise only the last evaluated element will be in the result.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"id\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"},\n * // \"4\": {id: 4, name: \"John\"}\n * // }\n *\n * @example Result of an iteratee producing a duplicate key:\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"name\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"John\": {\"id\": 4, \"name\": \"John\"},\n * // \"Jane\": {\"id\": 2, \"name\": \"Jane\"},\n * // \"Mario\": {\"id\": 3, \"name\": \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.indexBy|indexBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var index = _groupWith(function (a, b) {\n return b;\n });\n\n /**\n * A curried version of {@link module:lamb.index|index} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"}\n * ];\n * var indexByID = _.indexBy(_.getKey(\"id\"));\n *\n * var indexedUsers = indexByID(users);\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.index|index}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var indexBy = _curry2(index, true);\n\n /**\n * Returns a copy of the given array-like object without the last element.\n * @example\n * _.init([1, 2, 3, 4]) // => [1, 2, 3]\n * _.init([1]) // => []\n * _.init([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.tail|tail}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var init = partial(slice, [__, 0, -1]);\n\n /**\n * Inserts the provided element in a copy of an array-like object at the\n * specified index.
\n * If the index is greater than the length of the array-like, the element\n * will be appended at the end.
\n * Negative indexes are allowed; when a negative index is out of bounds\n * the element will be inserted at the start of the resulting array.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insert(arr, 3, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, -2, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, 10, 99) // => [1, 2, 3, 4, 5, 99]\n * _.insert(arr, -10, 99) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.insertAt|insertAt}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} element\n * @returns {Array}\n */\n function insert (arrayLike, index, element) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n result.splice(index, 0, element);\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.insert|insert}\n * expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insertAt(3, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(-2, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(10, 99)(arr) // => [1, 2, 3, 4, 5, 99]\n * _.insertAt(-10, 99)(arr) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.insert|insert}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.27.0\n * @param {Number} index\n * @param {*} element\n * @returns {Function}\n */\n var insertAt = _makePartial3(insert);\n\n /**\n * Returns an array of every unique item that is included in all two given arrays\n * or array-like objects.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 5, 4, 2, 6];\n * var a3 = [5, 6, 7];\n *\n * _.intersection(a1, a2) // => [2, 4]\n * _.intersection(a2, a3) // => [5, 6]\n * _.intersection(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n function intersection (a, b) {\n var result = [];\n var lenA = a.length;\n\n if (lenA && b.length) {\n for (var i = 0; i < lenA; i++) {\n !isIn(result, a[i]) && isIn(b, a[i]) && result.push(a[i]);\n }\n }\n\n return result;\n }\n\n /**\n * Transforms an array-like object into a string by joining its elements with\n * the given separator.
\n * Note that unlike the native method, this function won't convert\n * null and undefined values in the array to empty\n * strings and that the separator parameter isn't optional.
\n * See the examples about these differences.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n *\n * _.join(words, \"-\") // => \"foo-bar-baz\"\n *\n * @example Showing the differences with the native array method:\n * var mixed = [1, null, 2, undefined, 3, NaN, 4, 5];\n * var numbers = [1, 2, 3];\n *\n * _.join(mixed, \"-\") // => \"1-null-2-undefined-3-NaN-4-5\"\n * mixed.join(\"-\") // => \"1--2--3-NaN-4-5\"\n *\n * _.join(numbers) // => \"1undefined2undefined3\"\n * numbers.join() // => \"1,2,3\"\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.joinWith|joinWith}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {String} separator\n * @returns {String}\n */\n function join (arrayLike, separator) {\n return map(arrayLike, String).join(String(separator));\n }\n\n /**\n * A curried version of {@link module:lamb.join|join} that accepts an optional\n * separator and builds a function expecting the array-like object to act upon.
\n * Please refer to the description and examples of {@link module:lamb.join|join}\n * to understand the differences with the native array method.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n * var joinWithDash = _.joinWith(\"-\");\n *\n * joinWithDash(words) // => \"foo-bar-baz\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.join|join}\n * @since 0.58.0\n * @param {String} separator\n * @returns {Function}\n */\n var joinWith = _curry2(join, true);\n\n /**\n * Retrieves the last element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.last([1, 2, 3]) // => 3\n * _.last(\"hello\") // => \"o\"\n * _.last([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.head|head}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var last = getAt(-1);\n\n /**\n * Builds helper functions to extract portions of the arguments\n * object rather efficiently without having to write for loops\n * manually for each case.
\n * The arguments object needs to be passed to the apply method\n * of the generated function.\n * @private\n * @param {Number} idx\n * @returns {Function}\n */\n function _argsToArrayFrom (idx) {\n return function () {\n var argsLen = arguments.length || idx;\n var len = argsLen - idx;\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = arguments[i + idx];\n }\n\n return result;\n };\n }\n\n /**\n * Generates an array with the values passed as arguments.
\n * Behaves like ES6's [Array.of]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of}.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.1.0\n * @param {...*} value\n * @returns {Array}\n */\n var list = _argsToArrayFrom(0);\n\n /**\n * Splits an array-like object in two lists: the first with the elements satisfying the given predicate,\n * the others with the remaining elements.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * _.partition(numbers, isEven) // => [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.partitionWith|partitionWith}\n * @since 0.11.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Array}\n */\n function partition (arrayLike, predicate) {\n var result = [[], []];\n var len = arrayLike.length;\n\n for (var i = 0, el; i < len; i++) {\n el = arrayLike[i];\n result[predicate(el, i, arrayLike) ? 0 : 1].push(el);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.partition|partition} that uses the provided\n * predicate to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * ];\n * var isActive = _.hasKeyValue(\"active\", true);\n * var splitByActiveStatus = _.partitionWith(isActive);\n *\n * splitByActiveStatus(users) // =>\n * // [[\n * // {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true}\n * // ], [\n * // {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * // {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * // ]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.partition|partition}\n * @since 0.11.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var partitionWith = _curry2(partition, true);\n\n /**\n * Returns the value of the object property with the given key.\n * @example\n * var user = {name: \"John\"};\n *\n * _.getIn(user, \"name\") // => \"John\";\n * _.getIn(user, \"surname\") // => undefined\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getKey|getKey}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.18.0\n * @param {Object} obj\n * @param {String} key\n * @returns {*}\n */\n function getIn (obj, key) {\n return obj[key];\n }\n\n /**\n * A curried version of {@link module:lamb.getIn|getIn}.
\n * Receives a property name and builds a function expecting the object from which we want to retrieve\n * the property.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {name: \"jane\"};\n * var getName = _.getKey(\"name\");\n *\n * getName(user1) // => \"john\"\n * getName(user2) // => \"jane\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getIn|getIn}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var getKey = _curry2(getIn, true);\n\n /**\n * \"Plucks\" the values of the specified key from a list of objects.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n *\n * _.pluck(persons, \"age\") // => [12, 40, 18, 15]\n *\n * var lists = [\n * [1, 2],\n * [3, 4, 5],\n * [6]\n * ];\n *\n * _.pluck(lists, \"length\") // => [2, 3, 1]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pluckKey|pluckKey}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {String} key\n * @returns {Array}\n */\n function pluck (arrayLike, key) {\n return map(arrayLike, getKey(key));\n }\n\n /**\n * A curried version of {@link module:lamb.pluck|pluck} expecting the key to retrieve to\n * build a function waiting for the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n * var getAges = _.pluckKey(\"age\");\n *\n * getAges(persons) // => [12, 40, 18, 15]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pluck|pluck}\n * @since 0.12.0\n * @param {String} key\n * @returns {Function}\n */\n var pluckKey = compose(mapWith, getKey);\n\n /**\n * Creates an array copy of the given array-like object without the\n * specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.pullFrom(arr, [2, 5]) // => [1, 3, 4]\n *\n * @example It's not the same as {@link module:lamb.difference|difference}:\n *\n * var arr = [1,1,2,3,4,4,5];\n *\n * _.pullFrom(arr, [1, 2]) // => [3, 4, 4, 5]\n * _.difference(arr, [1, 2]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pull|pull}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} values\n * @returns {Array}\n */\n function pullFrom (arrayLike, values) {\n return values ? filter(arrayLike, function (element) {\n return !isIn(values, element);\n }) : slice(arrayLike, 0, arrayLike.length);\n }\n\n /**\n * A curried version of {@link module:lamb.pullFrom|pullFrom} expecting\n * a list of values to build a function waiting for an array-like object.
\n * The new function will create an array copy of the array-like without\n * the specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * See examples in {@link module:lamb.pullFrom|pullFrom} about the\n * relationship with {@link module:lamb.difference|difference}.\n * @example\n * var scores = [40, 20, 30, 10];\n * var newScores = [30, 10];\n * var pullNewScores = _.pull(newScores);\n *\n * pullNewScores(scores) // => [40, 20]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pullFrom|pullFrom}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} values\n * @returns {Function}\n */\n var pull = _curry2(pullFrom, true);\n\n /**\n * Same as {@link module:lamb.reduce|reduce}, but starts the fold operation from the last\n * element instead.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduce|reduce}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduceRight = _makeReducer(-1);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduceRight} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceRightWith(_.sum)(arr) // => 15\n * _.reduceRightWith(_.subtract)(arr) // => -5\n * _.reduceRightWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceWith|reduceWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceRightWith = _makePartial3(reduceRight, true);\n\n /**\n * Reverses a copy of the given array-like object.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.reverse(arr) // => [3, 2, 1];\n *\n * // `arr` still is [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.19.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function reverse (arrayLike) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0, ofs = len - 1; i < len; i++) {\n result[i] = arrayLike[ofs - i];\n }\n\n return result;\n }\n\n /**\n * Returns a copy of the given array-like with the element rotated by the desired amount.\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.rotate(arr, 3) // => [3, 4, 5, 1, 2]\n * _.rotate(arr, -3) // => [4, 5, 1, 2, 3]\n * _.rotate(arr, 11) // => [5, 1, 2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.rotateBy|rotateBy}\n * @since 0.55.0\n * @param {ArrayLike} arrayLike\n * @param {Number} amount\n * @returns {Array}\n */\n function rotate (arrayLike, amount) {\n var len = arrayLike.length;\n var shift = amount % len;\n\n return slice(arrayLike, -shift, len).concat(slice(arrayLike, 0, -shift));\n }\n\n /**\n * A curried version of {@link module:lamb.rotate|rotate}.
\n * Uses the given amount to build a function expecting the array to rotate by that amount.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var rotateByTwo = _.rotateBy(2);\n *\n * rotateByTwo(arr) // => [4, 5, 1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.rotate|rotate}\n * @since 0.55.0\n * @param {Number} amount\n * @returns {Function}\n */\n var rotateBy = _curry2(rotate, true);\n\n /**\n * Sets an index in an array-like object.
\n * If provided with an updater function it will use it to update the current value,\n * otherwise sets the index to the specified value.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {Number} idx\n * @param {*} [value]\n * @param {Function} [updater]\n * @returns {Array}\n */\n function _setIndex (arrayLike, idx, value, updater) {\n var result = slice(arrayLike, 0, arrayLike.length);\n var n = _toNaturalIndex(idx, result.length);\n\n if (n === n) { // eslint-disable-line no-self-compare\n result[n] = arguments.length === 4 ? updater(arrayLike[n]) : value;\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.setIndex|setIndex} that builds\n * a function that creates a copy of an array-like object with the given\n * index changed to the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.setAt(2, 99)(arr) // => [1, 2, 99, 4, 5]\n * arr // => [1, 2, 3, 4, 5]\n *\n * _.setAt(10, 99)(arr) // => [1, 2, 3, 4, 5] (not a reference to `arr`)\n *\n * @example Using negative indexes:\n * _.setAt(-1, 99)(arr) // => [1, 2, 3, 4, 99]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setIndex|setIndex}\n * @since 0.17.0\n * @param {Number} index\n * @param {*} value\n * @returns {Function}\n */\n var setAt = _makePartial3(_setIndex);\n\n /**\n * Builds a new function that passes only the specified amount of arguments to the original one.
\n * As {@link module:lamb.slice|slice} is used to extract the arguments, you can also\n * pass a negative arity.\n * @example\n * Math.max(10, 11, 45, 99) // => 99\n * _.aritize(Math.max, 2)(10, 11, 45, 99) // => 11\n *\n * @example Using a negative arity:\n * _.aritize(Math.max, -1)(10, 11, 45, 99) // => 45\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.binary|binary}, {@link module:lamb.unary|unary} for common use cases shortcuts\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} arity\n * @returns {Function}\n */\n function aritize (fn, arity) {\n return function () {\n var n = _toInteger(arity);\n var args = list.apply(null, arguments).slice(0, n);\n\n for (var i = args.length; i < n; i++) {\n args[i] = void 0;\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed to\n * the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.setIndex(arr, 1, 99) // => [1, 99, 3]\n * _.setIndex(arr, -1, 99) // => [1, 2, 99]\n * _.setIndex(arr, 10, 99) // => [1, 2, 3] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setAt|setAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} value\n * @returns {Array}\n */\n var setIndex = aritize(_setIndex, 3);\n\n /**\n * Flattens the \"first level\" of an array.\n * @example Showing the difference with flatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatten|flatten}\n * @since 0.9.0\n * @param {Array} array\n * @returns {Array}\n */\n var shallowFlatten = _makeArrayFlattener(false);\n\n /**\n * Checks if at least one element in an array-like object satisfies the given predicate.
\n * The function will stop calling the predicate as soon as it returns a truthy value.
\n * Note that unlike the native\n * [Array.prototype.some]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: false},\n * {\"name\": \"John\", \"age\": 40, active: false},\n * {\"name\": \"Mario\", \"age\": 17, active: false},\n * {\"name\": \"Paolo\", \"age\": 15, active: false}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.someIn(persons, isAdult) // => true\n * _.someIn(persons, isActive) // => false\n *\n * @example Showing the difference with Array.prototype.some:\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.some(_.isUndefined) // => false\n * _.someIn(arr, _.isUndefined) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.some|some}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var someIn = _makeArrayChecker(false);\n\n /**\n * A curried version of {@link module:lamb.someIn|someIn} that uses the given predicate to\n * build a function waiting for the array-like to act upon.\n * @example\n * var data = [1, 3, 5, 6, 7, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var containsEvens = _.some(isEven);\n * var containsStrings = _.some(_.isType(\"String\"));\n *\n * containsEvens(data) // => true\n * containsStrings(data) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.someIn|someIn}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var some = _curry2(someIn, true);\n\n /**\n * Accepts a list of sorting criteria with at least one element\n * and builds a function that compares two values with such criteria.\n * @private\n * @param {Sorter[]} criteria\n * @returns {Function}\n */\n function _compareWith (criteria) {\n return function (a, b) {\n var len = criteria.length;\n var criterion = criteria[0];\n var result = criterion.compare(a.value, b.value);\n\n for (var i = 1; result === 0 && i < len; i++) {\n criterion = criteria[i];\n result = criterion.compare(a.value, b.value);\n }\n\n if (result === 0) {\n result = a.index - b.index;\n }\n\n return criterion.isDescending ? -result : result;\n };\n }\n\n /**\n * The default comparer for sorting functions.
\n * If the given values are of different types they\n * will be both converted to strings.
\n * Uses the SameValueZero comparison.\n * @private\n * @param {*} a\n * @param {*} b\n * @returns {Number} -1 | 0 | 1\n */\n function _comparer (a, b) {\n var result = 0;\n\n if (typeof a !== typeof b) {\n a = String(a);\n b = String(b);\n }\n\n if (!areSVZ(a, b)) {\n // eslint-disable-next-line no-self-compare\n result = a > b || a !== a ? 1 : -1;\n }\n\n return result;\n }\n\n /**\n * Builds a sorting criterion. If the comparer function is missing, the default\n * comparer will be used instead.\n * @private\n * @param {Function} reader\n * @param {Boolean} isDescending\n * @param {Function} [comparer]\n * @returns {Sorter}\n */\n function _sorter (reader, isDescending, comparer) {\n if (typeof reader !== \"function\" || reader === identity) {\n reader = null;\n }\n\n if (typeof comparer !== \"function\") {\n comparer = _comparer;\n }\n\n return {\n isDescending: isDescending === true,\n compare: function (a, b) {\n if (reader) {\n a = reader(a);\n b = reader(b);\n }\n\n return comparer(a, b);\n }\n };\n }\n\n /**\n * Converts a sorting function to a sorting criterion if necessary.\n * @private\n * @param {Function} criterion\n * @returns {Sorter}\n */\n function _makeCriterion (criterion) {\n return criterion && typeof criterion.compare === \"function\" ? criterion : _sorter(criterion);\n }\n\n /**\n * Builds a list of sorting criteria from a list of sorter functions. Returns a list containing\n * a single default sorting criterion if the sorter list is empty.\n * @private\n * @param {Function[]} sorters\n * @returns {Sorter[]}\n */\n function _makeCriteria (sorters) {\n return sorters && sorters.length ? map(sorters, _makeCriterion) : [_sorter()];\n }\n\n /**\n * Returns a [stably]{@link https://en.wikipedia.org/wiki/Sorting_algorithm#Stability} sorted\n * copy of an array-like object using the given criteria.
\n * Sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you\n * can also pass simple \"reader\" functions and default ascending sorters will be built for you.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used\n * in the comparison.
\n * Please note that if the arguments received by the default comparer aren't of the same type,\n * they will be compared as strings.\n *\n * @example Stable sort:\n * var persons = [\n * {\"name\": \"John\", \"surname\" :\"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"},\n * {\"name\": \"John\", \"surname\" :\"Moe\"},\n * {\"name\": \"Jane\", \"surname\": \"Foe\"}\n * ];\n *\n * var personsByName = _.sort(persons, [_.getKey(\"name\")]);\n *\n * // personsByName holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Stable multi-sort:\n * var personsByNameAscSurnameDesc = _.sort(persons, [\n * _.getKey(\"name\"),\n * _.sorterDesc(_.getKey(\"surname\"))\n * ]);\n *\n * // personsByNameAscSurnameDesc holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Using custom comparers:\n * var localeSorter = new Intl.Collator(\"it\");\n * var chars = [\"a\", \"è\", \"à\", \"é\", \"c\", \"b\", \"e\"];\n *\n * _.sort(chars, [localeSorter]) // => [\"a\", \"à\", \"b\", \"c\", \"e\", \"é\", \"è\"]\n *\n * var localeSorterDesc = _.sorterDesc(_.identity, localeSorter.compare);\n *\n * _.sort(chars, [localeSorterDesc]) // => [\"è\", \"é\", \"e\", \"c\", \"b\", \"à\", \"a\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {ArrayLike} arrayLike\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Array}\n */\n function sort (arrayLike, sorters) {\n var criteria = _makeCriteria(sorters);\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = { value: arrayLike[i], index: i };\n }\n\n result.sort(_compareWith(criteria));\n\n for (i = 0; i < len; i++) {\n result[i] = result[i].value;\n }\n\n return result;\n }\n\n /**\n * Establishes at which index an element should be inserted in a sorted array to respect\n * the array order. Needs the comparer used to sort the array.\n * @private\n * @param {Array} array\n * @param {*} element\n * @param {Function} comparer\n * @param {Number} start\n * @param {Number} end\n * @returns {Number}\n */\n function _getInsertionIndex (array, element, comparer, start, end) {\n if (array.length === 0) {\n return 0;\n }\n\n var pivot = (start + end) >> 1;\n var result = comparer(\n { value: element, index: pivot },\n { value: array[pivot], index: pivot }\n );\n\n if (end - start <= 1) {\n return result < 0 ? pivot : pivot + 1;\n } else if (result < 0) {\n return _getInsertionIndex(array, element, comparer, start, pivot);\n } else if (result === 0) {\n return pivot + 1;\n } else {\n return _getInsertionIndex(array, element, comparer, pivot, end);\n }\n }\n\n /**\n * Inserts an element in a copy of a sorted array respecting the sort order.\n * @example With simple values:\n * _.sortedInsert([], 1) // => [1]\n * _.sortedInsert([2, 4, 6], 5) // => [2, 4, 5, 6]\n * _.sortedInsert([4, 2, 1], 3, _.sorterDesc()) // => [4, 3, 2, 1]\n *\n * @example With complex values:\n * var persons = [\n * {\"name\": \"jane\", \"surname\": \"doe\"},\n * {\"name\": \"John\", \"surname\": \"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * ];\n *\n * var getLowerCaseName = _.compose(\n * _.invoker(\"toLowerCase\"),\n * _.getKey(\"name\")\n * );\n *\n * var result = _.sortedInsert(\n * persons,\n * {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * getLowerCaseName\n * );\n *\n * // `result` holds:\n * // [\n * // {\"name\": \"jane\", \"surname\": \"doe\"},\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt} to insert the element\n * at a specific index\n * @since 0.27.0\n * @param {ArrayLike} arrayLike\n * @param {*} element\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]] - The sorting criteria\n * used to sort the array.\n * @returns {Array}\n */\n function sortedInsert (arrayLike, element, sorters) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n if (arguments.length === 1) {\n return result;\n }\n\n var criteria = _makeCriteria(sorters);\n var idx = _getInsertionIndex(result, element, _compareWith(criteria), 0, result.length);\n\n result.splice(idx, 0, element);\n\n return result;\n }\n\n /**\n * Creates an ascending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.1.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorter = partial(_sorter, [__, false, __]);\n\n /**\n * Creates a descending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}\n * @since 0.15.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorterDesc = partial(_sorter, [__, true, __]);\n\n /**\n * Builds a partial application of {@link module:lamb.sort|sort} using the provided criteria.\n * The returned function expects the array-like object to sort.\n * As usual, sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function,\n * but you can also pass simple \"reader\" functions and default ascending sorters will be built.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used in\n * the comparison.
\n * See {@link module:lamb.sort|sort} for more examples.\n *\n * @example\n * var sortAsNumbers = _.sortWith([parseFloat]);\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * sortAsNumbers(weights) // => [\"1 Kg\", \"2 Kg\", \"7 Kg\", \"10 Kg\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sort|sort}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Function}\n */\n var sortWith = _curry2(sort, true);\n\n /**\n * Returns a copy of the given array-like object without the first element.\n * @example\n * _.tail([1, 2, 3, 4]) // => [2, 3, 4]\n * _.tail([1]) // => []\n * _.tail([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.init|init}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var tail = drop(1);\n\n /**\n * Retrieves the first n elements from an array or array-like object.
\n * Note that, being this a shortcut for a common use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.takeFrom(arr, 3) // => [1, 2, 3]\n * _.takeFrom(arr, -1) // => [1, 2, 3, 4]\n * _.takeFrom(arr, -10) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function takeFrom (arrayLike, n) {\n return slice(arrayLike, 0, n);\n }\n\n /**\n * A curried version of {@link module:lamb.takeFrom|takeFrom} that expects the number of elements\n * to retrieve to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.takeFrom|takeFrom} about passing a\n * negative n.\n * @example\n * var take2 = _.take(2);\n *\n * take2([1, 2, 3, 4, 5]) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeFrom|takeFrom}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.5.0\n * @param {Number} n\n * @returns {Function}\n */\n var take = _curry2(takeFrom, true);\n\n /**\n * Builds a function that takes the first n elements satisfying a predicate from\n * an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeWhileIsEven = _.takeWhile(isEven);\n *\n * takeWhileIsEven([1, 2, 4, 6, 8]) // => []\n * takeWhileIsEven([2, 4, 7, 8]) // => [2, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n function takeWhile (predicate) {\n return function (arrayLike) {\n return slice(arrayLike, 0, _getNumConsecutiveHits(arrayLike, predicate));\n };\n }\n\n /**\n * Transposes a matrix. Can also be used to reverse a {@link module:lamb.zip|zip} operation.
\n * Just like {@link module:lamb.zip|zip}, the received array-like objects will be truncated to the\n * shortest length.\n * @example Transposing a matrix:\n * _.transpose([\n * [1, 2, 3],\n * [4, 5, 6],\n * [7, 8, 9]\n * ]) // =>\n * // [\n * // [1, 4, 7],\n * // [2, 5, 8],\n * // [3, 6, 9]\n * // ]\n *\n * @example Showing the relationship with zip:\n * var zipped = _.zip([\"a\", \"b\", \"c\"], [1, 2, 3]); // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.transpose(zipped) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function transpose (arrayLike) {\n var minLen = MAX_ARRAY_LENGTH;\n var len = _toArrayLength(arrayLike.length);\n\n if (len === 0) {\n return [];\n }\n\n for (var j = 0, elementLen; j < len; j++) {\n elementLen = _toArrayLength(arrayLike[j].length);\n\n if (elementLen < minLen) {\n minLen = elementLen;\n }\n }\n\n var result = Array(minLen);\n\n for (var i = 0, el; i < minLen; i++) {\n el = result[i] = Array(len);\n\n for (j = 0; j < len; j++) {\n el[j] = arrayLike[j][i];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a TypeError stating that it's not possible to convert the given value to the\n * desired type.\n * @private\n * @param {*} value\n * @param {String} desiredType\n * @returns {TypeError}\n */\n function _makeTypeErrorFor (value, desiredType) {\n return new TypeError(\"Cannot convert \" + type(value).toLowerCase() + \" to \" + desiredType);\n }\n\n /**\n * Creates a pipeline of functions, where each function consumes the result of the previous one.\n * @example\n * var __ = _.__;\n * var square = _.partial(Math.pow, [__, 2]);\n * var getMaxAndSquare = _.pipe([Math.max, square]);\n *\n * getMaxAndSquare(3, 5) // => 25\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.compose|compose}\n * @since 0.1.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function pipe (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n var len = functions.length;\n\n return len ? function () {\n var result = functions[0].apply(this, arguments);\n\n for (var i = 1; i < len; i++) {\n result = functions[i].call(this, result);\n }\n\n return result;\n } : identity;\n }\n\n /**\n * Using the provided iteratee to transform values, builds a function that will\n * return an array of the unique elements in the two provided array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.union|union} if you don't need to compare transformed values.\n * @example\n * var unionByFloor = _.unionBy(Math.floor);\n *\n * unionByFloor([2.8, 3.2, 1.5], [3.5, 1.2, 4]) // => [2.8, 3.2, 1.5, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.union|union}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function unionBy (iteratee) {\n return pipe([binary(list), flatMapWith(drop(0)), uniquesBy(iteratee)]);\n }\n\n /**\n * Returns a list of every unique element present in the two given array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.unionBy|unionBy} if you need to transform the values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.union([1, 2, 3, 2], [2, 3, 4]) // => [1, 2, 3, 4]\n * _.union(\"abc\", \"bcd\") // => [\"a\", \"b\", \"c\", \"d\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n var union = unionBy(identity);\n\n /**\n * Builds a function that creates a copy of an array-like object with the given index\n * changed by applying the provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateAt(1, toUpperCase)(arr) // => [\"a\", \"B\", \"c\"]\n * _.updateAt(-1, toUpperCase)(arr) // => [\"a\", \"b\", \"C\"]\n * _.updateAt(10, toUpperCase)(arr) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.updateIndex|updateIndex}\n * @since 0.22.0\n * @param {Number} index\n * @param {Function} updater\n * @returns {Function}\n */\n function updateAt (index, updater) {\n return function (arrayLike) {\n return _setIndex(arrayLike, index, null, updater);\n };\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed by applying the\n * provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIndex(arr, 1, toUpperCase) // => [\"a\", \"B\", \"c\"]\n * _.updateIndex(arr, -1, toUpperCase) // => [\"a\", \"b\", \"C\"]\n * _.updateIndex(arr, 10, toUpperCase) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.updateAt|updateAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {Function} updater\n * @returns {Array}\n */\n var updateIndex = partial(_setIndex, [__, __, null, __]);\n\n /**\n * Builds a list of arrays out of the two given array-like objects by pairing items with\n * the same index.
\n * The received array-like objects will be truncated to the shortest length.\n * @example\n * _.zip(\n * [\"a\", \"b\", \"c\"],\n * [1, 2, 3]\n * ) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.zip([1, 2, 3, 4], [5, 6, 7]) // => [[1, 5], [2, 6], [3, 7]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.transpose|transpose} for the reverse operation\n * @see {@link module:lamb.zipWithIndex|zipWithIndex}\n * @since 0.14.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n function zip (a, b) {\n return transpose([a, b]);\n }\n\n /**\n * \"{@link module:lamb.zip|Zips}\" an array-like object by pairing its values with their index.\n * @example\n * _.zipWithIndex([\"a\", \"b\", \"c\"]) // => [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array>}\n */\n var zipWithIndex = mapWith(binary(list));\n\n /**\n * Applies the given function to a list of arguments.\n * @example\n * _.application(_.sum, [3, 4]) // => 7\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.apply|apply}, {@link module:lamb.applyTo|applyTo}\n * @since 0.47.0\n * @param {Function} fn\n * @param {ArrayLike} args\n * @returns {*}\n */\n function application (fn, args) {\n return fn.apply(this, Object(args));\n }\n\n /**\n * A left-curried version of {@link module:lamb.application|application}. Expects the function\n * to apply and builds a function waiting for the arguments array.\n * @example\n * var arrayMax = _.apply(Math.max);\n *\n * arrayMax([4, 5, 2, 6, 1]) // => 6\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.applyTo|applyTo}\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n var apply = _curry2(application);\n\n /**\n * A right-curried version of {@link module:lamb.application|application}. Expects an array-like\n * object to use as arguments and builds a function waiting for the target of the application.\n * @example\n * var data = [3, 4];\n * var applyToData = _.applyTo(data);\n *\n * applyToData(_.sum) // => 7\n * applyToData(_.multiply) // => 12\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.apply|apply}\n * @since 0.47.0\n * @param {ArrayLike} args\n * @returns {Function}\n */\n var applyTo = _curry2(application, true);\n\n /**\n * Keeps building a partial application of the received function as long\n * as it's called with placeholders; applies the original function to\n * the collected parameters otherwise.
\n * The function checks only the public placeholder to gain a little performance\n * as no function in Lamb is built with {@link module:lamb.asPartial|asPartial}.\n * @private\n * @param {Function} fn\n * @param {Array} argsHolder\n * @returns {Function|*}\n */\n function _asPartial (fn, argsHolder) {\n return function () {\n var argsLen = arguments.length;\n var lastIdx = 0;\n var newArgs = [];\n\n for (var i = 0, len = argsHolder.length, boundArg; i < len; i++) {\n boundArg = argsHolder[i];\n newArgs[i] = boundArg === __ && lastIdx < argsLen ? arguments[lastIdx++] : boundArg;\n }\n\n while (lastIdx < argsLen) {\n newArgs[i++] = arguments[lastIdx++];\n }\n\n for (i = 0; i < argsLen; i++) {\n if (arguments[i] === __) {\n return _asPartial(fn, newArgs);\n }\n }\n\n for (i = 0, len = newArgs.length; i < len; i++) {\n if (newArgs[i] === __) {\n newArgs[i] = void 0;\n }\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Decorates the received function so that it can be called with\n * placeholders to build a partial application of it.
\n * The difference with {@link module:lamb.partial|partial} is that, as long as\n * you call the generated function with placeholders, another partial application\n * of the original function will be built.
\n * The final application will happen when one of the generated functions is\n * invoked without placeholders, using the parameters collected so far.
\n * This function comes in handy when you need to build different specialized\n * functions starting from a basic one, but it's also useful when dealing with\n * optional parameters as you can decide to apply the function even if its arity\n * hasn't been entirely consumed.\n * @example Explaining the function's behaviour:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + c;\n * });\n *\n * f(4, 3, 2) // => 9\n * f(4, __, 2)(3) // => 9\n * f(__, 3, __)(4, __)(2) // => 9\n *\n * @example Exploiting optional parameters:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + (c || 0);\n * });\n *\n * var addFive = f(5, __);\n * addFive(2) // => 7\n *\n * var addNine = addFive(4, __);\n * addNine(11) // => 20\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.36.0\n * @param {Function} fn\n * @returns {Function}\n */\n function asPartial (fn) {\n return _asPartial(fn, []);\n }\n\n /**\n * Accepts a series of functions and builds a new function. The functions in the series\n * will then be applied, in order, with the values received by the function built with\n * collect.
\n * The collected results will be returned in an array.\n * @example\n * var user = {\n * id: \"jdoe\",\n * name: \"John\",\n * surname: \"Doe\",\n * scores: [2, 4, 7]\n * };\n * var getIDAndLastScore = _.collect([_.getKey(\"id\"), _.getPath(\"scores.-1\")]);\n *\n * getIDAndLastScore(user) // => [\"jdoe\", 7]\n *\n * @example\n * var minAndMax = _.collect([Math.min, Math.max]);\n *\n * minAndMax(3, 1, -2, 5, 4, -1) // => [-2, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.35.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function collect (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n return map(functions, applyTo(arguments));\n };\n }\n\n /**\n * Used by curry functions to collect arguments until the arity is consumed,\n * then applies the original function.\n * @private\n * @param {Function} fn\n * @param {Number} arity\n * @param {Boolean} isRightCurry\n * @param {Boolean} isAutoCurry\n * @param {Array} argsHolder\n * @returns {Function}\n */\n function _currier (fn, arity, isRightCurry, isAutoCurry, argsHolder) {\n return function () {\n var holderLen = argsHolder.length;\n var argsLen = arguments.length;\n var newArgsLen = holderLen + (argsLen > 1 && isAutoCurry ? argsLen : 1);\n var newArgs = Array(newArgsLen);\n\n for (var i = 0; i < holderLen; i++) {\n newArgs[i] = argsHolder[i];\n }\n\n for (; i < newArgsLen; i++) {\n newArgs[i] = arguments[i - holderLen];\n }\n\n if (newArgsLen >= arity) {\n return fn.apply(this, isRightCurry ? newArgs.reverse() : newArgs);\n } else {\n return _currier(fn, arity, isRightCurry, isAutoCurry, newArgs);\n }\n };\n }\n\n /**\n * Curries a function of arity 3.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry3 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return function (c) {\n return isRightCurry ? fn.call(this, c, b, a) : fn.call(this, a, b, c);\n };\n };\n };\n }\n\n /**\n * Prepares a function for currying. If it's not auto-currying and the arity\n * is 2 or 3 returns optimized functions, otherwise delegates the currying\n * to the _currier function.
\n * If the desumed arity isn't greater than one, it will return the received\n * function itself, instead.\n * @private\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @param {Boolean} [isRightCurry=false]\n * @param {Boolean} [isAutoCurry=false]\n * @returns {Function}\n */\n function _curry (fn, arity, isRightCurry, isAutoCurry) {\n if (arity >>> 0 !== arity) {\n arity = fn.length;\n }\n\n if (isAutoCurry && arity > 1 || arity > 3) {\n return _currier(fn, arity, isRightCurry, isAutoCurry, []);\n } else if (arity === 2) {\n return _curry2(fn, isRightCurry);\n } else if (arity === 3) {\n return _curry3(fn, isRightCurry);\n } else {\n return fn;\n }\n }\n\n /**\n * Transforms the evaluation of the given function in the evaluation of a sequence of functions\n * expecting only one argument. Each function of the sequence is a partial application of the\n * original one, which will be applied when the specified (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryRight|curryRight}\n * for right currying.\n * @example\n * var makeWithKeys = _.curry(_.make);\n * var makePerson = makeWithKeys([\"name\", \"surname\"]);\n *\n * makePerson([\"John\", \"Doe\"]) // => {name: \"John\", surname: \"Doe\"};\n * makePerson([\"Mario\", \"Rossi\"]) // => {name: \"Mario\", surname: \"Rossi\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curry (fn, arity) {\n return _curry(fn, arity, false);\n }\n\n /**\n * Builds an auto-curried function. The resulting function can be called multiple times with\n * any number of arguments, and the original function will be applied only when the specified\n * (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryableRight|curryableRight}\n * for right currying.\n * @example\n * var collectFourElements = _.curryable(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2)(3, 4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3, 4, 5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3)(4, 5) // => [2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.6.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryable (fn, arity) {\n return _curry(fn, arity, false, true);\n }\n\n /**\n * Same as {@link module:lamb.curryable|curryable}, but currying starts from the rightmost argument.\n * @example\n * var collectFourElements = _.curryableRight(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2)(3, 4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3, 4, 5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3)(4, 5) // => [5, 4, 3, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryable|curryable}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryableRight (fn, arity) {\n return _curry(fn, arity, true, true);\n }\n\n /**\n * Same as {@link module:lamb.curry|curry}, but currying starts from the rightmost argument.\n * @example\n * var makeWithValues = _.curryRight(_.make);\n * var makeJohnDoe = makeWithValues([\"John\", \"Doe\"]);\n *\n * makeJohnDoe([\"name\", \"surname\"]) // => {name: \"John\", surname: \"Doe\"};\n * makeJohnDoe([\"firstName\", \"lastName\"]) // => {firstName: \"John\", lastName: \"Doe\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curry|curry}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryRight (fn, arity) {\n return _curry(fn, arity, true);\n }\n\n /**\n * Returns a function that will execute the given function only if it stops being called for the\n * specified timespan.
\n * See also {@link module:lamb.throttle|throttle} for a different behaviour where the first call\n * happens immediately.\n * @example A common use case of debounce in a browser environment:\n * var updateLayout = function () {\n * // some heavy DOM operations here\n * };\n *\n * window.addEventListener(\"resize\", _.debounce(updateLayout, 200), false);\n *\n * // The resize event is fired repeteadly until the user stops resizing the\n * // window, while the `updateLayout` function is called only once: 200 ms\n * // after he stopped.\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.throttle|throttle}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds\n * @returns {Function}\n */\n function debounce (fn, timespan) {\n var timeoutID;\n\n return function () {\n var args = arguments;\n var debounced = function () {\n timeoutID = null;\n fn.apply(this, args);\n }.bind(this);\n\n clearTimeout(timeoutID);\n timeoutID = setTimeout(debounced, timespan);\n };\n }\n\n /**\n * Returns a function that applies the original function with the arguments in reverse order.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n * _.flip(_.list)(1, 2, 3) // => [3, 2, 1]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n function flip (fn) {\n return function () {\n var args = list.apply(null, arguments).reverse();\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Builds a function that returns the argument received at the given index.
\n * As with {@link module:lamb.getAt|getAt} negative indexes are allowed.
\n * The resulting function will return undefined if no arguments are\n * passed or if the index is out of bounds.\n * @example\n * var getFirstArg = _.getArgAt(0);\n * var getLastArg = _.getArgAt(-1);\n *\n * getFirstArg(1, 2, 3) // => 1\n * getLastArg(1, 2, 3) // => 3\n *\n * _.getArgAt()(1, 2, 3) // => undefined\n * _.getArgAt(6)(1, 2, 3) // => undefined\n * _.getArgAt(1)() // => undefined\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.17.0\n * @param {Number} idx\n * @returns {Function}\n */\n function getArgAt (idx) {\n return function () {\n return arguments[_toNaturalIndex(idx, arguments.length)];\n };\n }\n\n /**\n * Builds an array with the received arguments excluding the first one.
\n * To be used with the arguments object, which needs to be passed to the apply\n * method of this function.\n * @private\n * @function\n * @param {...*} value\n * @returns {Array}\n */\n var _argsTail = _argsToArrayFrom(1);\n\n /**\n * If a method with the given name exists on the target, applies it to the provided\n * arguments and returns the result. Returns undefined otherwise.
\n * The arguments for the method are built by concatenating the array of bound arguments,\n * optionally received by {@link module:lamb.invoker|invoker}, with the final set of, also\n * optional, args.\n * @private\n * @param {Array} boundArgs\n * @param {String} methodName\n * @param {Object} target\n * @param {...*} [args]\n * @returns {*}\n */\n function _invoker (boundArgs, methodName, target) {\n var method = target[methodName];\n\n if (typeof method !== \"function\") {\n return void 0;\n }\n\n var boundArgsLen = boundArgs.length;\n var ofs = 3 - boundArgsLen;\n var len = arguments.length - ofs;\n var args = Array(len);\n\n for (var i = 0; i < boundArgsLen; i++) {\n args[i] = boundArgs[i];\n }\n\n for (; i < len; i++) {\n args[i] = arguments[i + ofs];\n }\n\n return method.apply(target, args);\n }\n\n /**\n * Builds a function that will invoke the given method name on any received object and\n * return the result. If no method with such name is found the function will return\n * undefined.
\n * Along with the method name it's possible to supply some arguments that will be bound to the\n * method call. Further arguments can also be passed when the function is actually called, and\n * they will be concatenated to the bound ones.
\n * Returning undefined is a behaviour meant to quickly create a case for\n * {@link module:lamb.adapter|adapter} without the need to check for the existence of the\n * desired method.
\n * See also {@link module:lamb.generic|generic} to create functions out of object methods.\n * @example Basic polymorphism with invoker:\n * var polySlice = _.invoker(\"slice\");\n *\n * polySlice([1, 2, 3, 4, 5], 1, 3) // => [2, 3]\n * polySlice(\"Hello world\", 1, 3) // => \"el\"\n *\n * @example With bound arguments:\n * var substrFrom2 = _.invoker(\"substr\", 2);\n * substrFrom2(\"Hello world\") // => \"llo world\"\n * substrFrom2(\"Hello world\", 5) // => \"llo w\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invokerOn|invokerOn}\n * @since 0.1.0\n * @param {String} methodName\n * @param {...*} [boundArg]\n * @returns {Function}\n */\n function invoker (methodName) {\n return partial(_invoker, [_argsTail.apply(null, arguments), methodName]);\n }\n\n /**\n * Accepts an object and builds a function expecting a method name, and optionally arguments,\n * to call on such object.\n * Like {@link module:lamb.invoker|invoker}, if no method with the given name is found the\n * function will return undefined.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var arr = [1, 2, 3, 4, 5];\n * var invokerOnArr = _.invokerOn(arr);\n *\n * invokerOnArr(\"filter\", isEven) // => [2, 4]\n * invokerOnArr(\"slice\", 1, 3) // => [2, 3]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.15.0\n * @param {Object} target\n * @returns {Function}\n */\n function invokerOn (target) {\n return partial(_invoker, [[], __, target]);\n }\n\n /**\n * Builds a function that allows to map over the received arguments before applying them\n * to the original one.\n * @example\n * var __ = _.__;\n * var sumArray = _.reduceWith(_.sum);\n * var sumArgs = _.compose(sumArray, _.list);\n *\n * sumArgs(1, 2, 3, 4, 5) // => 15\n *\n * var square = _.partial(Math.pow, [__, 2]);\n * var sumSquares = _.mapArgs(sumArgs, square);\n *\n * sumSquares(1, 2, 3, 4, 5) // => 55\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.tapArgs|tapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {ListIteratorCallback} mapper\n * @returns {Function}\n */\n function mapArgs (fn, mapper) {\n return pipe([list, mapWith(mapper), apply(fn)]);\n }\n\n /**\n * Builds a function that allows to \"tap\" into the arguments of the original one.\n * This allows to extract simple values from complex ones, transform arguments or simply intercept them.\n * If a \"tapper\" isn't found the argument is passed as it is.\n * @example\n * var someObject = {count: 5};\n * var someArrayData = [2, 3, 123, 5, 6, 7, 54, 65, 76, 0];\n * var getDataAmount = _.tapArgs(_.sum, [_.getKey(\"count\"), _.getKey(\"length\")]);\n *\n * getDataAmount(someObject, someArrayData); // => 15\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.mapArgs|mapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {Function[]} tappers\n * @returns {Function}\n */\n function tapArgs (fn, tappers) {\n return function () {\n var len = arguments.length;\n var tappersLen = tappers.length;\n var args = [];\n\n for (var i = 0; i < len; i++) {\n args.push(i < tappersLen ? tappers[i](arguments[i]) : arguments[i]);\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Returns a function that will invoke the passed function at most once in the given timespan.
\n * The first call in this case happens as soon as the function is invoked; see also\n * {@link module:lamb.debounce|debounce} for a different behaviour where the first call is delayed.\n * @example\n * var log = _.throttle(console.log.bind(console), 5000);\n *\n * log(\"Hi\"); // console logs \"Hi\"\n * log(\"Hi again\"); // nothing happens\n * // after five seconds\n * log(\"Hello world\"); // console logs \"Hello world\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.debounce|debounce}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds.\n * @returns {Function}\n */\n function throttle (fn, timespan) {\n var result;\n var lastCall = 0;\n\n return function () {\n var now = Date.now();\n\n if (now - lastCall >= timespan) {\n lastCall = now;\n result = fn.apply(this, arguments);\n }\n\n return result;\n };\n }\n\n /**\n * Builds a function that passes only one argument to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * _.map(weights, _.unary(parseInt)) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.binary|binary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function unary (fn) {\n return function (a) {\n return fn.call(this, a);\n };\n }\n\n /**\n * Accepts a series of functions and builds a function that applies the received\n * arguments to each one and returns the first non-undefined value.
\n * Meant to work in synergy with {@link module:lamb.case|case} and\n * {@link module:lamb.invoker|invoker}, can be useful as a strategy pattern for functions,\n * to mimic conditional logic or pattern matching, and also to build polymorphic functions.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var filterString = _.compose(_.invoker(\"join\", \"\"), _.filter);\n * var filterAdapter = _.adapter([\n * _.invoker(\"filter\"),\n * _.case(_.isType(\"String\"), filterString)\n * ]);\n *\n * filterAdapter([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterAdapter(\"123456\", isEven) // => \"246\"\n * filterAdapter({}, isEven) // => undefined\n *\n * // by its nature is composable\n * var filterWithDefault = _.adapter([filterAdapter, _.always(\"Not implemented\")]);\n *\n * filterWithDefault([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterWithDefault(\"123456\", isEven) // => \"246\"\n * filterWithDefault({}, isEven) // => \"Not implemented\"\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.case|case}\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.6.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function adapter (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n var len = functions.length;\n var result;\n\n for (var i = 0; i < len; i++) {\n result = functions[i].apply(this, arguments);\n\n if (!isUndefined(result)) {\n break;\n }\n }\n\n return result;\n };\n }\n\n /**\n * Creates a function to check the given predicates.
\n * Used to build the {@link module:lamb.allOf|allOf} and the\n * {@link module:lamb.anyOf|anyOf} functions.\n * @private\n * @param {Boolean} checkAll\n * @returns {Function}\n */\n function _checkPredicates (checkAll) {\n return function (predicates) {\n if (!Array.isArray(predicates)) {\n throw _makeTypeErrorFor(predicates, \"array\");\n }\n\n return function () {\n for (var i = 0, len = predicates.length, result; i < len; i++) {\n result = predicates[i].apply(this, arguments);\n\n if (checkAll && !result) {\n return false;\n } else if (!checkAll && result) {\n return true;\n }\n }\n\n return checkAll;\n };\n };\n }\n\n /**\n * Accepts an array of predicates and builds a new one that returns true if they are all satisfied\n * by the same arguments. The functions in the array will be applied one at a time until a\n * false value is produced, which is returned immediately.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isPositiveEven = _.allOf([isEven, _.isGT(0)]);\n *\n * isPositiveEven(-2) // => false\n * isPositiveEven(11) // => false\n * isPositiveEven(6) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.anyOf|anyOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\n var allOf = _checkPredicates(true);\n\n /**\n * Accepts an array of predicates and builds a new one that returns true if at least one of them is\n * satisfied by the received arguments. The functions in the array will be applied one at a time\n * until a true value is produced, which is returned immediately.\n * @example\n * var users = [\n * {id: 1, name: \"John\", group: \"guest\"},\n * {id: 2, name: \"Jane\", group: \"root\"},\n * {id: 3, name: \"Mario\", group: \"admin\"}\n * ];\n * var isInGroup = _.partial(_.hasKeyValue, [\"group\"]);\n * var isSuperUser = _.anyOf([isInGroup(\"admin\"), isInGroup(\"root\")]);\n *\n * isSuperUser(users[0]) // => false\n * isSuperUser(users[1]) // => true\n * isSuperUser(users[2]) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.allOf|allOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\n var anyOf = _checkPredicates(false);\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValue\" comparison.
\n * Note that this doesn't behave as the strict equality operator, but rather as a shim of ES6's\n * [Object.is]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is}.\n * Differences are that 0 and -0 aren't the same value and, finally,\n * NaN is equal to itself.
\n * See also {@link module:lamb.is|is} for a curried version building a predicate and\n * {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ} to perform a \"SameValueZero\"\n * comparison.\n * @example\n * var testObject = {};\n *\n * _.areSame({}, testObject) // => false\n * _.areSame(testObject, testObject) // => true\n * _.areSame(\"foo\", \"foo\") // => true\n * _.areSame(0, -0) // => false\n * _.areSame(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.is|is}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSame (a, b) {\n return a === 0 && b === 0 ? 1 / a === 1 / b : areSVZ(a, b);\n }\n\n /**\n * Builds a case for {@link module:lamb.adapter|adapter}.
\n * The function will apply the received arguments to fn if the predicate is satisfied\n * with the same arguments, otherwise will return undefined.
\n * See also {@link module:lamb.condition|condition} to build a condition with two branching functions\n * and {@link module:lamb.unless|unless} and {@link module:lamb.when|when} where one of the branches\n * is the identity function.\n * @example\n * var halveIfNumber = _.case(_.isType(\"Number\"), _.divideBy(2));\n *\n * halveIfNumber(2) // => 1\n * halveIfNumber(\"2\") // => undefined\n *\n * @alias module:lamb.case\n * @category Logic\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @since 0.51.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function case_ (predicate, fn) {\n return function () {\n return predicate.apply(this, arguments) ? fn.apply(this, arguments) : void 0;\n };\n }\n\n /**\n * Builds a function that will apply the received arguments to trueFn,\n * if the predicate is satisfied with the same arguments, or to falseFn otherwise.
\n * Although you can use other conditions as trueFn or falseFn,\n * it's probably better to use {@link module:lamb.adapter|adapter} to build more complex behaviours.
\n * See also {@link module:lamb.unless|unless} and {@link module:lamb.when|when} as they are\n * shortcuts to common use cases.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveEvenAndDoubleOdd = _.condition(isEven, _.divideBy(2), _.multiplyBy(2));\n *\n * halveEvenAndDoubleOdd(5) // => 10\n * halveEvenAndDoubleOdd(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.2.0\n * @param {Function} predicate\n * @param {Function} trueFn\n * @param {Function} falseFn\n * @returns {Function}\n */\n function condition (predicate, trueFn, falseFn) {\n return function () {\n return (predicate.apply(this, arguments) ? trueFn : falseFn).apply(this, arguments);\n };\n }\n\n /**\n * Verifies that the first given value is greater than the second.
\n * Wraps the native > operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.gt(today, pastDate) // => true\n * _.gt(pastDate, today) // => false\n * _.gt(3, 4) // => false\n * _.gt(3, 3) // => false\n * _.gt(3, 2) // => true\n * _.gt(0, -0) // => false\n * _.gt(-0, 0) // => false\n * _.gt(\"a\", \"A\") // => true\n * _.gt(\"b\", \"a\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gt (a, b) {\n return a > b;\n }\n\n /**\n * Verifies that the first given value is greater than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * >= operator, so -0 === 0.\n * @example\n * _.gte(3, 4) // => false\n * _.gte(3, 3) // => true\n * _.gte(3, 2) // => true\n * _.gte(0, -0) // => true\n * _.gte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gt|gt}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gte (a, b) {\n return a >= b;\n }\n\n /**\n * A curried version of {@link module:lamb.areSame|areSame}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValue\"\n * comparison.
\n * See also {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ}\n * to perform a \"SameValueZero\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.is(john);\n * var isNegativeZero = _.is(-0);\n * var isReallyNaN = _.is(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isNegativeZero(0) // => false\n * isNegativeZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSame|areSame}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var is = _curry2(areSame);\n\n /**\n * A right curried version of {@link module:lamb.gt|gt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than the one received by the predicate.\n * @example\n * var isGreaterThan5 = _.isGT(5);\n *\n * isGreaterThan5(3) // => false\n * isGreaterThan5(5) // => false\n * isGreaterThan5(7) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGT = _curry2(gt, true);\n\n /**\n * A right curried version of {@link module:lamb.gte|gte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than or equal to the one received by the predicate.\n * @example\n * var isPositiveOrZero = _.isGTE(0);\n *\n * isPositiveOrZero(-3) // => false\n * isPositiveOrZero(-0) // => true\n * isPositiveOrZero(0) // => true\n * isPositiveOrZero(5) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGT|isGT}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGTE = _curry2(gte, true);\n\n /**\n * Verifies that the first given value is less than the second.
\n * Wraps the native < operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.lt(today, pastDate) // => false\n * _.lt(pastDate, today) // => true\n * _.lt(3, 4) // => true\n * _.lt(3, 3) // => false\n * _.lt(3, 2) // => false\n * _.lt(0, -0) // => false\n * _.lt(-0, 0) // => false\n * _.lt(\"a\", \"A\") // => false\n * _.lt(\"a\", \"b\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lt (a, b) {\n return a < b;\n }\n\n /**\n * A right curried version of {@link module:lamb.lt|lt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than the one received by the predicate.\n * @example\n * var isLessThan5 = _.isLT(5);\n *\n * isLessThan5(7) // => false\n * isLessThan5(5) // => false\n * isLessThan5(3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLT = _curry2(lt, true);\n\n /**\n * Verifies that the first given value is less than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * <= operator, so -0 === 0.\n * @example\n * _.lte(3, 4) // => true\n * _.lte(3, 3) // => true\n * _.lte(3, 2) // => false\n * _.lte(0, -0) // => true\n * _.lte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lt|lt}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lte (a, b) {\n return a <= b;\n }\n\n /**\n * A right curried version of {@link module:lamb.lte|lte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than or equal to the one received by the predicate.\n * @example\n * var isNegativeOrZero = _.isLTE(0);\n *\n * isNegativeOrZero(5) // => false\n * isNegativeOrZero(-0) // => true\n * isNegativeOrZero(0) // => true\n * isNegativeOrZero(-3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLT|isLT}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLTE = _curry2(lte, true);\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate isn't satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.when|when} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its trueFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveUnlessIsEven = _.unless(isEven, _.divideBy(2));\n *\n * halveUnlessIsEven(5) // => 2.5\n * halveUnlessIsEven(6) // => 6\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function unless (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? value : fn.call(this, value);\n };\n }\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate is satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.unless|unless} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its falseFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var halveIfEven = _.when(isEven, _.divideBy(2));\n *\n * halveIfEven(5) // => 5\n * halveIfEven(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function when (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? fn.call(this, value) : value;\n };\n }\n\n /**\n * Sums two numbers.\n * @example\n * _.sum(4, 5) // => 9\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.add|add}\n * @since 0.50.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function sum (a, b) {\n return a + b;\n }\n\n /**\n * A curried version of {@link module:lamb.sum|sum}.\n * @example\n * var add5 = _.add(5);\n *\n * _.add5(4) // => 9\n * _.add5(-2) // => 3\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.sum|sum}\n * @since 0.1.0\n * @param {Number} a\n * @returns {Function}\n */\n var add = _curry2(sum, true);\n\n /**\n * Subtracts two numbers.\n * @example\n * _.subtract(5, 3) // => 2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.deduct|deduct}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function subtract (a, b) {\n return a - b;\n }\n\n /**\n * A curried version of {@link module:lamb.subtract|subtract} that expects the\n * subtrahend to build a function waiting for the minuend.\n * @example\n * var deduct5 = _.deduct(5);\n *\n * deduct5(12) // => 7\n * deduct5(3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.subtract|subtract}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var deduct = _curry2(subtract, true);\n\n /**\n * Divides two numbers.\n * @example\n * _.divide(5, 2) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.divideBy|divideBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function divide (a, b) {\n return a / b;\n }\n\n /**\n * A curried version of {@link module:lamb.divide|divide} that expects a divisor to\n * build a function waiting for the dividend.\n * @example\n * var halve = divideBy(2);\n *\n * halve(10) // => 5\n * halve(5) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.divide|divide}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var divideBy = _curry2(divide, true);\n\n /**\n * Generates a sequence of values of the desired length with the provided iteratee.\n * The values being iterated, and received by the iteratee, are the results generated so far.\n * @example\n * var fibonacci = function (n, idx, results) {\n * return n + (results[idx - 1] || 0);\n * };\n *\n * _.generate(1, 10, fibonacci) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.range|range}\n * @since 0.21.0\n * @param {*} start - The starting value\n * @param {Number} len - The desired length for the sequence\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function generate (start, len, iteratee) {\n var result = [start];\n\n for (var i = 0, limit = len - 1; i < limit; i++) {\n result.push(iteratee(result[i], i, result));\n }\n\n return result;\n }\n\n /**\n * Verifies whether the received value is a finite number.
\n * Behaves almost as a shim of ES6's [Number.isFinite]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isFinite(5) // => true\n * _.isFinite(new Number(5)) // => true\n * _.isFinite(Infinity) // => false\n * _.isFinite(-Infinity) // => false\n * _.isFinite(\"5\") // => false\n * _.isFinite(NaN) // => false\n * _.isFinite(null) // => false\n *\n * @alias module:lamb.isFinite\n * @category Math\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isFinite_ (value) {\n return type(value) === \"Number\" && isFinite(value);\n }\n\n /**\n * Verifies whether the received value is a number and an integer.\n * Behaves almost as a shim of ES6's [Number.isInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isInteger(5) // => true\n * _.isInteger(new Number(5)) // => true\n * _.isInteger(2.5) // => false\n * _.isInteger(Infinity) // => false\n * _.isInteger(-Infinity) // => false\n * _.isInteger(\"5\") // => false\n * _.isInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isSafeInteger|isSafeInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isInteger (value) {\n return type(value) === \"Number\" && value % 1 === 0;\n }\n\n /**\n * Verifies whether the received value is a \"safe integer\", meaning that is a number and that\n * can be exactly represented as an IEEE-754 double precision number.\n * The safe integers consist of all integers from -(253 - 1) inclusive to\n * 253 - 1 inclusive.
\n * Behaves almost as a shim of ES6's [Number.isSafeInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isSafeInteger(5) // => true\n * _.isSafeInteger(new Number(5)) // => true\n * _.isSafeInteger(Math.pow(2, 53) - 1) // => true\n * _.isSafeInteger(Math.pow(2, 53)) // => false\n * _.isSafeInteger(2e32) // => false\n * _.isSafeInteger(2.5) // => false\n * _.isSafeInteger(Infinity) // => false\n * _.isSafeInteger(-Infinity) // => false\n * _.isSafeInteger(\"5\") // => false\n * _.isSafeInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isInteger|isInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isSafeInteger (value) {\n return isInteger(value) && Math.abs(value) <= MAX_SAFE_INTEGER;\n }\n\n /**\n * Performs the modulo operation and should not be confused with the\n * {@link module:lamb.remainder|remainder}.\n * The function performs a floored division to calculate the result and not\n * a truncated one, hence the sign of the dividend is not kept, unlike the\n * {@link module:lamb.remainder|remainder}.\n * @example\n * _.modulo(5, 3) // => 2\n * _.remainder(5, 3) // => 2\n *\n * _.modulo(-5, 3) // => 1\n * _.remainder(-5, 3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.remainder|remainder}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function modulo (a, b) {\n return a - (b * Math.floor(a / b));\n }\n\n /**\n * Multiplies two numbers.\n * @example\n * _.multiply(5, 3) // => 15\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.multiplyBy|multiplyBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function multiply (a, b) {\n return a * b;\n }\n\n /**\n * A curried version of {@link module:lamb.multiply|multiply}.\n * @example\n * var double = _.multiplyBy(2);\n *\n * double(5) // => 10\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.multiply|multiply}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var multiplyBy = _curry2(multiply, true);\n\n /**\n * Generates a random integer between two given integers, both included.\n * Note that no safety measure is taken if the provided arguments aren't integers, so\n * you may end up with unexpected (not really) results.\n * For example randomInt(0.1, 1.2) could be 2.\n * @example\n *\n * _.randomInt(1, 10) // => an integer >=1 && <= 10\n *\n * @memberof module:lamb\n * @category Math\n * @since 0.1.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function randomInt (min, max) {\n return Math.floor(Math.random() * (max - min + 1) + min);\n }\n\n /**\n * Converts a value to a number and returns it if it's not NaN, otherwise\n * returns zero.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _forceToNumber (value) {\n var n = +value;\n\n return n === n ? n : 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * Generates an arithmetic progression of numbers starting from start up to,\n * but not including, limit, using the given step.\n * @example\n * _.range(2, 10) // => [2, 3, 4, 5, 6, 7, 8, 9]\n * _.range(1, -10, -2) // => [1, -1, -3, -5, -7, -9]\n * _.range(0, 3, 1) // => [0, 1, 2]\n * _.range(-0, 3, 1) // => [-0, 1, 2]\n * _.range(1, -10, 2) // => []\n * _.range(3, 5, -1) // => []\n *\n * @example Behaviour if step happens to be zero:\n * _.range(2, 10, 0) // => [2]\n * _.range(2, -10, 0) // => [2]\n * _.range(2, 2, 0) // => []\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.generate|generate}\n * @since 0.1.0\n * @param {Number} start\n * @param {Number} limit\n * @param {Number} [step=1]\n * @returns {Number[]}\n */\n function range (start, limit, step) {\n start = _forceToNumber(start);\n limit = _forceToNumber(limit);\n step = arguments.length === 3 ? _forceToNumber(step) : 1;\n\n if (step === 0) {\n return limit === start ? [] : [start];\n }\n\n var len = Math.max(Math.ceil((limit - start) / step), 0);\n var result = Array(len);\n\n for (var i = 0, last = start; i < len; i++) {\n result[i] = last;\n last += step;\n }\n\n return result;\n }\n\n /**\n * Gets the remainder of the division of two numbers.\n * Not to be confused with the {@link module:lamb.modulo|modulo} as the remainder\n * keeps the sign of the dividend and may lead to some unexpected results.\n * @example\n * // example of wrong usage of the remainder\n * // (in this case the modulo operation should be used)\n * var isOdd = function (n) { return _.remainder(n, 2) === 1; };\n * isOdd(-3) // => false as -3 % 2 === -1\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.modulo|modulo}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function remainder (a, b) {\n return a % b;\n }\n\n /**\n * Checks whether the specified key is a own enumerable property of the given object or not.\n * @private\n * @function\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var _isOwnEnumerable = generic(Object.prototype.propertyIsEnumerable);\n\n /**\n * Builds a list of the enumerable properties of an object.\n * The function is null-safe, unlike the public one.\n * @private\n * @param {Object} obj\n * @returns {String[]}\n */\n function _safeEnumerables (obj) {\n var result = [];\n\n for (var key in obj) {\n result.push(key);\n }\n\n return result;\n }\n\n /**\n * Checks whether the specified key is an enumerable property of the given object or not.\n * @private\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function _isEnumerable (obj, key) {\n return key in Object(obj) && (_isOwnEnumerable(obj, key) || ~_safeEnumerables(obj).indexOf(key));\n }\n\n /**\n * Helper to retrieve the correct key while evaluating a path.\n * @private\n * @param {Object} target\n * @param {String} key\n * @param {Boolean} includeNonEnumerables\n * @returns {String|Number|Undefined}\n */\n function _getPathKey (target, key, includeNonEnumerables) {\n if (includeNonEnumerables && key in Object(target) || _isEnumerable(target, key)) {\n return key;\n }\n\n var n = +key;\n var len = target && target.length;\n\n return n >= -len && n < len ? n < 0 ? n + len : n : void 0;\n }\n\n /**\n * Checks if a path is valid in the given object and retrieves the path target.\n * @private\n * @param {Object} obj\n * @param {String[]} parts\n * @param {Boolean} walkNonEnumerables\n * @returns {Object}\n */\n function _getPathInfo (obj, parts, walkNonEnumerables) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n var target = obj;\n var i = -1;\n var len = parts.length;\n var key;\n\n while (++i < len) {\n key = _getPathKey(target, parts[i], walkNonEnumerables);\n\n if (isUndefined(key)) {\n break;\n }\n\n target = target[key];\n }\n\n return i === len ? { isValid: true, target: target } : { isValid: false, target: void 0 };\n }\n\n /**\n * Splits a sting path using the provided separator and returns an array\n * of path parts.\n * @private\n * @param {String} path\n * @param {String} separator\n * @returns {String[]}\n */\n function _toPathParts (path, separator) {\n return String(path).split(separator || \".\");\n }\n\n /**\n * Gets a nested property value from an object using the given path.
\n * The path is a string with property names separated by dots by default, but\n * it can be customised with the optional third parameter.
\n * You can use integers in the path, even negative ones, to refer to array-like\n * object indexes, but the priority will be given to existing object keys:\n * the last example explains this particular case.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * },\n * scores: [\n * {id: 1, value: 10},\n * {id: 2, value: 20},\n * {id: 3, value: 30}\n * ]\n * };\n *\n * _.getPathIn(user, \"name\") // => \"John\"\n * _.getPathIn(user, \"login.password\") // => \"abc123\";\n * _.getPathIn(user, \"login/user.name\", \"/\") // => \"jdoe\"\n * _.getPathIn(user, \"name.foo\") // => undefined\n * _.getPathIn(user, \"name.foo.bar\") // => undefined\n *\n * @example Accessing array-like objects indexes:\n * _.getPathIn(user, \"login.password.1\") // => \"b\"\n * _.getPathIn(user, \"scores.0\") // => {id: 1, value: 10}\n * _.getPathIn(user, \"scores.-1.value\") // => 30\n *\n * @example Priority will be given to existing object keys over indexes:\n * _.getPathIn(user, \"scores.-1\") // => {id: 3, value: 30}\n *\n * // let's do something funny\n * user.scores[\"-1\"] = \"foo bar\";\n *\n * _.getPathIn(user, \"scores.-1\") // => \"foo bar\";\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getPath|getPath}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {Object|ArrayLike} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {*}\n */\n function getPathIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).target;\n }\n\n /**\n * Builds a checker function meant to be used with\n * {@link module:lamb.validate|validate}.
\n * Note that the function accepts multiple keyPaths as a means to\n * compare their values. In other words all the received keyPaths will be\n * passed as arguments to the predicate to run the test.
\n * If you want to run the same single property check with multiple properties, you should build\n * multiple checkers and combine them with {@link module:lamb.validate|validate}.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\",\n * passwordConfirm: \"abc123\"\n * }\n * };\n * var pwdMatch = _.checker(\n * _.areSame,\n * \"Passwords don't match\",\n * [\"login.password\", \"login.passwordConfirm\"]\n * );\n *\n * pwdMatch(user) // => []\n *\n * var newUser = _.setPathIn(user, \"login.passwordConfirm\", \"avc123\");\n *\n * pwdMatch(newUser) // => [\"Passwords don't match\", [\"login.password\", \"login.passwordConfirm\"]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validate|validate}, {@link module:lamb.validateWith|validateWith}\n * @since 0.1.0\n * @param {Function} predicate - The predicate to test the object properties\n * @param {String} message - The error message\n * @param {String[]} keyPaths - The array of keys, or {@link module:lamb.getPathIn|paths}, to test.\n * @param {String} [pathSeparator=\".\"]\n * @returns {Function} A checker function which returns an error in the form\n * [\"message\", [\"propertyA\", \"propertyB\"]] or an empty array.\n */\n function checker (predicate, message, keyPaths, pathSeparator) {\n return function (obj) {\n var getValues = partial(getPathIn, [obj, __, pathSeparator]);\n\n return predicate.apply(obj, map(keyPaths, getValues)) ? [] : [message, keyPaths];\n };\n }\n\n /**\n * Creates a non-null-safe version of the provided \"getKeys\" function.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _unsafeKeyListFrom = _curry2(function (getKeys, obj) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n return getKeys(obj);\n });\n\n /**\n * Creates an array with all the enumerable properties of the given object.\n * @example Showing the difference with {@link module:lamb.keys|keys}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.keys(foo) // => [\"d\"]\n * _.enumerables(foo) // => [\"d\", \"a\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.keys|keys}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {String[]}\n */\n var enumerables = _unsafeKeyListFrom(_safeEnumerables);\n\n /**\n * Builds an object from a list of key / value pairs like the one\n * returned by {@link module:lamb.pairs|pairs} or {@link module:lamb.ownPairs|ownPairs}.
\n * In case of duplicate keys the last key / value pair is used.\n * @example\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"c\", 3]]) // => {\"a\": 1, \"b\": 2, \"c\": 3}\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"a\", 3]]) // => {\"a\": 3, \"b\": 2}\n * _.fromPairs([[1], [void 0, 2], [null, 3]]) // => {\"1\": undefined, \"undefined\": 2, \"null\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.ownPairs|ownPairs}, {@link module:lamb.pairs|pairs}\n * @since 0.8.0\n * @param {Array>} pairsList\n * @returns {Object}\n */\n function fromPairs (pairsList) {\n var result = {};\n\n forEach(pairsList, function (pair) {\n result[pair[0]] = pair[1];\n });\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.getPathIn|getPathIn} with the given\n * path and separator, expecting the object to act upon.
\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * }\n * };\n *\n * var getPwd = _.getPath(\"login.password\");\n * var getUsername = _.getPath(\"login/user.name\", \"/\");\n *\n * getPwd(user) // => \"abc123\";\n * getUsername(user) // => \"jdoe\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getPathIn|getPathIn}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var getPath = _makePartial3(getPathIn);\n\n /**\n * Verifies the existence of a property in an object.\n * @example\n * var user1 = {name: \"john\"};\n *\n * _.has(user1, \"name\") // => true\n * _.has(user1, \"surname\") // => false\n * _.has(user1, \"toString\") // => true\n *\n * var user2 = Object.create(null);\n *\n * // not inherited through the prototype chain\n * _.has(user2, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function has (obj, key) {\n if (typeof obj !== \"object\" && !isUndefined(obj)) {\n obj = Object(obj);\n }\n\n return key in obj;\n }\n\n /**\n * Curried version of {@link module:lamb.has|has}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {};\n * var hasName = _.hasKey(\"name\");\n *\n * hasName(user1) // => true\n * hasName(user2) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.has|has}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasKey = _curry2(has, true);\n\n /**\n * Verifies if an object has the specified property and that the property isn't inherited through\n * the prototype chain.
\n * @example Comparison with has:\n * var user = {name: \"john\"};\n *\n * _.has(user, \"name\") // => true\n * _.has(user, \"surname\") // => false\n * _.has(user, \"toString\") // => true\n *\n * _.hasOwn(user, \"name\") // => true\n * _.hasOwn(user, \"surname\") // => false\n * _.hasOwn(user, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var hasOwn = generic(Object.prototype.hasOwnProperty);\n\n /**\n * Curried version of {@link module:lamb.hasOwn|hasOwn}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user = {name: \"john\"};\n * var hasOwnName = _.hasOwnKey(\"name\");\n * var hasOwnToString = _.hasOwnToString(\"toString\");\n *\n * hasOwnName(user) // => true\n * hasOwnToString(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwn|hasOwn}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasOwnKey = _curry2(hasOwn, true);\n\n /**\n * Builds a predicate expecting an object to check against the given key / value pair.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var hasTheCorrectAnswer = _.hasKeyValue(\"answer\", 42);\n *\n * hasTheCorrectAnswer({answer: 2}) // false\n * hasTheCorrectAnswer({answer: 42}) // true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasPathValue|hasPathValue}\n * @since 0.1.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n function hasKeyValue (key, value) {\n return function (obj) {\n return isUndefined(value) ? has(obj, key) && obj[key] === value : areSVZ(value, obj[key]);\n };\n }\n\n /**\n * Builds a predicate to check if the given path exists in an object and holds the desired value.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * personal: {\n * age: 25,\n * gender: \"M\"\n * },\n * scores: [\n * {id: 1, value: 10, passed: false},\n * {id: 2, value: 20, passed: false},\n * {id: 3, value: 30, passed: true}\n * ]\n * };\n *\n * var isMale = _.hasPathValue(\"personal.gender\", \"M\");\n * var hasPassedFirstTest = _.hasPathValue(\"scores.0.passed\", true);\n * var hasPassedLastTest = _.hasPathValue(\"scores.-1.passed\", true);\n *\n * isMale(user) // => true\n * hasPassedFirstTest(user) // => false\n * hasPassedLastTest(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKeyValue|hasKeyValue}\n * @since 0.41.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function hasPathValue (path, value, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return pathInfo.isValid && areSVZ(pathInfo.target, value);\n };\n }\n\n /**\n * Makes an object immutable by recursively calling Object.freeze\n * on its members.\n * @private\n * @param {Object} obj\n * @param {Array} seen\n * @returns {Object} The obj parameter itself, not a copy.\n */\n function _immutable (obj, seen) {\n if (seen.indexOf(obj) === -1) {\n seen.push(Object.freeze(obj));\n\n forEach(Object.getOwnPropertyNames(obj), function (key) {\n var value = obj[key];\n\n if (typeof value === \"object\" && !isNull(value)) {\n _immutable(value, seen);\n }\n });\n }\n\n return obj;\n }\n\n /**\n * Makes an object immutable by recursively calling [Object.freeze]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze}\n * on its members.
\n * Any attempt to extend or modify the object can throw a TypeError or fail silently,\n * depending on the environment and the [strict mode]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode} directive.\n * @example\n * var user = _.immutable({\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\"\n * },\n * luckyNumbers: [13, 17]\n * });\n *\n * // All of these statements will fail and possibly\n * // throw a TypeError (see the function description)\n * user.name = \"Joe\";\n * delete user.name;\n * user.newProperty = [];\n * user.login.password = \"foo\";\n * user.luckyNumbers.push(-13);\n *\n * @memberof module:lamb\n * @category Object\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Object}\n */\n function immutable (obj) {\n return _immutable(obj, []);\n }\n\n /**\n * A null-safe version of Object.keys.\n * @private\n * @function\n * @param {Object} obj\n * @returns {String[]}\n */\n var _safeKeys = compose(Object.keys, Object);\n\n /**\n * Retrieves the list of the own enumerable properties of an object.
\n * Although [Object.keys]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys}\n * is already present in ECMAScript 5, its behaviour changed in the subsequent specifications\n * of the standard.
\n * This function shims the ECMAScript 6 version, by forcing a conversion to\n * object for any value but null and undefined.\n * @example Showing the difference with {@link module:lamb.enumerables|enumerables}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.enumerables(foo) // => [\"d\", \"a\"]\n * _.keys(foo) // => [\"d\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.enumerables|enumerables}\n * @since 0.25.1\n * @param {Object} obj\n * @returns {String[]}\n */\n var keys = _unsafeKeyListFrom(_safeKeys);\n\n /**\n * Builds a predicate to check if the given key satisfies the desired condition\n * on an object.\n * @example\n * var users = [\n * {name: \"John\", age: 25},\n * {name: \"Jane\", age: 15},\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n *\n * isAdult(users[0]) // => true\n * isAdult(users[1]) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathSatisfies|pathSatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} key\n * @returns {Function}\n */\n function keySatisfies (predicate, key) {\n return function (obj) {\n return predicate.call(this, obj[key]);\n };\n }\n\n /**\n * Builds an object from the two given lists, using the first one as keys and the last\n * one as values.
\n * If the list of keys is longer than the values one, the keys will be created with\n * undefined values.
\n * If more values than keys are supplied, the extra values will be ignored.\n * @example\n * _.make([\"a\", \"b\", \"c\"], [1, 2, 3]) // => {a: 1, b: 2, c: 3}\n * _.make([\"a\", \"b\", \"c\"], [1, 2]) // => {a: 1, b: 2, c: undefined}\n * _.make([\"a\", \"b\"], [1, 2, 3]) // => {a: 1, b: 2}\n * _.make([null, void 0, 2], [1, 2, 3]) // => {\"null\": 1, \"undefined\": 2, \"2\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.tear|tear}, {@link module:lamb.tearOwn|tearOwn} for the reverse operation\n * @since 0.8.0\n * @param {String[]} names\n * @param {ArrayLike} values\n * @returns {Object}\n */\n function make (names, values) {\n var result = {};\n var valuesLen = values.length;\n\n for (var i = 0, len = names.length; i < len; i++) {\n result[names[i]] = i < valuesLen ? values[i] : void 0;\n }\n\n return result;\n }\n\n /**\n * Creates a new object by applying the given function\n * to all enumerable properties of the source one.\n * @example\n * var weights = {\n * john: \"72.5 Kg\",\n * jane: \"52.3 Kg\"\n * };\n *\n * _.mapValues(weights, parseFloat) // => {john: 72.5, jane: 52.3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValuesWith|mapValuesWith}\n * @since 0.54.0\n * @param {Object} source\n * @param {ObjectIteratorCallback} fn\n * @returns {Object}\n */\n function mapValues (source, fn) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n result[key] = fn(source[key], key, source);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.mapValues|mapValues}.
\n * Expects a mapping function to build a new function waiting for the\n * object to act upon.\n * @example\n * var incValues = _.mapValuesWith(_.add(1));\n * var results = {\n * first: 10,\n * second: 5,\n * third: 3\n * };\n *\n * incValues(results) // => {first: 11, second: 6, third: 4}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValues|mapValues}\n * @since 0.54.0\n * @function\n * @param {ObjectIteratorCallback} fn\n * @returns {Function}\n */\n var mapValuesWith = _curry2(mapValues, true);\n\n /**\n * Merges the received objects using the provided function to retrieve their keys.\n * @private\n * @param {Function} getKeys\n * @param {Object} a\n * @param {Object} b\n * @returns {Function}\n */\n function _merge (getKeys, a, b) {\n return reduce([a, b], function (result, source) {\n forEach(getKeys(source), function (key) {\n result[key] = source[key];\n });\n\n return result;\n }, {});\n }\n\n /**\n * Merges the enumerable properties of the provided sources into a new object.
\n * In case of key homonymy the last source has precedence over the first.\n * @example\n * _.merge({a: 1, b: 3}, {b: 5, c: 4}) // => {a: 1, b: 5, c: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.merge([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.merge(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.merge({a: 2}, 99) // => {a: 2}\n * _.merge({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mergeOwn|mergeOwn} to merge own properties only\n * @since 0.10.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\n var merge = partial(_merge, [enumerables]);\n\n /**\n * Same as {@link module:lamb.merge|merge}, but only the own properties of the\n * sources are taken into account.\n * @example Showing the difference with merge:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * var bar = {d: 4};\n *\n * _.merge(foo, bar) // => {a: 1, b: 2, c: 3, d: 4}\n * _.mergeOwn(foo, bar) // => {c: 3, d: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.mergeOwn([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.mergeOwn(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.mergeOwn({a: 2}, 99) // => {a: 2}\n * _.mergeOwn({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.merge|merge} to merge all enumerable properties\n * @since 0.12.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\n var mergeOwn = partial(_merge, [keys]);\n\n /**\n * Accepts an object and build a function expecting a key to create a \"pair\" with the key\n * and its value.\n * @private\n * @function\n * @param {Object} obj\n * @returns {Function}\n */\n var _keyToPairIn = _curry2(function (obj, key) {\n return [key, obj[key]];\n });\n\n /**\n * Using the provided function to retrieve the keys, builds a new function\n * expecting an object to create a list of key / value pairs.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _pairsFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), _keyToPairIn(obj));\n });\n\n /**\n * Same as {@link module:lamb.pairs|pairs}, but only the own enumerable properties of the object are\n * taken into account.
\n * See also {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example Showing the difference with pairs:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.pairs(foo) // => [[\"c\", 3], [\"b\", 2], [\"a\", 1]]\n * _.ownPairs(foo) // => [[\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pairs|pairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var ownPairs = _pairsFrom(keys);\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create the list of values for such keys.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _valuesFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), function (key) {\n return obj[key];\n });\n });\n\n /**\n * Same as {@link module:lamb.values|values}, but only the own enumerable properties of the object are\n * taken into account.
\n * @example Showing the difference with values:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.values(foo) // => [3, 2, 1]\n * _.ownValues(foo) // => [3]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.values|values}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var ownValues = _valuesFrom(keys);\n\n /**\n * Converts an object into an array of key / value pairs of its enumerable properties.
\n * See also {@link module:lamb.ownPairs|ownPairs} for picking only the own enumerable\n * properties and {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example\n * _.pairs({a: 1, b: 2, c: 3}) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownPairs|ownPairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var pairs = _pairsFrom(enumerables);\n\n /**\n * Checks if the provided path exists in the given object.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * _.pathExistsIn(user, \"address.city\") // => true\n * _.pathExistsIn(user, \"address.country\") // => false\n * _.pathExistsIn(user, \"scores.1\") // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathExists|pathExists}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {Object} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Boolean}\n */\n function pathExistsIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).isValid;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.pathExistsIn|pathExistsIn} using the given\n * path and the optional separator. The resulting function expects the object to check.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * var hasCity = _.pathExists(\"address.city\");\n * var hasCountry = _.pathExists(\"address.country\");\n * var hasAtLeastThreeScores = _.pathExists(\"scores.2\");\n *\n * hasCity(user) // => true\n * hasCountry(user) // => false\n * hasAtLeastThreeScores(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var pathExists = _makePartial3(pathExistsIn);\n\n /**\n * Builds a predicate that verifies if a condition is satisfied for the given\n * path in an object.
\n * Like the other \"path functions\" you can use integers in the path, even\n * negative ones, to refer to array-like object indexes, but the priority will\n * be given to existing object keys.\n * @example\n * var user = {\n * name: \"John\",\n * performance: {\n * scores: [1, 5, 10]\n * }\n * };\n *\n * var gotAnHighScore = _.pathSatisfies(_.contains(10), \"performance.scores\");\n * var hadAGoodStart = _.pathSatisfies(_.isGT(6), \"performance.scores.0\");\n *\n * gotAnHighScore(user) // => true\n * hadAGoodStart(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.keySatisfies|keySatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function pathSatisfies (predicate, path, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return predicate.call(this, pathInfo.target);\n };\n }\n\n /**\n * Returns an object containing only the specified properties of the given object.
\n * Non existent properties will be ignored.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.pick(user, [\"name\", \"age\"]) // => {\"name\": \"john\", \"age\": 30};\n * _.pick(user, [\"name\", \"email\"]) // => {\"name\": \"john\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pickIf|pickIf}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} whitelist\n * @returns {Object}\n */\n function pick (source, whitelist) {\n var result = {};\n\n for (var i = 0, len = whitelist.length, key; i < len; i++) {\n key = whitelist[i];\n\n if (has(source, key)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be included in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var pickIfIsString = _.pickIf(_.isType(\"String\"));\n *\n * pickIfIsString(user) // => {name: \"john\", surname: \"doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n function pickIf (predicate) {\n return function (source) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n if (predicate(source[key], key, source)) {\n result[key] = source[key];\n }\n }\n\n return result;\n };\n }\n\n /**\n * A curried version of {@link module:lamb.pick|pick}, expecting a whitelist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.pickKeys([\"id\", \"active\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var select = _.compose(_.mapWith, _.pickKeys);\n * var selectUserInfo = select([\"id\", \"active\"]);\n *\n * selectUserInfo(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickIf|pickIf}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.35.0\n * @param {String[]} whitelist\n * @returns {Function}\n */\n var pickKeys = _curry2(pick, true);\n\n /**\n * Creates a copy of the given object with its enumerable keys renamed as\n * indicated in the provided lookup table.\n * @example\n * var person = {\"firstName\": \"John\", \"lastName\": \"Doe\"};\n * var keysMap = {\"firstName\": \"name\", \"lastName\": \"surname\"};\n *\n * _.rename(person, keysMap) // => {\"name\": \"John\", \"surname\": \"Doe\"}\n *\n * @example It's safe using it to swap keys:\n * var keysMap = {\"firstName\": \"lastName\", \"lastName\": \"firstName\"};\n *\n * _.rename(person, keysMap) // => {\"lastName\": \"John\", \"firstName\": \"Doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.renameKeys|renameKeys}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} source\n * @param {Object} keysMap\n * @returns {Object}\n */\n function rename (source, keysMap) {\n keysMap = Object(keysMap);\n var result = {};\n var oldKeys = enumerables(source);\n\n for (var prop in keysMap) {\n if (~oldKeys.indexOf(prop)) {\n result[keysMap[prop]] = source[prop];\n }\n }\n\n for (var i = 0, len = oldKeys.length, key; i < len; i++) {\n key = oldKeys[i];\n\n if (!(key in keysMap || key in result)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.rename|rename} expecting a\n * keysMap to build a function waiting for the object to act upon.\n * @example\n * var persons = [\n * {\"firstName\": \"John\", \"lastName\": \"Doe\"},\n * {\"first_name\": \"Mario\", \"last_name\": \"Rossi\"},\n * ];\n * var normalizeKeys = _.renameKeys({\n * \"firstName\": \"name\",\n * \"first_name\": \"name\",\n * \"lastName\": \"surname\",\n * \"last_name\": \"surname\"\n * });\n *\n * _.map(persons, normalizeKeys) // =>\n * // [\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} keysMap\n * @returns {Function}\n */\n var renameKeys = _curry2(rename, true);\n\n /**\n * Uses the provided function as a keysMap generator and returns\n * a function expecting the object whose keys we want to {@link module:lamb.rename|rename}.\n * @example\n * var person = {\"NAME\": \"John\", \"SURNAME\": \"Doe\"};\n * var arrayToLower = _.mapWith(_.invoker(\"toLowerCase\"));\n * var makeLowerKeysMap = function (source) {\n * var sourceKeys = _.keys(source);\n *\n * return _.make(sourceKeys, arrayToLower(sourceKeys));\n * };\n * var lowerKeysFor = _.renameWith(makeLowerKeysMap);\n *\n * lowerKeysFor(person) // => {\"name\": \"John\", \"surname\": \"doe\"};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameKeys|renameKeys}\n * @since 0.26.0\n * @param {Function} fn\n * @returns {Function}\n */\n function renameWith (fn) {\n return function (source) {\n return rename(source, fn(source));\n };\n }\n\n /**\n * Sets, or creates, a property in a copy of the provided object to the desired value.\n * @private\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function _setIn (source, key, value) {\n var result = {};\n\n for (var prop in source) {\n result[prop] = source[prop];\n }\n\n result[key] = value;\n\n return result;\n }\n\n /**\n * Sets the specified key to the given value in a copy of the provided object.
\n * All the remaining enumerable keys of the source object will be simply copied in the\n * result object without breaking references.
\n * If the specified key is not part of the source object, it will be added to the\n * result.
\n * The main purpose of the function is to work on simple plain objects used as\n * data structures, such as JSON objects, and makes no effort to play nice with\n * objects created from an OOP perspective (it's not worth it).
\n * For example the prototype of the result will be Object's regardless\n * of the source's one.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n *\n * _.setIn(user, \"name\", \"Jane\") // => {name: \"Jane\", surname: \"Doe\", age: 30}\n * _.setIn(user, \"gender\", \"male\") // => {name: \"John\", surname: \"Doe\", age: 30, gender: \"male\"}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setKey|setKey}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function setIn (source, key, value) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setIn(source, key, value);\n }\n\n /**\n * Builds a partial application of {@link module:lamb.setIn|setIn} with the provided\n * key and value.
\n * The resulting function expects the object to act upon.
\n * Please refer to {@link module:lamb.setIn|setIn}'s description for explanations about\n * how the copy of the source object is made.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n * var setAgeTo40 = _.setKey(\"age\", 40);\n *\n * setAgeTo40(user) // => {name: \"john\", surname: \"doe\", age: 40}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.setIn|setIn}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n var setKey = _makePartial3(setIn);\n\n /**\n * Accepts a target object and a key name and verifies that the target is an array and that\n * the key is an existing index.\n * @private\n * @param {Object} target\n * @param {String|Number} key\n * @returns {Boolean}\n */\n function _isArrayIndex (target, key) {\n var n = +key;\n\n return Array.isArray(target) && n % 1 === 0 && !(n < 0 && _isEnumerable(target, key));\n }\n\n /**\n * Sets the object's property targeted by the given path to the desired value.
\n * Works with arrays and is able to set their indexes, even negative ones.\n * @private\n * @param {Object|Array} obj\n * @param {String[]} parts\n * @param {*} value\n * @returns {Object|Array}\n */\n function _setPathIn (obj, parts, value) {\n var key = parts[0];\n var partsLen = parts.length;\n var v;\n\n if (partsLen === 1) {\n v = value;\n } else {\n var targetKey = _getPathKey(obj, key, false);\n\n v = _setPathIn(\n isUndefined(targetKey) ? targetKey : obj[targetKey],\n slice(parts, 1, partsLen),\n value\n );\n }\n\n return _isArrayIndex(obj, key) ? _setIndex(obj, key, v) : _setIn(obj, key, v);\n }\n\n /**\n * Allows to change a nested value in a copy of the provided object.
\n * The function will delegate the \"set action\" to {@link module:lamb.setIn|setIn} or\n * {@link module:lamb.setAt|setAt} depending on the value encountered in the path,\n * so please refer to the documentation of those functions for specifics about the\n * implementation.
\n * Note anyway that the distinction will be between Arrays, delegated\n * to {@link module:lamb.setAt|setAt}, and everything else (including array-like objects),\n * which will be delegated to {@link module:lamb.setIn|setIn}.
\n * As a result of that, array-like objects will be converted to objects having numbers as keys\n * and paths targeting non-object values will be converted to empty objects.
\n * You can anyway target array elements using integers in the path, even negative ones, but\n * the priority will be given to existing, and enumerable, object keys.
\n * Non-enumerable properties encountered in the path will be considered as non-existent properties.
\n * Like {@link module:lamb.getPathIn|getPathIn} or {@link module:lamb.getPath|getPath} you can\n * use custom path separators.\n * @example\n * var user = {id: 1, status: {active : false, scores: [2, 4, 6]}};\n *\n * _.setPathIn(user, \"status.active\", true) // => {id: 1, status: {active : true, scores: [2, 4, 6]}}\n *\n * @example Targeting arrays:\n * _.setPathIn(user, \"status.scores.0\", 8) // => {id: 1, status: {active : false, scores: [8, 4, 6]}}\n *\n * // you can use negative indexes as well\n * _.setPathIn(user, \"status.scores.-1\", 8) // => {id: 1, status: {active : false, scores: [2, 4, 8]}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.setPathIn(user, \"scores.0.value\", 8);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 8, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPath|setPath}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function setPathIn (source, path, value, separator) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setPathIn(source, _toPathParts(path, separator), value);\n }\n\n /**\n * Builds a partial application of {@link module:lamb.setPathIn|setPathIn} expecting the\n * object to act upon.
\n * See {@link module:lamb.setPathIn|setPathIn} for more details and examples.\n * @example\n * var user = {id: 1, status: {active: false}};\n * var activate = _.setPath(\"status.active\", true);\n *\n * activate(user) // => {id: 1, status: {active: true}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPathIn|setPathIn}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function setPath (path, value, separator) {\n return function (source) {\n return setPathIn(source, path, value, separator);\n };\n }\n\n /**\n * Returns a copy of the source object without the specified properties.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.skip(user, [\"name\", \"age\"]) // => {surname: \"doe\"};\n * _.skip(user, [\"name\", \"email\"]) // => {surname: \"doe\", age: 30};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.skipKeys|skipKeys}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} blacklist\n * @returns {Object}\n */\n function skip (source, blacklist) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n var props = make(blacklist, []);\n\n for (var key in source) {\n if (!(key in props)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be omitted in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var skipIfIstring = _.skipIf(_.isType(\"String\"));\n *\n * skipIfIstring(user) // => {age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n var skipIf = compose(pickIf, not);\n\n /**\n * A curried version of {@link module:lamb.skip|skip}, expecting a blacklist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.skipKeys([\"name\", \"surname\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var discard = _.compose(_.mapWith, _.skipKeys);\n * var discardNames = discard([\"name\", \"surname\"]);\n *\n * discardNames(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.35.0\n * @param {String[]} blacklist\n * @returns {Function}\n */\n var skipKeys = _curry2(skip, true);\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create an array containing a list\n * of the keys in its first index and the corresponding list of values\n * in the second one.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _tearFrom = _curry2(function (getKeys, obj) {\n return reduce(getKeys(obj), function (result, key) {\n result[0].push(key);\n result[1].push(obj[key]);\n\n return result;\n }, [[], []]);\n });\n\n /**\n * Tears an object apart by transforming it in an array of two lists: one containing\n * its enumerable keys, the other containing the corresponding values.
\n * Although this \"tearing apart\" may sound as a rather violent process, the source\n * object will be unharmed.\n * @example\n * _.tear({a: 1, b: 2, c: 3}) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tearOwn|tearOwn}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tear = _tearFrom(enumerables);\n\n /**\n * Same as {@link module:lamb.tear|tear}, but only the own properties of the object are\n * taken into account.\n * @example Showing the difference with tear:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.tear(foo) // => [[\"c\", \"b\", \"a\"], [3, 2, 1]]\n * _.tearOwn(foo) // => [[\"c\"], [3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tear|tear}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tearOwn = _tearFrom(keys);\n\n /**\n * Creates a copy of the given object having the desired key value updated by applying\n * the provided function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIn(user, \"name\", toUpperCase) // => {name: \"JOHN\", visits: 2}\n * _.updateIn(user, \"surname\", toUpperCase) // => {name: \"John\", visits: 2}\n *\n * @example Non-enumerable properties will be treated as non-existent:\n * var user = Object.create({name: \"John\"}, {visits: {value: 2}});\n *\n * _.updateIn(user, \"visits\", _.add(1)) // => {name: \"John\", visits: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updateKey|updateKey}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {Object} source\n * @param {String} key\n * @param {Function} updater\n * @returns {Object}\n */\n function updateIn (source, key, updater) {\n return _isEnumerable(source, key) ?\n _setIn(source, key, updater(source[key])) :\n _merge(enumerables, source, {});\n }\n\n /**\n * Builds a partial application of {@link module:lamb.updateIn|updateIn} with the provided\n * key and updater, expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var incrementVisits = _.updateKey(\"visits\", _.add(1));\n *\n * incrementVisits(user) // => {name: \"John\", visits: 3}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.updateIn|updateIn}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {String} key\n * @param {Function} updater\n * @returns {Function}\n */\n var updateKey = _makePartial3(updateIn);\n\n /**\n * Allows to change a nested value in a copy of the given object by applying the provided\n * function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var inc = _.add(1);\n *\n * _.updatePathIn(user, \"status.visits\", inc) // => {id: 1, status: {scores: [2, 4, 6]}, visits: 1}\n *\n * @example Targeting arrays:\n * _.updatePathIn(user, \"status.scores.0\", inc) // => {id: 1, status: {scores: [3, 4, 6], visits: 0}}\n *\n * // you can use negative indexes as well\n * _.updatePathIn(user, \"status.scores.-1\", inc) // => {id: 1, status: {scores: [2, 4, 7], visits: 0}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.updatePathIn(user, \"scores.0.value\", inc);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 3, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePath|updatePath}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function updatePathIn (source, path, updater, separator) {\n var parts = _toPathParts(path, separator);\n var pathInfo = _getPathInfo(source, parts, false);\n\n if (pathInfo.isValid) {\n return _setPathIn(source, parts, updater(pathInfo.target));\n } else {\n return Array.isArray(source) ? slice(source, 0, source.length) : _merge(enumerables, source, {});\n }\n }\n\n /**\n * Builds a partial application of {@link module:lamb.updatePathIn|updatePathIn}\n * expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var incrementScores = _.updatePath(\"status.scores\", _.mapWith(_.add(1)))\n *\n * incrementScores(user) // => {id: 1, status: {scores: [3, 5, 7], visits: 0}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePathIn|updatePathIn}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function updatePath (path, updater, separator) {\n return function (source) {\n return updatePathIn(source, path, updater, separator);\n };\n }\n\n /**\n * Validates an object with the given list of {@link module:lamb.checker|checker} functions.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * _.validate(user1, userCheckers) // => []\n * _.validate(user2, userCheckers) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validateWith|validateWith}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Object} obj\n * @param {Function[]} checkers\n * @returns {Array>} An array of errors in the form returned by\n * {@link module:lamb.checker|checker}, or an empty array.\n */\n function validate (obj, checkers) {\n return reduce(checkers, function (errors, _checker) {\n var result = _checker(obj);\n\n result.length && errors.push(result);\n\n return errors;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.validate|validate} accepting a list of\n * {@link module:lamb.checker|checkers} and returning a function expecting the object to validate.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n * var validateUser = _.validateWith(userCheckers);\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * validateUser(user1) // => []\n * validateUser(user2) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.validate|validate}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Function[]} checkers\n * @returns {Function}\n */\n var validateWith = _curry2(validate, true);\n\n /**\n * Generates an array with the values of the enumerable properties of the given object.
\n * See also {@link module:lamb.ownValues|ownValues} to pick only from the own properties of the object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.values(user) // => [\"john\", \"doe\", 30]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownValues|ownValues}\n * @since 0.1.0\n * @param {Object} obj\n * @returns {Array}\n */\n var values = _valuesFrom(enumerables);\n\n /**\n * A null-safe function to repeat the source string the desired amount of times.\n * @private\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function _repeat (source, times) {\n var result = \"\";\n\n for (var i = 0; i < times; i++) {\n result += source;\n }\n\n return result;\n }\n\n /**\n * Builds the prefix or suffix to be used when padding a string.\n * @private\n * @param {String} source\n * @param {String} char\n * @param {Number} len\n * @returns {String}\n */\n function _getPadding (source, char, len) {\n if (!isNil(source) && type(source) !== \"String\") {\n source = String(source);\n }\n\n return _repeat(String(char)[0] || \"\", Math.ceil(len - source.length));\n }\n\n /**\n * Pads a string to the desired length with the given char starting from the beginning of the string.\n * @example\n * _.padLeft(\"foo\", \"-\", 0) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", -1) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", 5) // => \"--foo\"\n * _.padLeft(\"foo\", \"-\", 3) // => \"foo\"\n * _.padLeft(\"foo\", \"ab\", 7) // => \"aaaafoo\"\n * _.padLeft(\"foo\", \"\", 5) // => \"foo\"\n * _.padLeft(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padRight|padRight}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padLeft (source, char, len) {\n return _getPadding(source, char, len) + source;\n }\n\n /**\n * Pads a string to the desired length with the given char starting from the end of the string.\n * @example\n * _.padRight(\"foo\", \"-\", 0) // => \"foo\"\n * _.padRight(\"foo\", \"-\", -1) // => \"foo\"\n * _.padRight(\"foo\", \"-\", 5) // => \"foo--\"\n * _.padRight(\"foo\", \"-\", 3) // => \"foo\"\n * _.padRight(\"foo\", \"ab\", 7) // => \"fooaaaa\"\n * _.padRight(\"foo\", \"\", 5) // => \"foo\"\n * _.padRight(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padLeft|padLeft}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padRight (source, char, len) {\n return source + _getPadding(source, char, len);\n }\n\n /**\n * Builds a new string by repeating the source string the desired amount of times.
\n * Note that unlike the current ES6 proposal for\n * [String.prototype.repeat]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat},\n * this function doesn't throw a RangeError if times is negative,\n * but returns an empty string instead.\n * @example\n * _.repeat(\"Hello\", -1) // => \"\"\n * _.repeat(\"Hello\", 1) // => \"Hello\"\n * _.repeat(\"Hello\", 3) // => \"HelloHelloHello\"\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function repeat (source, times) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"string\");\n }\n\n return _repeat(source, Math.floor(times));\n }\n\n /**\n * A generic version of String.prototype.search\n * @private\n * @function\n * @param {String} s\n * @param {RegExp} pattern\n * @return {Number}\n */\n var _search = generic(String.prototype.search);\n\n /**\n * Builds a predicate expecting a string to test against the given regular expression pattern.\n * @example\n * var hasNumbersOnly = _.testWith(/^\\d+$/);\n *\n * hasNumbersOnly(\"123\") // => true\n * hasNumbersOnly(\"123 Kg\") // => false\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {RegExp} pattern\n * @returns {Function}\n */\n function testWith (pattern) {\n return function (s) {\n return _search(s, pattern) !== -1;\n };\n }\n\n /**\n * Accepts a constructor and builds a predicate expecting an object,\n * which will be tested to verify whether the prototype of the constructor\n * is in its prototype chain.
\n * Wraps in a convenient way the native\n * [instanceof]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof} operator.\n * @example\n * function SomeObjA () {}\n *\n * var a = new SomeObjA();\n * var sObj = new String(\"foo\");\n * var s = \"foo\";\n *\n * _.isInstanceOf(Object)(a) // => true\n * _.isInstanceOf(SomeObjA)(a) // => true\n *\n * _.isInstanceOf(Object)(sObj) // => true\n * _.isInstanceOf(String)(sObj) // => true\n *\n * _.isInstanceOf(Object)(s) // => false\n * _.isInstanceOf(String)(s) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.47.0\n * @param {*} constructor\n * @returns {Function}\n */\n function isInstanceOf (constructor) {\n return function (obj) {\n return obj instanceof constructor;\n };\n }\n\n /**\n * Builds a predicate that expects a value to check against the specified type.\n * @example\n * var isString = _.isType(\"String\");\n *\n * isString(\"Hello\") // => true\n * isString(new String(\"Hi\")) // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.type|type}\n * @since 0.1.0\n * @param {String} typeName\n * @returns {Function}\n */\n function isType (typeName) {\n return function (value) {\n return type(value) === typeName;\n };\n }\n\n exports.__ = __;\n exports.always = always;\n exports.areSVZ = areSVZ;\n exports.binary = binary;\n exports.clamp = clamp;\n exports.clampWithin = clampWithin;\n exports.compose = compose;\n exports.forEach = forEach;\n exports.generic = generic;\n exports.identity = identity;\n exports.isNil = isNil;\n exports.isNull = isNull;\n exports.isSVZ = isSVZ;\n exports.isUndefined = isUndefined;\n exports.map = map;\n exports.mapWith = mapWith;\n exports.partial = partial;\n exports.partialRight = partialRight;\n exports.reduce = reduce;\n exports.reduceWith = reduceWith;\n exports.slice = slice;\n exports.sliceAt = sliceAt;\n exports.type = type;\n exports.append = append;\n exports.appendTo = appendTo;\n exports.contains = contains;\n exports.count = count;\n exports.countBy = countBy;\n exports.difference = difference;\n exports.drop = drop;\n exports.dropFrom = dropFrom;\n exports.dropWhile = dropWhile;\n exports.every = every;\n exports.everyIn = everyIn;\n exports.filter = filter;\n exports.filterWith = filterWith;\n exports.find = find;\n exports.findIndex = findIndex;\n exports.findWhere = findWhere;\n exports.findIndexWhere = findIndexWhere;\n exports.flatMap = flatMap;\n exports.flatMapWith = flatMapWith;\n exports.flatten = flatten;\n exports.getAt = getAt;\n exports.getIndex = getIndex;\n exports.group = group;\n exports.groupBy = groupBy;\n exports.head = head;\n exports.index = index;\n exports.indexBy = indexBy;\n exports.init = init;\n exports.insert = insert;\n exports.insertAt = insertAt;\n exports.intersection = intersection;\n exports.isIn = isIn;\n exports.join = join;\n exports.joinWith = joinWith;\n exports.last = last;\n exports.list = list;\n exports.partition = partition;\n exports.partitionWith = partitionWith;\n exports.pluck = pluck;\n exports.pluckKey = pluckKey;\n exports.pull = pull;\n exports.pullFrom = pullFrom;\n exports.reduceRight = reduceRight;\n exports.reduceRightWith = reduceRightWith;\n exports.reverse = reverse;\n exports.rotate = rotate;\n exports.rotateBy = rotateBy;\n exports.setAt = setAt;\n exports.setIndex = setIndex;\n exports.shallowFlatten = shallowFlatten;\n exports.some = some;\n exports.someIn = someIn;\n exports.sort = sort;\n exports.sortedInsert = sortedInsert;\n exports.sorter = sorter;\n exports.sorterDesc = sorterDesc;\n exports.sortWith = sortWith;\n exports.tail = tail;\n exports.take = take;\n exports.takeFrom = takeFrom;\n exports.takeWhile = takeWhile;\n exports.transpose = transpose;\n exports.union = union;\n exports.unionBy = unionBy;\n exports.uniques = uniques;\n exports.uniquesBy = uniquesBy;\n exports.updateAt = updateAt;\n exports.updateIndex = updateIndex;\n exports.zip = zip;\n exports.zipWithIndex = zipWithIndex;\n exports.application = application;\n exports.apply = apply;\n exports.applyTo = applyTo;\n exports.asPartial = asPartial;\n exports.aritize = aritize;\n exports.collect = collect;\n exports.curry = curry;\n exports.curryable = curryable;\n exports.curryableRight = curryableRight;\n exports.curryRight = curryRight;\n exports.debounce = debounce;\n exports.flip = flip;\n exports.getArgAt = getArgAt;\n exports.invoker = invoker;\n exports.invokerOn = invokerOn;\n exports.mapArgs = mapArgs;\n exports.pipe = pipe;\n exports.tapArgs = tapArgs;\n exports.throttle = throttle;\n exports.unary = unary;\n exports.adapter = adapter;\n exports.allOf = allOf;\n exports.anyOf = anyOf;\n exports.areSame = areSame;\n exports.case = case_;\n exports.condition = condition;\n exports.gt = gt;\n exports.gte = gte;\n exports.is = is;\n exports.isGT = isGT;\n exports.isGTE = isGTE;\n exports.isLT = isLT;\n exports.isLTE = isLTE;\n exports.lt = lt;\n exports.lte = lte;\n exports.not = not;\n exports.unless = unless;\n exports.when = when;\n exports.add = add;\n exports.deduct = deduct;\n exports.divide = divide;\n exports.divideBy = divideBy;\n exports.generate = generate;\n exports.isFinite = isFinite_;\n exports.isInteger = isInteger;\n exports.isSafeInteger = isSafeInteger;\n exports.modulo = modulo;\n exports.multiply = multiply;\n exports.multiplyBy = multiplyBy;\n exports.randomInt = randomInt;\n exports.range = range;\n exports.remainder = remainder;\n exports.subtract = subtract;\n exports.sum = sum;\n exports.checker = checker;\n exports.enumerables = enumerables;\n exports.fromPairs = fromPairs;\n exports.getIn = getIn;\n exports.getKey = getKey;\n exports.getPath = getPath;\n exports.getPathIn = getPathIn;\n exports.has = has;\n exports.hasKey = hasKey;\n exports.hasOwn = hasOwn;\n exports.hasOwnKey = hasOwnKey;\n exports.hasKeyValue = hasKeyValue;\n exports.hasPathValue = hasPathValue;\n exports.immutable = immutable;\n exports.keys = keys;\n exports.keySatisfies = keySatisfies;\n exports.make = make;\n exports.mapValues = mapValues;\n exports.mapValuesWith = mapValuesWith;\n exports.merge = merge;\n exports.mergeOwn = mergeOwn;\n exports.ownPairs = ownPairs;\n exports.ownValues = ownValues;\n exports.pairs = pairs;\n exports.pathExists = pathExists;\n exports.pathExistsIn = pathExistsIn;\n exports.pathSatisfies = pathSatisfies;\n exports.pick = pick;\n exports.pickIf = pickIf;\n exports.pickKeys = pickKeys;\n exports.rename = rename;\n exports.renameKeys = renameKeys;\n exports.renameWith = renameWith;\n exports.setIn = setIn;\n exports.setKey = setKey;\n exports.setPath = setPath;\n exports.setPathIn = setPathIn;\n exports.skip = skip;\n exports.skipIf = skipIf;\n exports.skipKeys = skipKeys;\n exports.tear = tear;\n exports.tearOwn = tearOwn;\n exports.updateIn = updateIn;\n exports.updateKey = updateKey;\n exports.updatePath = updatePath;\n exports.updatePathIn = updatePathIn;\n exports.validate = validate;\n exports.validateWith = validateWith;\n exports.values = values;\n exports.padLeft = padLeft;\n exports.padRight = padRight;\n exports.repeat = repeat;\n exports.testWith = testWith;\n exports.isInstanceOf = isInstanceOf;\n exports.isType = isType;\n\n Object.defineProperty(exports, '__esModule', { value: true });\n\n}));\n"]} \ No newline at end of file +{"version":3,"sources":["lamb.js"],"names":["global","factory","exports","module","define","amd","self","lamb","this","__","areSVZ","a","b","binary","fn","call","clamp","n","min","max","NaN","partial","args","Array","isArray","apply","arguments","boundArg","lastIdx","newArgs","argsLen","length","i","len","_makePartial3","shouldAritize","clampWithin","identity","value","compose","MAX_ARRAY_LENGTH","_toArrayLength","forEach","arrayLike","iteratee","generic","Function","bind","isNull","isUndefined","isNil","_curry2","isRightCurry","isSVZ","map","result","mapWith","_makeReducer","step","accumulator","initialValue","nCalls","idx","TypeError","reduce","reduceWith","_toInteger","Math","floor","abs","slice","start","end","begin","upTo","resultLen","sliceAt","objectProtoToString","Object","prototype","toString","type","appendTo","concat","append","isIn","contains","_groupWith","makeValue","element","key","count","countBy","filter","predicate","push","not","uniquesBy","seen","uniques","dropFrom","drop","_getNumConsecutiveHits","_makeArrayChecker","defaultResult","everyIn","every","filterWith","findIndex","find","findWhere","findIndexWhere","flatMap","array","el","arr","v","rLen","flatMapWith","_makeArrayFlattener","isDeep","_flatten","output","j","vLen","flatten","_toNaturalIndex","getIndex","index","getAt","group","groupBy","head","indexBy","init","insert","splice","insertAt","join","separator","String","joinWith","last","_argsToArrayFrom","list","partition","partitionWith","getIn","obj","getKey","pluckKey","pullFrom","values","pull","reduceRight","reduceRightWith","rotate","amount","shift","rotateBy","_setIndex","updater","setAt","aritize","arity","setIndex","shallowFlatten","someIn","some","_compareWith","criteria","criterion","compare","isDescending","_comparer","_sorter","reader","comparer","_makeCriterion","_makeCriteria","sorters","sort","sorter","sorterDesc","sortWith","tail","takeFrom","take","transpose","minLen","elementLen","_makeTypeErrorFor","desiredType","toLowerCase","pipe","functions","unionBy","union","updateIndex","zipWithIndex","application","applyTo","_curry","isAutoCurry","_currier","argsHolder","holderLen","newArgsLen","reverse","c","_argsTail","_invoker","boundArgs","methodName","target","method","boundArgsLen","ofs","_checkPredicates","checkAll","predicates","allOf","anyOf","areSame","gt","gte","is","isGT","isGTE","lt","isLT","lte","isLTE","sum","add","subtract","deduct","divide","divideBy","isInteger","multiply","multiplyBy","_forceToNumber","_isOwnEnumerable","propertyIsEnumerable","_safeEnumerables","_isEnumerable","indexOf","_getPathKey","includeNonEnumerables","_getPathInfo","parts","walkNonEnumerables","isValid","_toPathParts","path","split","getPathIn","_unsafeKeyListFrom","getKeys","enumerables","getPath","has","hasKey","hasOwn","hasOwnProperty","hasOwnKey","keys","make","names","valuesLen","mapValues","source","mapValuesWith","_merge","merge","mergeOwn","_keyToPairIn","_pairsFrom","ownPairs","_valuesFrom","ownValues","pairs","pathExistsIn","pathExists","pick","whitelist","pickIf","pickKeys","rename","keysMap","oldKeys","prop","renameKeys","_setIn","setIn","setKey","_setPathIn","partsLen","targetKey","setPathIn","skip","blacklist","props","skipIf","skipKeys","_tearFrom","tear","tearOwn","updateIn","updateKey","updatePathIn","pathInfo","validate","checkers","errors","_checker","validateWith","_repeat","times","_getPadding","char","ceil","_search","search","always","partialRight","difference","other","isNotInOther","dropWhile","intersection","lenA","pluck","sortedInsert","_getInsertionIndex","pivot","takeWhile","updateAt","zip","asPartial","_asPartial","collect","curry","curryable","curryableRight","curryRight","debounce","timespan","timeoutID","debounced","clearTimeout","setTimeout","flip","getArgAt","invoker","invokerOn","mapArgs","mapper","tapArgs","tappers","tappersLen","throttle","lastCall","now","Date","unary","adapter","case","condition","trueFn","falseFn","unless","when","generate","limit","isFinite","isSafeInteger","modulo","randomInt","random","range","remainder","checker","message","keyPaths","pathSeparator","getValues","fromPairs","pairsList","pair","hasKeyValue","hasPathValue","immutable","_immutable","freeze","getOwnPropertyNames","keySatisfies","pathSatisfies","renameWith","setPath","updatePath","padLeft","padRight","repeat","testWith","pattern","s","isInstanceOf","constructor","isType","typeName","defineProperty"],"mappings":"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","file":"lamb.min.js","sourcesContent":["/**\n* @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming.\n* @author Andrea Scartabelli \n* @version 0.58.0-alpha.2\n* @module lamb\n* @license MIT\n* @preserve\n*/\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define(['exports'], factory) :\n (global = global || self, factory(global.lamb = {}));\n}(this, function (exports) { 'use strict';\n\n /**\n * The placeholder object used in partial application.\n * @memberof module:lamb\n * @alias module:lamb.__\n * @category Special properties\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.57.0\n * @type {Object}\n */\n var __ = {};\n\n /**\n * Builds a function that returns a constant value.\n * It's actually the simplest form of the K combinator or Kestrel.\n * @example\n * var truth = _.always(true);\n *\n * truth() // => true\n * truth(false) // => true\n * truth(1, 2) // => true\n *\n * // the value being returned is actually the\n * // very same value passed to the function\n * var foo = {bar: \"baz\"};\n * var alwaysFoo = _.always(foo);\n *\n * alwaysFoo() === foo // => true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n function always (value) {\n return function () {\n return value;\n };\n }\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValueZero\" comparison.
\n * With this comparison NaN is equal to itself, but 0 and -0 are\n * considered the same value.
\n * See also {@link module:lamb.isSVZ|isSVZ} for a curried version building a predicate and\n * {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is} to perform a \"SameValue\" comparison.\n * @example\n * var testObject = {};\n *\n * _.areSVZ({}, testObject) // => false\n * _.areSVZ(testObject, testObject) // => true\n * _.areSVZ(\"foo\", \"foo\") // => true\n * _.areSVZ(0, -0) // => true\n * _.areSVZ(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.isSVZ|isSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSVZ (a, b) {\n return a !== a ? b !== b : a === b; // eslint-disable-line no-self-compare\n }\n\n /**\n * Builds a function that passes only two arguments to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * _.list(1, 2, 3, 4, 5) // => [1, 2, 3, 4, 5]\n * _.binary(_.list)(1, 2, 3, 4, 5) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.unary|unary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function binary (fn) {\n return function (a, b) {\n return fn.call(this, a, b);\n };\n }\n\n /**\n * \"Clamps\" a number within the given limits, both included.
\n * The function will convert to number all its parameters before starting any\n * evaluation, and will return NaN if min is greater\n * than max.\n * @example\n * _.clamp(-5, 0, 10) // => 0\n * _.clamp(5, 0, 10) // => 5\n * _.clamp(15, 0, 10) // => 10\n * _.clamp(0, 0, 10) // => 0\n * _.clamp(10, 0, 10) // => 10\n * _.is(_.clamp(-0, 0, 10), -0) // => true\n * _.clamp(10, 20, 15) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.clampWithin|clampWithin}\n * @since 0.13.0\n * @param {Number} n\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function clamp (n, min, max) {\n n = +n;\n min = +min;\n max = +max;\n\n if (min > max) {\n return NaN;\n } else {\n return n < min ? min : n > max ? max : n;\n }\n }\n\n /**\n * Builds a partially applied function.
\n * The {@link module:lamb.__|__} object can be used as a placeholder for arguments.
\n * @example\n * var __ = _.__;\n * var users = [\n * {id: 1, name: \"John\", active: true, confirmedMail: true},\n * {id: 2, name: \"Jane\", active: true, confirmedMail: false},\n * {id: 3, name: \"Mario\", active: false, confirmedMail: false}\n * ];\n * var isKeyTrue = _.partial(_.hasKeyValue, [__, true]);\n * var isActive = isKeyTrue(\"active\");\n * var hasConfirmedMail = isKeyTrue(\"confirmedMail\");\n *\n * _.map(users, isActive) // => [true, true, false]\n * _.map(users, hasConfirmedMail) // => [true, false, false]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.1.0\n * @param {Function} fn\n * @param {Array} args\n * @returns {Function}\n */\n function partial (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = 0;\n var newArgs = [];\n var argsLen = args.length;\n\n for (var i = 0, boundArg; i < argsLen; i++) {\n boundArg = args[i];\n newArgs[i] = boundArg === __ ? arguments[lastIdx++] : boundArg;\n }\n\n for (var len = arguments.length; lastIdx < len; lastIdx++) {\n newArgs[i++] = arguments[lastIdx];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Builds a partial application of a ternary function so that its first parameter\n * is expected as the last one.
\n * The shouldAritize parameter is for the \"reduce\" functions, where\n * the absence of the initialValue transforms a \"fold\" operation into a\n * \"reduce\" one.\n * @private\n * @param {Function} fn\n * @param {Boolean} shouldAritize\n * @returns {Function}\n */\n function _makePartial3 (fn, shouldAritize) {\n return function (a, b) {\n var f = shouldAritize && arguments.length !== 2 ? binary(fn) : fn;\n\n return partial(f, [__, a, b]);\n };\n }\n\n /**\n * A curried version of {@link module:lamb.clamp|clamp}, expecting a min\n * and a max value, that builds a function waiting for the number to clamp.\n * @example\n * _.clampWithin(0, 10)(-5) // => 0\n * _.clampWithin(0, 10)(5) // => 5\n * _.clampWithin(0, 10)(15) // => 10\n * _.clampWithin(0, 10)(0) // => 0\n * _.clampWithin(0, 10)(10) // => 10\n * _.is(_.clampWithin(0, 10)(-0), -0) // => true\n * _.clampWithin(20, 15)(10) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.clamp|clamp}\n * @since 0.47.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Function}\n */\n var clampWithin = _makePartial3(clamp);\n\n /**\n * The I combinator. Any value passed to the function is simply returned as it is.\n * @example\n * var foo = {bar: \"baz\"};\n *\n * _.identity(foo) === foo // true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {*} The value passed as parameter.\n */\n function identity (value) {\n return value;\n }\n\n /**\n * Returns a function that is the composition of the functions given as parameters.\n * The first function consumes the result of the function that follows.\n * @example\n * var sayHi = function (name) { return \"Hi, \" + name; };\n * var capitalize = function (s) {\n * return s[0].toUpperCase() + s.substr(1).toLowerCase();\n * };\n * var fixNameAndSayHi = _.compose(sayHi, capitalize);\n *\n * sayHi(\"bOb\") // => \"Hi, bOb\"\n * fixNameAndSayHi(\"bOb\") // \"Hi, Bob\"\n *\n * var users = [{name: \"fred\"}, {name: \"bOb\"}];\n * var sayHiToUser = _.compose(fixNameAndSayHi, _.getKey(\"name\"));\n *\n * _.map(users, sayHiToUser) // [\"Hi, Fred\", \"Hi, Bob\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.pipe|pipe}\n * @since 0.1.0\n * @param {Function} a\n * @param {Function} b\n * @returns {Function}\n */\n function compose (a, b) {\n return arguments.length ? function () {\n return a.call(this, b.apply(this, arguments));\n } : identity;\n }\n\n var MAX_ARRAY_LENGTH = 4294967295;\n var MAX_SAFE_INTEGER = 9007199254740991;\n\n /**\n * Converts a value to a valid array length, thus an integer within\n * 0 and 232 - 1 (both included).\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toArrayLength (value) {\n return clamp(value, 0, MAX_ARRAY_LENGTH) >>> 0;\n }\n\n /**\n * Executes the provided iteratee for each element of the given array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example Adding a CSS class to all elements of a NodeList in a browser environment:\n * var addClass = _.curry(function (className, element) {\n * element.classList.add(className);\n * });\n * var paragraphs = document.querySelectorAll(\"#some-container p\");\n *\n * _.forEach(paragraphs, addClass(\"main\"));\n * // each \"p\" element in the container will have the \"main\" class now\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Undefined}\n */\n function forEach (arrayLike, iteratee) {\n for (var i = 0, len = _toArrayLength(arrayLike.length); i < len; i++) {\n iteratee(arrayLike[i], i, arrayLike);\n }\n }\n\n /**\n * Creates generic functions out of methods.\n * @author A very little change on a great idea by [Irakli Gozalishvili]{@link https://github.com/Gozala/}.\n * Thanks for this *beautiful* one-liner (never liked your \"unbind\" naming choice, though).\n * @memberof module:lamb\n * @category Function\n * @function\n * @example\n * var join = _.generic(Array.prototype.join);\n *\n * join([1, 2, 3, 4, 5], \"-\") // => \"1-2-3-4-5\"\n *\n * // the function will work with any array-like object\n * join(\"hello\", \"-\") // => \"h-e-l-l-o\"\n *\n * @since 0.1.0\n * @param {Function} method\n * @returns {Function}\n */\n var generic = Function.bind.bind(Function.call);\n\n /**\n * Verifies if a value is null.\n * @example\n * _.isNull(null) // => true\n * _.isNull(void 0) // => false\n * _.isNull(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for undefined too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNull (value) {\n return value === null;\n }\n\n /**\n * Verifies if a value is undefined.\n * @example\n * _.isUndefined(null) // => false\n * _.isUndefined(void 0) // => true\n * _.isUndefined(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for null too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isUndefined (value) {\n return value === void 0;\n }\n\n /**\n * Verifies if a value is null or undefined.\n * @example\n * _.isNil(NaN) // => false\n * _.isNil({}) // => false\n * _.isNil(null) // => true\n * _.isNil(void 0) // => true\n * _.isNil() // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNull|isNull}\n * @see {@link module:lamb.isUndefined|isUndefined}\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNil (value) {\n return isNull(value) || isUndefined(value);\n }\n\n /**\n * Curries a function of arity 2.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry2 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return isRightCurry ? fn.call(this, b, a) : fn.call(this, a, b);\n };\n };\n }\n\n /**\n * A curried version of {@link module:lamb.areSVZ|areSVZ}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValueZero\"\n * comparison.
\n * See also {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is}\n * to perform a \"SameValue\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.isSVZ(john);\n * var isZero = _.isSVZ(0);\n * var isReallyNaN = _.isSVZ(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isZero(0) // => true\n * isZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSVZ|areSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var isSVZ = _curry2(areSVZ);\n\n /**\n * Builds a new array by applying the iteratee function to each element of the\n * received array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.map([\"Joe\", \"Mario\", \"Jane\"], _.invoker(\"toUpperCase\")) // => [\"JOE\", \"MARIO\", \"JANE\"]\n *\n * _.map([4, 9, 16], Math.sqrt); // => [2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.mapWith|mapWith}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function map (arrayLike, iteratee) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = iteratee(arrayLike[i], i, arrayLike);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.map|map} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var square = function (n) { return n * n; };\n * var getSquares = _.mapWith(square);\n *\n * getSquares([1, 2, 3, 4, 5]) // => [1, 4, 9, 16, 25]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.map|map}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ListIteratorCallback} iteratee\n * @returns {function}\n */\n var mapWith = _curry2(map, true);\n\n /**\n * Like {@link module:lamb.partial|partial} will build a partially applied function and\n * it will accept placeholders.
\n * The difference is that the bound arguments will be appended to the ones received by\n * the resulting function.\n * @example\n * Explaining the difference with partial:\n * var f1 = _.partial(_.list, [\"a\", \"b\", \"c\"]);\n * var f2 = _.partialRight(_.list, [\"a\", \"b\", \"c\"]);\n *\n * f1(\"d\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"d\", \"e\") // => [\"d\", \"e\", \"a\", \"b\", \"c\"]\n *\n * @example\n * Explaining placeholder substitutions:\n * var __ = _.__;\n * var f1 = _.partial(_.list, [\"a\", __, __, \"d\"]);\n * var f2 = _.partialRight(_.list, [\"a\", __, __, \"d\"]);\n *\n * f1(\"b\", \"c\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"b\", \"c\", \"e\") // => [\"b\", \"a\", \"c\", \"e\", \"d\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @param {Function} fn\n * @param {Array} args\n * @since 0.52.0\n * @returns {Function}\n */\n function partialRight (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = arguments.length - 1;\n var argsLen = args.length;\n var boundArgs = Array(argsLen);\n var newArgs = [];\n\n for (var i = argsLen - 1, boundArg; i > -1; i--) {\n boundArg = args[i];\n boundArgs[i] = boundArg === __ ? arguments[lastIdx--] : boundArg;\n }\n\n for (i = 0; i <= lastIdx; i++) {\n newArgs[i] = arguments[i];\n }\n\n for (var j = 0; j < argsLen; j++) {\n newArgs[i++] = boundArgs[j];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Builds a reduce function. The step parameter must be 1\n * to build {@link module:lamb.reduce|reduce} and -1 to build\n * {@link module:lamb.reduceRight|reduceRight}.\n * @private\n * @param {Number} step\n * @returns {Function}\n */\n function _makeReducer (step) {\n return function (arrayLike, accumulator, initialValue) {\n var len = _toArrayLength(arrayLike.length);\n var idx = step === 1 ? 0 : len - 1;\n var nCalls;\n var result;\n\n if (arguments.length === 3) {\n nCalls = len;\n result = initialValue;\n } else {\n if (len === 0) {\n throw new TypeError(\"Reduce of empty array-like with no initial value\");\n }\n\n result = arrayLike[idx];\n idx += step;\n nCalls = len - 1;\n }\n\n for (; nCalls--; idx += step) {\n result = accumulator(result, arrayLike[idx], idx, arrayLike);\n }\n\n return result;\n };\n }\n\n /**\n * Reduces (or folds) the values of an array-like object, starting from the first, to a new\n * value using the provided accumulator function.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.reduce([1, 2, 3, 4], _.sum) // => 10\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRight|reduceRight}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduce = _makeReducer(1);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduce} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceWith(_.sum)(arr) // => 15\n * _.reduceWith(_.subtract)(arr) // => -13\n * _.reduceWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRightWith|reduceRightWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceWith = _makePartial3(reduce, true);\n\n /**\n * Converts a value to an integer.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toInteger (value) {\n var n = +value;\n\n if (n !== n) { // eslint-disable-line no-self-compare\n return 0;\n } else if (n % 1 === 0) {\n return n;\n } else {\n return Math.floor(Math.abs(n)) * (n < 0 ? -1 : 1);\n }\n }\n\n /**\n * Builds an array by extracting a portion of an array-like object.
\n * Note that unlike the native array method this function ensures that dense\n * arrays are returned.
\n * Also, unlike the native method, the start and end\n * parameters aren't optional and will be simply converted to integer.
\n * See {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.slice(arr, 0, 2) // => [1, 2]\n * _.slice(arr, 2, -1) // => [3, 4]\n * _.slice(arr, -3, 5) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sliceAt|sliceAt}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike - Any array like object.\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Array}\n */\n function slice (arrayLike, start, end) {\n var len = _toArrayLength(arrayLike.length);\n var begin = _toInteger(start);\n var upTo = _toInteger(end);\n\n if (begin < 0) {\n begin = begin < -len ? 0 : begin + len;\n }\n\n if (upTo < 0) {\n upTo = upTo < -len ? 0 : upTo + len;\n } else if (upTo > len) {\n upTo = len;\n }\n\n var resultLen = upTo - begin;\n var result = resultLen > 0 ? Array(resultLen) : [];\n\n for (var i = 0; i < resultLen; i++) {\n result[i] = arrayLike[begin + i];\n }\n\n return result;\n }\n\n /**\n * Given the start and end bounds, builds a partial application\n * of {@link module:lamb.slice|slice} expecting the array-like object to slice.
\n * See also {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var s = \"hello\";\n * var dropFirstAndLast = _.sliceAt(1, -1);\n *\n * dropFirstAndLast(arr) // => [2, 3, 4]\n * dropFirstAndLast(s) // => [\"e\", \"l\", \"l\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.slice|slice}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.48.0\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Function}\n */\n var sliceAt = _makePartial3(slice);\n\n var objectProtoToString = Object.prototype.toString;\n\n /**\n * Retrieves the \"type tag\" from the given value.\n * @example\n * var x = 5;\n * var y = new Number(5);\n *\n * typeof x // => \"number\"\n * typeof y // => \"object\"\n * _.type(x) // => \"Number\"\n * _.type(y) // => \"Number\"\n *\n * _.type(Object.prototype.toString) // => \"Function\"\n * _.type(/a/) // => \"RegExp\"\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.9.0\n * @param {*} value\n * @returns {String}\n */\n function type (value) {\n return objectProtoToString.call(value).slice(8, -1);\n }\n\n /**\n * Appends the given value at the end of a copy of the provided array-like object.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.appendTo(arr, 5) // => [1, 2, 3, 4, 5]\n * _.appendTo(arr, [5]) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.append|append}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Array}\n */\n function appendTo (arrayLike, value) {\n return slice(arrayLike, 0, arrayLike.length).concat([value]);\n }\n\n /**\n * A curried version of {@link module:lamb.appendTo|appendTo} that uses the value to append\n * to build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.append(5)(arr) // => [1, 2, 3, 4, 5]\n * _.append([5])(arr) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.appendTo|appendTo}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {*} value\n * @returns {Function}\n */\n var append = _curry2(appendTo, true);\n\n /**\n * Checks if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.contains|contains} for a curried version building a predicate.\n * @example\n * var numbers = [0, 1, 2, 3, NaN];\n *\n * _.isIn(numbers, 1) // => true\n * _.isIn(numbers, 0) // => true\n * _.isIn(numbers, -0) // => true\n * _.isIn(numbers, NaN) // => true\n * _.isIn(numbers, 5) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.contains|contains}\n * @since 0.13.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Boolean}\n */\n function isIn (arrayLike, value) {\n var result = false;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (areSVZ(value, arrayLike[i])) {\n result = true;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Builds a predicate to check if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.isIn|isIn} for an uncurried version.\n * @example\n * var containsNaN = _.contains(NaN);\n *\n * containsNaN([0, 1, 2, 3, NaN]) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.isIn|isIn}\n * @since 0.13.0\n * @param {*} value\n * @returns {Function}\n */\n var contains = _curry2(isIn, true);\n\n /**\n * Builds a \"grouping function\" for an array-like object.\n * @private\n * @param {Function} makeValue\n * @returns {Function}\n */\n function _groupWith (makeValue) {\n return function (arrayLike, iteratee) {\n var result = {};\n var len = arrayLike.length;\n\n for (var i = 0, element, key; i < len; i++) {\n element = arrayLike[i];\n key = iteratee(element, i, arrayLike);\n result[key] = makeValue(result[key], element);\n }\n\n return result;\n };\n }\n\n /**\n * Transforms an array-like object in a lookup table with the keys generated by the provided\n * iteratee, having as values the count of matches for the key.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 17},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n * var getAgeStatus = function (person) { return person.age >= 18 ? \"adult\" : \"minor\"; };\n *\n * _.count(persons, getAgeStatus) // => {\"adult\": 1, \"minor\": 3}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var count = _groupWith(function (a) {\n return a ? ++a : 1;\n });\n\n /**\n * A curried version of {@link module:lamb.count|count} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCityOrUnknown = _.adapter([_.getKey(\"city\"), _.always(\"Unknown\")]);\n * var countByCity = _.countBy(getCityOrUnknown);\n *\n * countByCity(persons) // => {\"New York\": 2, \"Rome\": 1, \"Unknown\": 1}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.count|count}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var countBy = _curry2(count, true);\n\n /**\n * Builds an array comprised of all values of the array-like object passing the predicate\n * test.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n *\n * _.filter([\"Foo\", \"bar\", \"baZ\"], isLowerCase) // => [\"bar\"]\n *\n * // the function will work with any array-like object\n * _.filter(\"fooBAR\", isLowerCase) // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.filterWith|filterWith}\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @since 0.1.0\n * @returns {Array}\n */\n function filter (arrayLike, predicate) {\n var len = arrayLike.length;\n var result = [];\n\n for (var i = 0; i < len; i++) {\n predicate(arrayLike[i], i, arrayLike) && result.push(arrayLike[i]);\n }\n\n return result;\n }\n\n /**\n * Returns a predicate that negates the given one.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isOdd = _.not(isEven);\n *\n * isOdd(5) // => true\n * isOdd(4) // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @since 0.1.0\n * @param {Function} predicate\n * @returns {Function}\n */\n function not (predicate) {\n return function () {\n return !predicate.apply(this, arguments);\n };\n }\n\n /**\n * Using the provided iteratee, builds a function that will return an array comprised of the\n * unique elements of an array-like object. The values being compared are the ones returned by\n * the iteratee.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniques|uniques} if you don't need to transform your values before the\n * comparison.\n * @example\n * var data = [\n * {id: \"1\", name: \"John\"},\n * {id: \"4\", name: \"Jane\"},\n * {id: \"5\", name: \"Joe\"},\n * {id: \"1\", name: \"Mario\"},\n * {id: \"5\", name: \"Paolo\"},\n * ];\n * var uniquesById = _.uniquesBy(_.getKey(\"id\"));\n *\n * uniquesById(data) // => [{id: \"1\", name: \"John\"}, {id: \"4\", name: \"Jane\"}, {id: \"5\", name: \"Joe\"}]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.uniques|uniques}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function uniquesBy (iteratee) {\n return function (arrayLike) {\n var result = [];\n\n for (var i = 0, len = arrayLike.length, seen = [], value; i < len; i++) {\n value = iteratee(arrayLike[i], i, arrayLike);\n\n if (!isIn(seen, value)) {\n seen.push(value);\n result.push(arrayLike[i]);\n }\n }\n\n return result;\n };\n }\n\n /**\n * Returns an array comprised of the unique elements of the given array-like object.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniquesBy|uniquesBy} if you need to transform your values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.uniques([-0, 1, 2, 0, 2, 3, 4, 3, 5, 1]) // => [-0, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.uniquesBy|uniquesBy}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var uniques = uniquesBy(identity);\n\n /**\n * Returns an array of unique items present only in the first of the two given\n * array-like objects. To determine uniqueness the function uses the\n * [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 1, 3, 4];\n * var a2 = [2, 4, 5, 6];\n * var a3 = [3, 4, 5, 2, 1];\n *\n * _.difference(a1, a2) // => [1, 3]\n * _.difference(a2, a3) // => [6]\n * _.difference(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.intersection|intersection}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.pull|pull}, {@link module:lamb.pullFrom|pullFrom}\n * @since 0.6.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} other\n * @returns {Array}\n */\n function difference (arrayLike, other) {\n var isNotInOther = partial(not(isIn), [other]);\n\n return uniques(filter(arrayLike, isNotInOther));\n }\n\n /**\n * Builds an array without the first n elements of the given array or array-like object.\n * Note that, being this only a shortcut for a specific use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.dropFrom(arr, 2) // => [3, 4, 5]\n * _.dropFrom(arr, -1) // => [5]\n * _.dropFrom(arr, -10) // => [1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function dropFrom (arrayLike, n) {\n return slice(arrayLike, n, arrayLike.length);\n }\n\n /**\n * A curried version of {@link module:lamb.dropFrom|dropFrom} that expects the number of elements\n * to drop to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.dropFrom|dropFrom} about passing a\n * negative n.\n * @example\n * var drop2 = _.drop(2);\n *\n * drop2([1, 2, 3, 4, 5]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.5.0\n * @see {@link module:lamb.dropFrom|dropFrom}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @param {Number} n\n * @returns {Function}\n */\n var drop = _curry2(dropFrom, true);\n\n /**\n * Gets the number of consecutive elements satisfying a predicate in an array-like object.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function _getNumConsecutiveHits (arrayLike, predicate) {\n var idx = 0;\n var len = arrayLike.length;\n\n while (idx < len && predicate(arrayLike[idx], idx, arrayLike)) {\n idx++;\n }\n\n return idx;\n }\n\n /**\n * Builds a function that drops the first n elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropWhileIsEven = _.dropWhile(isEven);\n *\n * dropWhileIsEven([2, 4, 6, 8]) // => []\n * dropWhileIsEven([2, 4, 7, 8]) // => [7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.takeWhile|takeWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n function dropWhile (predicate) {\n return function (arrayLike) {\n return slice(arrayLike, _getNumConsecutiveHits(arrayLike, predicate), arrayLike.length);\n };\n }\n\n /**\n * Helper to build the {@link module:lamb.everyIn|everyIn} or the\n * {@link module:lamb.someIn|someIn} function.\n * @private\n * @param {Boolean} defaultResult\n * @returns {Function}\n */\n function _makeArrayChecker (defaultResult) {\n return function (arrayLike, predicate) {\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (defaultResult ^ !!predicate(arrayLike[i], i, arrayLike)) {\n return !defaultResult;\n }\n }\n\n return defaultResult;\n };\n }\n\n /**\n * Checks if all the elements in an array-like object satisfy the given predicate.
\n * The function will stop calling the predicate as soon as it returns a falsy value.
\n * Note that an empty array-like will always produce a true result regardless of the\n * predicate because of [vacuous truth]{@link https://en.wikipedia.org/wiki/Vacuous_truth}.
\n * Also note that unlike the native\n * [Array.prototype.every]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: true},\n * {\"name\": \"John\", \"age\": 40, active: true},\n * {\"name\": \"Mario\", \"age\": 17, active: true},\n * {\"name\": \"Paolo\", \"age\": 15, active: true}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.everyIn(persons, isAdult) // => false\n * _.everyIn(persons, isActive) // => true\n *\n * @example Showing the difference with Array.prototype.every:\n * var isDefined = _.not(_.isUndefined);\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.every(isDefined) // => true\n * _.everyIn(arr, isDefined) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.every|every}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var everyIn = _makeArrayChecker(true);\n\n /**\n * A curried version of {@link module:lamb.everyIn|everyIn} that expects a predicate\n * to build a function waiting for the array-like to act upon.\n * @example\n * var data = [2, 3, 5, 6, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var allEvens = _.every(isEven);\n * var allIntegers = _.every(_.isInteger);\n *\n * allEvens(data) // => false\n * allIntegers(data) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.everyIn|everyIn}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var every = _curry2(everyIn, true);\n\n /**\n * A curried version of {@link module:lamb.filter|filter} that uses the given predicate\n * to build a function expecting the array-like object to act upon.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n * var getLowerCaseEntries = _.filterWith(isLowerCase);\n *\n * getLowerCaseEntries([\"Foo\", \"bar\", \"baZ\"]) // => [\"bar\"]\n *\n * // array-like objects can be used as well\n * getLowerCaseEntries(\"fooBAR\") // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.filter|filter}\n * @since 0.9.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var filterWith = _curry2(filter, true);\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns its\n * index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findIndex(persons, _.hasKeyValue(\"age\", 40)) // => 1\n * _.findIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function findIndex (arrayLike, predicate) {\n var result = -1;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (predicate(arrayLike[i], i, arrayLike)) {\n result = i;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns it if\n * the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.find(persons, _.hasKeyValue(\"age\", 40)) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.find(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\n function find (arrayLike, predicate) {\n var idx = findIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n }\n\n /**\n * A curried version of {@link module:lamb.find|find} expecting the array-like object\n * to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 7]) // => 4\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.find|find}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findWhere = _curry2(find, true);\n\n /**\n * A curried version of {@link module:lamb.findIndex|findIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEvenIdx = _.findIndexWhere(isEven);\n *\n * findEvenIdx([1, 3, 4, 5, 7]) // => 2\n * findEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findIndex|findIndex}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findIndexWhere = _curry2(findIndex, true);\n\n /**\n * Similar to {@link module:lamb.map|map}, but if the mapping function returns an array this will\n * be concatenated, rather than pushed, to the final result.\n * @example Showing the difference with map:\n * var words = [\"foo\", \"bar\"];\n * var toCharArray = function (s) { return s.split(\"\"); };\n *\n * _.map(words, toCharArray) // => [[\"f\", \"o\", \"o\"], [\"b\", \"a\", \"r\"]]\n * _.flatMap(words, toCharArray) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.flatMapWith|flatMapWith}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.1.0\n * @param {Array} array\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function flatMap (array, iteratee) {\n return reduce(array, function (result, el, idx, arr) {\n var v = iteratee(el, idx, arr);\n\n if (!Array.isArray(v)) {\n v = [v];\n }\n\n for (var i = 0, len = v.length, rLen = result.length; i < len; i++) {\n result[rLen + i] = v[i];\n }\n\n return result;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.flatMap|flatMap} that uses provided iteratee\n * to build a function expecting the array to act upon.\n * @example\n * var toCharArray = function (s) { return s.split(\"\"); };\n * var wordsToCharArray = _.flatMapWith(toCharArray);\n *\n * wordsToCharArray([\"foo\", \"bar\"]) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatMap|flatMap}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.11.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var flatMapWith = _curry2(flatMap, true);\n\n /**\n * Flattens an array.\n * @private\n * @param {Array} array - The source array\n * @param {Boolean} isDeep - Whether to perform a deep flattening or not\n * @param {Array} output - An array to collect the result\n * @param {Number} idx - The next index to be filled in the output\n * @returns {Array} The output array filled with the results\n */\n function _flatten (array, isDeep, output, idx) {\n for (var i = 0, len = array.length, value, j, vLen; i < len; i++) {\n value = array[i];\n\n if (!Array.isArray(value)) {\n output[idx++] = value;\n } else if (isDeep) {\n _flatten(value, true, output, idx);\n idx = output.length;\n } else {\n vLen = value.length;\n output.length += vLen;\n\n for (j = 0; j < vLen; j++) {\n output[idx++] = value[j];\n }\n }\n }\n\n return output;\n }\n\n /**\n * Helper to build the {@link module:lamb.flatten|flatten} and\n * {@link module:lamb.shallowFlatten|shallowFlatten} functions.\n * @private\n * @function\n * @param {Boolean} isDeep\n * @returns {Function}\n */\n var _makeArrayFlattener = _curry2(function (isDeep, array) {\n return Array.isArray(array) ? _flatten(array, isDeep, [], 0) : slice(array, 0, array.length);\n });\n\n /**\n * Flattens an array.\n * @example Showing the difference with shallowFlatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.shallowFlatten|shallowFlatten}\n * @since 0.1.0\n * @param {Array} array\n * @returns {Array}\n */\n var flatten = _makeArrayFlattener(true);\n\n /**\n * Checks if the given number, even negative, represents an array-like index\n * within the provided length. If so returns its natural number equivalent.
\n * Returns NaN otherwise.\n * @private\n * @param {Number} idx\n * @param {Number} len\n * @returns {Number}\n */\n function _toNaturalIndex (idx, len) {\n idx = _toInteger(idx);\n\n return idx >= -len && idx < len ? idx < 0 ? idx + len : idx : NaN;\n }\n\n /**\n * Retrieves the element at the given index in an array-like object.
\n * Like {@link module:lamb.slice|slice} the index can be negative.
\n * If the index isn't supplied, or if its value isn't an integer within the array-like bounds,\n * the function will return undefined.
\n * getIndex will throw an exception when receives null or\n * undefined in place of an array-like object, but returns undefined\n * for any other value.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.getIndex(arr, 1) // => 2\n * _.getIndex(arr, -1) // => 5\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.getAt|getAt}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @returns {*}\n */\n function getIndex (arrayLike, index) {\n var idx = _toNaturalIndex(index, _toArrayLength(arrayLike.length));\n\n return idx === idx ? arrayLike[idx] : void 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * A curried version of {@link module:lamb.getIndex|getIndex} that uses the provided index\n * to build a function expecting the array-like object holding the element we want to retrieve.\n * @example\n * var getFifthElement = _.getAt(4);\n *\n * getFifthElement([1, 2, 3, 4, 5]) // => 5\n * getFifthElement(\"foo bar\") // => \"b\"\n * getFifthElement([]) // => undefined\n * getFifthElement(\"foo\") // => undefined\n *\n * @example Using negative indexes:\n * _.getAt(-2)([1, 2, 3]) // => 2\n * _.getAt(-3)(\"foo\") // => \"f\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.16.0\n * @see {@link module:lamb.getIndex|getIndex}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @param {Number} index\n * @returns {Function}\n */\n var getAt = _curry2(getIndex, true);\n\n /**\n * Transforms an array-like object into a lookup table using the provided iteratee as a grouping\n * criterion to generate keys and values.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCity = _.getKey(\"city\");\n * var personsByCity = _.group(persons, getCity);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"undefined\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @example Adding a custom value for missing keys:\n *\n * var getCityOrUnknown = _.adapter([getCity, _.always(\"Unknown\")]);\n *\n * var personsByCity = _.group(persons, getCityOrUnknown);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"Unknown\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var group = _groupWith(function (a, b) {\n if (!a) {\n return [b];\n }\n\n a[a.length] = b;\n\n return a;\n });\n\n /**\n * A curried version of {@link module:lamb.group|group} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 18},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n *\n * var getAgeStatus = function (person) { return person.age > 20 ? \"over 20\" : \"under 20\"; };\n * var groupByAgeStatus = _.groupBy(getAgeStatus);\n *\n * var personsByAgeStatus = groupByAgeStatus(persons);\n *\n * // \"personsByAgeStatus\" holds:\n * // {\n * // \"under 20\": [\n * // {\"name\": \"Jane\", \"age\": 12},\n * // {\"name\": \"Mario\", \"age\": 18},\n * // {\"name\": \"Paolo\", \"age\": 15}\n * // ],\n * // \"over 20\": [\n * // {\"name\": \"John\", \"age\": 40}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.group|group}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var groupBy = _curry2(group, true);\n\n /**\n * Retrieves the first element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.head([1, 2, 3]) // => 1\n * _.head(\"hello\") // => \"h\"\n * _.head([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.last|last}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var head = getAt(0);\n\n /**\n * Similar to {@link module:lamb.group|group}, but the generated lookup table will have\n * only one element of the original array-like object for each value.
\n * Should be used only when you're sure that your iteratee won't produce\n * duplicate keys, otherwise only the last evaluated element will be in the result.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"id\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"},\n * // \"4\": {id: 4, name: \"John\"}\n * // }\n *\n * @example Result of an iteratee producing a duplicate key:\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"name\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"John\": {\"id\": 4, \"name\": \"John\"},\n * // \"Jane\": {\"id\": 2, \"name\": \"Jane\"},\n * // \"Mario\": {\"id\": 3, \"name\": \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.indexBy|indexBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var index = _groupWith(function (a, b) {\n return b;\n });\n\n /**\n * A curried version of {@link module:lamb.index|index} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"}\n * ];\n * var indexByID = _.indexBy(_.getKey(\"id\"));\n *\n * var indexedUsers = indexByID(users);\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.index|index}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var indexBy = _curry2(index, true);\n\n /**\n * Returns a copy of the given array-like object without the last element.\n * @example\n * _.init([1, 2, 3, 4]) // => [1, 2, 3]\n * _.init([1]) // => []\n * _.init([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.tail|tail}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var init = partial(slice, [__, 0, -1]);\n\n /**\n * Inserts the provided element in a copy of an array-like object at the\n * specified index.
\n * If the index is greater than the length of the array-like, the element\n * will be appended at the end.
\n * Negative indexes are allowed; when a negative index is out of bounds\n * the element will be inserted at the start of the resulting array.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insert(arr, 3, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, -2, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, 10, 99) // => [1, 2, 3, 4, 5, 99]\n * _.insert(arr, -10, 99) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.insertAt|insertAt}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} element\n * @returns {Array}\n */\n function insert (arrayLike, index, element) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n result.splice(index, 0, element);\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.insert|insert}\n * expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insertAt(3, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(-2, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(10, 99)(arr) // => [1, 2, 3, 4, 5, 99]\n * _.insertAt(-10, 99)(arr) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.insert|insert}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.27.0\n * @param {Number} index\n * @param {*} element\n * @returns {Function}\n */\n var insertAt = _makePartial3(insert);\n\n /**\n * Returns an array of every unique item that is included in all two given arrays\n * or array-like objects.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 5, 4, 2, 6];\n * var a3 = [5, 6, 7];\n *\n * _.intersection(a1, a2) // => [2, 4]\n * _.intersection(a2, a3) // => [5, 6]\n * _.intersection(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n function intersection (a, b) {\n var result = [];\n var lenA = a.length;\n\n if (lenA && b.length) {\n for (var i = 0; i < lenA; i++) {\n !isIn(result, a[i]) && isIn(b, a[i]) && result.push(a[i]);\n }\n }\n\n return result;\n }\n\n /**\n * Transforms an array-like object into a string by joining its elements with\n * the given separator.
\n * Note that unlike the native method, this function won't convert\n * null and undefined values in the array to empty\n * strings and that the separator parameter isn't optional.
\n * See the examples about these differences.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n *\n * _.join(words, \"-\") // => \"foo-bar-baz\"\n *\n * @example Showing the differences with the native array method:\n * var mixed = [1, null, 2, undefined, 3, NaN, 4, 5];\n * var numbers = [1, 2, 3];\n *\n * _.join(mixed, \"-\") // => \"1-null-2-undefined-3-NaN-4-5\"\n * mixed.join(\"-\") // => \"1--2--3-NaN-4-5\"\n *\n * _.join(numbers) // => \"1undefined2undefined3\"\n * numbers.join() // => \"1,2,3\"\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.joinWith|joinWith}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {String} separator\n * @returns {String}\n */\n function join (arrayLike, separator) {\n return map(arrayLike, String).join(String(separator));\n }\n\n /**\n * A curried version of {@link module:lamb.join|join} that accepts an optional\n * separator and builds a function expecting the array-like object to act upon.
\n * Please refer to the description and examples of {@link module:lamb.join|join}\n * to understand the differences with the native array method.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n * var joinWithDash = _.joinWith(\"-\");\n *\n * joinWithDash(words) // => \"foo-bar-baz\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.join|join}\n * @since 0.58.0\n * @param {String} separator\n * @returns {Function}\n */\n var joinWith = _curry2(join, true);\n\n /**\n * Retrieves the last element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.last([1, 2, 3]) // => 3\n * _.last(\"hello\") // => \"o\"\n * _.last([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.head|head}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var last = getAt(-1);\n\n /**\n * Builds helper functions to extract portions of the arguments\n * object rather efficiently without having to write for loops\n * manually for each case.
\n * The arguments object needs to be passed to the apply method\n * of the generated function.\n * @private\n * @param {Number} idx\n * @returns {Function}\n */\n function _argsToArrayFrom (idx) {\n return function () {\n var argsLen = arguments.length || idx;\n var len = argsLen - idx;\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = arguments[i + idx];\n }\n\n return result;\n };\n }\n\n /**\n * Generates an array with the values passed as arguments.
\n * Behaves like ES6's [Array.of]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of}.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.1.0\n * @param {...*} value\n * @returns {Array}\n */\n var list = _argsToArrayFrom(0);\n\n /**\n * Splits an array-like object in two lists: the first with the elements satisfying the given predicate,\n * the others with the remaining elements.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * _.partition(numbers, isEven) // => [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.partitionWith|partitionWith}\n * @since 0.11.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Array}\n */\n function partition (arrayLike, predicate) {\n var result = [[], []];\n var len = arrayLike.length;\n\n for (var i = 0, el; i < len; i++) {\n el = arrayLike[i];\n result[predicate(el, i, arrayLike) ? 0 : 1].push(el);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.partition|partition} that uses the provided\n * predicate to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * ];\n * var isActive = _.hasKeyValue(\"active\", true);\n * var splitByActiveStatus = _.partitionWith(isActive);\n *\n * splitByActiveStatus(users) // =>\n * // [[\n * // {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true}\n * // ], [\n * // {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * // {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * // ]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.partition|partition}\n * @since 0.11.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var partitionWith = _curry2(partition, true);\n\n /**\n * Returns the value of the object property with the given key.\n * @example\n * var user = {name: \"John\"};\n *\n * _.getIn(user, \"name\") // => \"John\";\n * _.getIn(user, \"surname\") // => undefined\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getKey|getKey}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.18.0\n * @param {Object} obj\n * @param {String} key\n * @returns {*}\n */\n function getIn (obj, key) {\n return obj[key];\n }\n\n /**\n * A curried version of {@link module:lamb.getIn|getIn}.
\n * Receives a property name and builds a function expecting the object from which we want to retrieve\n * the property.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {name: \"jane\"};\n * var getName = _.getKey(\"name\");\n *\n * getName(user1) // => \"john\"\n * getName(user2) // => \"jane\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getIn|getIn}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var getKey = _curry2(getIn, true);\n\n /**\n * \"Plucks\" the values of the specified key from a list of objects.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n *\n * _.pluck(persons, \"age\") // => [12, 40, 18, 15]\n *\n * var lists = [\n * [1, 2],\n * [3, 4, 5],\n * [6]\n * ];\n *\n * _.pluck(lists, \"length\") // => [2, 3, 1]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pluckKey|pluckKey}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {String} key\n * @returns {Array}\n */\n function pluck (arrayLike, key) {\n return map(arrayLike, getKey(key));\n }\n\n /**\n * A curried version of {@link module:lamb.pluck|pluck} expecting the key to retrieve to\n * build a function waiting for the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n * var getAges = _.pluckKey(\"age\");\n *\n * getAges(persons) // => [12, 40, 18, 15]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pluck|pluck}\n * @since 0.12.0\n * @param {String} key\n * @returns {Function}\n */\n var pluckKey = compose(mapWith, getKey);\n\n /**\n * Creates an array copy of the given array-like object without the\n * specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.pullFrom(arr, [2, 5]) // => [1, 3, 4]\n *\n * @example It's not the same as {@link module:lamb.difference|difference}:\n *\n * var arr = [1,1,2,3,4,4,5];\n *\n * _.pullFrom(arr, [1, 2]) // => [3, 4, 4, 5]\n * _.difference(arr, [1, 2]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pull|pull}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} values\n * @returns {Array}\n */\n function pullFrom (arrayLike, values) {\n return values ? filter(arrayLike, function (element) {\n return !isIn(values, element);\n }) : slice(arrayLike, 0, arrayLike.length);\n }\n\n /**\n * A curried version of {@link module:lamb.pullFrom|pullFrom} expecting\n * a list of values to build a function waiting for an array-like object.
\n * The new function will create an array copy of the array-like without\n * the specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * See examples in {@link module:lamb.pullFrom|pullFrom} about the\n * relationship with {@link module:lamb.difference|difference}.\n * @example\n * var scores = [40, 20, 30, 10];\n * var newScores = [30, 10];\n * var pullNewScores = _.pull(newScores);\n *\n * pullNewScores(scores) // => [40, 20]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pullFrom|pullFrom}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} values\n * @returns {Function}\n */\n var pull = _curry2(pullFrom, true);\n\n /**\n * Same as {@link module:lamb.reduce|reduce}, but starts the fold operation from the last\n * element instead.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduce|reduce}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduceRight = _makeReducer(-1);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduceRight} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceRightWith(_.sum)(arr) // => 15\n * _.reduceRightWith(_.subtract)(arr) // => -5\n * _.reduceRightWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceWith|reduceWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceRightWith = _makePartial3(reduceRight, true);\n\n /**\n * Reverses a copy of the given array-like object.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.reverse(arr) // => [3, 2, 1];\n *\n * // `arr` still is [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.19.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function reverse (arrayLike) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0, ofs = len - 1; i < len; i++) {\n result[i] = arrayLike[ofs - i];\n }\n\n return result;\n }\n\n /**\n * Returns a copy of the given array-like with the element rotated by the desired amount.\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.rotate(arr, 3) // => [3, 4, 5, 1, 2]\n * _.rotate(arr, -3) // => [4, 5, 1, 2, 3]\n * _.rotate(arr, 11) // => [5, 1, 2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.rotateBy|rotateBy}\n * @since 0.55.0\n * @param {ArrayLike} arrayLike\n * @param {Number} amount\n * @returns {Array}\n */\n function rotate (arrayLike, amount) {\n var len = arrayLike.length;\n var shift = amount % len;\n\n return slice(arrayLike, -shift, len).concat(slice(arrayLike, 0, -shift));\n }\n\n /**\n * A curried version of {@link module:lamb.rotate|rotate}.
\n * Uses the given amount to build a function expecting the array to rotate by that amount.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var rotateByTwo = _.rotateBy(2);\n *\n * rotateByTwo(arr) // => [4, 5, 1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.rotate|rotate}\n * @since 0.55.0\n * @param {Number} amount\n * @returns {Function}\n */\n var rotateBy = _curry2(rotate, true);\n\n /**\n * Sets an index in an array-like object.
\n * If provided with an updater function it will use it to update the current value,\n * otherwise sets the index to the specified value.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {Number} idx\n * @param {*} [value]\n * @param {Function} [updater]\n * @returns {Array}\n */\n function _setIndex (arrayLike, idx, value, updater) {\n var result = slice(arrayLike, 0, arrayLike.length);\n var n = _toNaturalIndex(idx, result.length);\n\n if (n === n) { // eslint-disable-line no-self-compare\n result[n] = arguments.length === 4 ? updater(arrayLike[n]) : value;\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.setIndex|setIndex} that builds\n * a function that creates a copy of an array-like object with the given\n * index changed to the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.setAt(2, 99)(arr) // => [1, 2, 99, 4, 5]\n * arr // => [1, 2, 3, 4, 5]\n *\n * _.setAt(10, 99)(arr) // => [1, 2, 3, 4, 5] (not a reference to `arr`)\n *\n * @example Using negative indexes:\n * _.setAt(-1, 99)(arr) // => [1, 2, 3, 4, 99]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setIndex|setIndex}\n * @since 0.17.0\n * @param {Number} index\n * @param {*} value\n * @returns {Function}\n */\n var setAt = _makePartial3(_setIndex);\n\n /**\n * Builds a new function that passes only the specified amount of arguments to the original one.
\n * As {@link module:lamb.slice|slice} is used to extract the arguments, you can also\n * pass a negative arity.\n * @example\n * Math.max(10, 11, 45, 99) // => 99\n * _.aritize(Math.max, 2)(10, 11, 45, 99) // => 11\n *\n * @example Using a negative arity:\n * _.aritize(Math.max, -1)(10, 11, 45, 99) // => 45\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.binary|binary}, {@link module:lamb.unary|unary} for common use cases shortcuts\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} arity\n * @returns {Function}\n */\n function aritize (fn, arity) {\n return function () {\n var n = _toInteger(arity);\n var args = list.apply(null, arguments).slice(0, n);\n\n for (var i = args.length; i < n; i++) {\n args[i] = void 0;\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed to\n * the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.setIndex(arr, 1, 99) // => [1, 99, 3]\n * _.setIndex(arr, -1, 99) // => [1, 2, 99]\n * _.setIndex(arr, 10, 99) // => [1, 2, 3] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setAt|setAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} value\n * @returns {Array}\n */\n var setIndex = aritize(_setIndex, 3);\n\n /**\n * Flattens the \"first level\" of an array.\n * @example Showing the difference with flatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatten|flatten}\n * @since 0.9.0\n * @param {Array} array\n * @returns {Array}\n */\n var shallowFlatten = _makeArrayFlattener(false);\n\n /**\n * Checks if at least one element in an array-like object satisfies the given predicate.
\n * The function will stop calling the predicate as soon as it returns a truthy value.
\n * Note that unlike the native\n * [Array.prototype.some]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: false},\n * {\"name\": \"John\", \"age\": 40, active: false},\n * {\"name\": \"Mario\", \"age\": 17, active: false},\n * {\"name\": \"Paolo\", \"age\": 15, active: false}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.someIn(persons, isAdult) // => true\n * _.someIn(persons, isActive) // => false\n *\n * @example Showing the difference with Array.prototype.some:\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.some(_.isUndefined) // => false\n * _.someIn(arr, _.isUndefined) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.some|some}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var someIn = _makeArrayChecker(false);\n\n /**\n * A curried version of {@link module:lamb.someIn|someIn} that uses the given predicate to\n * build a function waiting for the array-like to act upon.\n * @example\n * var data = [1, 3, 5, 6, 7, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var containsEvens = _.some(isEven);\n * var containsStrings = _.some(_.isType(\"String\"));\n *\n * containsEvens(data) // => true\n * containsStrings(data) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.someIn|someIn}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var some = _curry2(someIn, true);\n\n /**\n * Accepts a list of sorting criteria with at least one element\n * and builds a function that compares two values with such criteria.\n * @private\n * @param {Sorter[]} criteria\n * @returns {Function}\n */\n function _compareWith (criteria) {\n return function (a, b) {\n var len = criteria.length;\n var criterion = criteria[0];\n var result = criterion.compare(a.value, b.value);\n\n for (var i = 1; result === 0 && i < len; i++) {\n criterion = criteria[i];\n result = criterion.compare(a.value, b.value);\n }\n\n if (result === 0) {\n result = a.index - b.index;\n }\n\n return criterion.isDescending ? -result : result;\n };\n }\n\n /**\n * The default comparer for sorting functions.
\n * If the given values are of different types they\n * will be both converted to strings.
\n * Uses the SameValueZero comparison.\n * @private\n * @param {*} a\n * @param {*} b\n * @returns {Number} -1 | 0 | 1\n */\n function _comparer (a, b) {\n var result = 0;\n\n if (typeof a !== typeof b) {\n a = String(a);\n b = String(b);\n }\n\n if (!areSVZ(a, b)) {\n // eslint-disable-next-line no-self-compare\n result = a > b || a !== a ? 1 : -1;\n }\n\n return result;\n }\n\n /**\n * Builds a sorting criterion. If the comparer function is missing, the default\n * comparer will be used instead.\n * @private\n * @param {Function} reader\n * @param {Boolean} isDescending\n * @param {Function} [comparer]\n * @returns {Sorter}\n */\n function _sorter (reader, isDescending, comparer) {\n if (typeof reader !== \"function\" || reader === identity) {\n reader = null;\n }\n\n if (typeof comparer !== \"function\") {\n comparer = _comparer;\n }\n\n return {\n isDescending: isDescending === true,\n compare: function (a, b) {\n if (reader) {\n a = reader(a);\n b = reader(b);\n }\n\n return comparer(a, b);\n }\n };\n }\n\n /**\n * Converts a sorting function to a sorting criterion if necessary.\n * @private\n * @param {Function} criterion\n * @returns {Sorter}\n */\n function _makeCriterion (criterion) {\n return criterion && typeof criterion.compare === \"function\" ? criterion : _sorter(criterion);\n }\n\n /**\n * Builds a list of sorting criteria from a list of sorter functions. Returns a list containing\n * a single default sorting criterion if the sorter list is empty.\n * @private\n * @param {Function[]} sorters\n * @returns {Sorter[]}\n */\n function _makeCriteria (sorters) {\n return sorters && sorters.length ? map(sorters, _makeCriterion) : [_sorter()];\n }\n\n /**\n * Returns a [stably]{@link https://en.wikipedia.org/wiki/Sorting_algorithm#Stability} sorted\n * copy of an array-like object using the given criteria.
\n * Sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you\n * can also pass simple \"reader\" functions and default ascending sorters will be built for you.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used\n * in the comparison.
\n * Please note that if the arguments received by the default comparer aren't of the same type,\n * they will be compared as strings.\n *\n * @example Stable sort:\n * var persons = [\n * {\"name\": \"John\", \"surname\" :\"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"},\n * {\"name\": \"John\", \"surname\" :\"Moe\"},\n * {\"name\": \"Jane\", \"surname\": \"Foe\"}\n * ];\n *\n * var personsByName = _.sort(persons, [_.getKey(\"name\")]);\n *\n * // personsByName holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Stable multi-sort:\n * var personsByNameAscSurnameDesc = _.sort(persons, [\n * _.getKey(\"name\"),\n * _.sorterDesc(_.getKey(\"surname\"))\n * ]);\n *\n * // personsByNameAscSurnameDesc holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Using custom comparers:\n * var localeSorter = new Intl.Collator(\"it\");\n * var chars = [\"a\", \"è\", \"à\", \"é\", \"c\", \"b\", \"e\"];\n *\n * _.sort(chars, [localeSorter]) // => [\"a\", \"à\", \"b\", \"c\", \"e\", \"é\", \"è\"]\n *\n * var localeSorterDesc = _.sorterDesc(_.identity, localeSorter.compare);\n *\n * _.sort(chars, [localeSorterDesc]) // => [\"è\", \"é\", \"e\", \"c\", \"b\", \"à\", \"a\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {ArrayLike} arrayLike\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Array}\n */\n function sort (arrayLike, sorters) {\n var criteria = _makeCriteria(sorters);\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = { value: arrayLike[i], index: i };\n }\n\n result.sort(_compareWith(criteria));\n\n for (i = 0; i < len; i++) {\n result[i] = result[i].value;\n }\n\n return result;\n }\n\n /**\n * Establishes at which index an element should be inserted in a sorted array to respect\n * the array order. Needs the comparer used to sort the array.\n * @private\n * @param {Array} array\n * @param {*} element\n * @param {Function} comparer\n * @param {Number} start\n * @param {Number} end\n * @returns {Number}\n */\n function _getInsertionIndex (array, element, comparer, start, end) {\n if (array.length === 0) {\n return 0;\n }\n\n var pivot = (start + end) >> 1;\n var result = comparer(\n { value: element, index: pivot },\n { value: array[pivot], index: pivot }\n );\n\n if (end - start <= 1) {\n return result < 0 ? pivot : pivot + 1;\n } else if (result < 0) {\n return _getInsertionIndex(array, element, comparer, start, pivot);\n } else if (result === 0) {\n return pivot + 1;\n } else {\n return _getInsertionIndex(array, element, comparer, pivot, end);\n }\n }\n\n /**\n * Inserts an element in a copy of a sorted array respecting the sort order.\n * @example With simple values:\n * _.sortedInsert([], 1) // => [1]\n * _.sortedInsert([2, 4, 6], 5) // => [2, 4, 5, 6]\n * _.sortedInsert([4, 2, 1], 3, _.sorterDesc()) // => [4, 3, 2, 1]\n *\n * @example With complex values:\n * var persons = [\n * {\"name\": \"jane\", \"surname\": \"doe\"},\n * {\"name\": \"John\", \"surname\": \"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * ];\n *\n * var getLowerCaseName = _.compose(\n * _.invoker(\"toLowerCase\"),\n * _.getKey(\"name\")\n * );\n *\n * var result = _.sortedInsert(\n * persons,\n * {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * getLowerCaseName\n * );\n *\n * // `result` holds:\n * // [\n * // {\"name\": \"jane\", \"surname\": \"doe\"},\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt} to insert the element\n * at a specific index\n * @since 0.27.0\n * @param {ArrayLike} arrayLike\n * @param {*} element\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]] - The sorting criteria\n * used to sort the array.\n * @returns {Array}\n */\n function sortedInsert (arrayLike, element, sorters) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n if (arguments.length === 1) {\n return result;\n }\n\n var criteria = _makeCriteria(sorters);\n var idx = _getInsertionIndex(result, element, _compareWith(criteria), 0, result.length);\n\n result.splice(idx, 0, element);\n\n return result;\n }\n\n /**\n * Creates an ascending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.1.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorter = partial(_sorter, [__, false, __]);\n\n /**\n * Creates a descending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}\n * @since 0.15.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorterDesc = partial(_sorter, [__, true, __]);\n\n /**\n * Builds a partial application of {@link module:lamb.sort|sort} using the provided criteria.\n * The returned function expects the array-like object to sort.\n * As usual, sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function,\n * but you can also pass simple \"reader\" functions and default ascending sorters will be built.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used in\n * the comparison.
\n * See {@link module:lamb.sort|sort} for more examples.\n *\n * @example\n * var sortAsNumbers = _.sortWith([parseFloat]);\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * sortAsNumbers(weights) // => [\"1 Kg\", \"2 Kg\", \"7 Kg\", \"10 Kg\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sort|sort}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Function}\n */\n var sortWith = _curry2(sort, true);\n\n /**\n * Returns a copy of the given array-like object without the first element.\n * @example\n * _.tail([1, 2, 3, 4]) // => [2, 3, 4]\n * _.tail([1]) // => []\n * _.tail([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.init|init}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var tail = drop(1);\n\n /**\n * Retrieves the first n elements from an array or array-like object.
\n * Note that, being this a shortcut for a common use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.takeFrom(arr, 3) // => [1, 2, 3]\n * _.takeFrom(arr, -1) // => [1, 2, 3, 4]\n * _.takeFrom(arr, -10) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function takeFrom (arrayLike, n) {\n return slice(arrayLike, 0, n);\n }\n\n /**\n * A curried version of {@link module:lamb.takeFrom|takeFrom} that expects the number of elements\n * to retrieve to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.takeFrom|takeFrom} about passing a\n * negative n.\n * @example\n * var take2 = _.take(2);\n *\n * take2([1, 2, 3, 4, 5]) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeFrom|takeFrom}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @since 0.5.0\n * @param {Number} n\n * @returns {Function}\n */\n var take = _curry2(takeFrom, true);\n\n /**\n * Builds a function that takes the first n elements satisfying a predicate from\n * an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeWhileIsEven = _.takeWhile(isEven);\n *\n * takeWhileIsEven([1, 2, 4, 6, 8]) // => []\n * takeWhileIsEven([2, 4, 7, 8]) // => [2, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n function takeWhile (predicate) {\n return function (arrayLike) {\n return slice(arrayLike, 0, _getNumConsecutiveHits(arrayLike, predicate));\n };\n }\n\n /**\n * Transposes a matrix. Can also be used to reverse a {@link module:lamb.zip|zip} operation.
\n * Just like {@link module:lamb.zip|zip}, the received array-like objects will be truncated to the\n * shortest length.\n * @example Transposing a matrix:\n * _.transpose([\n * [1, 2, 3],\n * [4, 5, 6],\n * [7, 8, 9]\n * ]) // =>\n * // [\n * // [1, 4, 7],\n * // [2, 5, 8],\n * // [3, 6, 9]\n * // ]\n *\n * @example Showing the relationship with zip:\n * var zipped = _.zip([\"a\", \"b\", \"c\"], [1, 2, 3]); // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.transpose(zipped) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function transpose (arrayLike) {\n var minLen = MAX_ARRAY_LENGTH;\n var len = _toArrayLength(arrayLike.length);\n\n if (len === 0) {\n return [];\n }\n\n for (var j = 0, elementLen; j < len; j++) {\n elementLen = _toArrayLength(arrayLike[j].length);\n\n if (elementLen < minLen) {\n minLen = elementLen;\n }\n }\n\n var result = Array(minLen);\n\n for (var i = 0, el; i < minLen; i++) {\n el = result[i] = Array(len);\n\n for (j = 0; j < len; j++) {\n el[j] = arrayLike[j][i];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a TypeError stating that it's not possible to convert the given value to the\n * desired type.\n * @private\n * @param {*} value\n * @param {String} desiredType\n * @returns {TypeError}\n */\n function _makeTypeErrorFor (value, desiredType) {\n return new TypeError(\"Cannot convert \" + type(value).toLowerCase() + \" to \" + desiredType);\n }\n\n /**\n * Creates a pipeline of functions, where each function consumes the result of the previous one.\n * @example\n * var __ = _.__;\n * var square = _.partial(Math.pow, [__, 2]);\n * var getMaxAndSquare = _.pipe([Math.max, square]);\n *\n * getMaxAndSquare(3, 5) // => 25\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.compose|compose}\n * @since 0.1.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function pipe (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n var len = functions.length;\n\n return len ? function () {\n var result = functions[0].apply(this, arguments);\n\n for (var i = 1; i < len; i++) {\n result = functions[i].call(this, result);\n }\n\n return result;\n } : identity;\n }\n\n /**\n * Using the provided iteratee to transform values, builds a function that will\n * return an array of the unique elements in the two provided array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.union|union} if you don't need to compare transformed values.\n * @example\n * var unionByFloor = _.unionBy(Math.floor);\n *\n * unionByFloor([2.8, 3.2, 1.5], [3.5, 1.2, 4]) // => [2.8, 3.2, 1.5, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.union|union}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function unionBy (iteratee) {\n return pipe([binary(list), flatMapWith(drop(0)), uniquesBy(iteratee)]);\n }\n\n /**\n * Returns a list of every unique element present in the two given array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.unionBy|unionBy} if you need to transform the values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.union([1, 2, 3, 2], [2, 3, 4]) // => [1, 2, 3, 4]\n * _.union(\"abc\", \"bcd\") // => [\"a\", \"b\", \"c\", \"d\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n var union = unionBy(identity);\n\n /**\n * Builds a function that creates a copy of an array-like object with the given index\n * changed by applying the provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateAt(1, toUpperCase)(arr) // => [\"a\", \"B\", \"c\"]\n * _.updateAt(-1, toUpperCase)(arr) // => [\"a\", \"b\", \"C\"]\n * _.updateAt(10, toUpperCase)(arr) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.updateIndex|updateIndex}\n * @since 0.22.0\n * @param {Number} index\n * @param {Function} updater\n * @returns {Function}\n */\n function updateAt (index, updater) {\n return function (arrayLike) {\n return _setIndex(arrayLike, index, null, updater);\n };\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed by applying the\n * provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIndex(arr, 1, toUpperCase) // => [\"a\", \"B\", \"c\"]\n * _.updateIndex(arr, -1, toUpperCase) // => [\"a\", \"b\", \"C\"]\n * _.updateIndex(arr, 10, toUpperCase) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.updateAt|updateAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {Function} updater\n * @returns {Array}\n */\n var updateIndex = partial(_setIndex, [__, __, null, __]);\n\n /**\n * Builds a list of arrays out of the two given array-like objects by pairing items with\n * the same index.
\n * The received array-like objects will be truncated to the shortest length.\n * @example\n * _.zip(\n * [\"a\", \"b\", \"c\"],\n * [1, 2, 3]\n * ) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.zip([1, 2, 3, 4], [5, 6, 7]) // => [[1, 5], [2, 6], [3, 7]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.transpose|transpose} for the reverse operation\n * @see {@link module:lamb.zipWithIndex|zipWithIndex}\n * @since 0.14.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n function zip (a, b) {\n return transpose([a, b]);\n }\n\n /**\n * \"{@link module:lamb.zip|Zips}\" an array-like object by pairing its values with their index.\n * @example\n * _.zipWithIndex([\"a\", \"b\", \"c\"]) // => [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array>}\n */\n var zipWithIndex = mapWith(binary(list));\n\n /**\n * Applies the given function to a list of arguments.\n * @example\n * _.application(_.sum, [3, 4]) // => 7\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.apply|apply}, {@link module:lamb.applyTo|applyTo}\n * @since 0.47.0\n * @param {Function} fn\n * @param {ArrayLike} args\n * @returns {*}\n */\n function application (fn, args) {\n return fn.apply(this, Object(args));\n }\n\n /**\n * A left-curried version of {@link module:lamb.application|application}. Expects the function\n * to apply and builds a function waiting for the arguments array.\n * @example\n * var arrayMax = _.apply(Math.max);\n *\n * arrayMax([4, 5, 2, 6, 1]) // => 6\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.applyTo|applyTo}\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n var apply = _curry2(application);\n\n /**\n * A right-curried version of {@link module:lamb.application|application}. Expects an array-like\n * object to use as arguments and builds a function waiting for the target of the application.\n * @example\n * var data = [3, 4];\n * var applyToData = _.applyTo(data);\n *\n * applyToData(_.sum) // => 7\n * applyToData(_.multiply) // => 12\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.apply|apply}\n * @since 0.47.0\n * @param {ArrayLike} args\n * @returns {Function}\n */\n var applyTo = _curry2(application, true);\n\n /**\n * Keeps building a partial application of the received function as long\n * as it's called with placeholders; applies the original function to\n * the collected parameters otherwise.
\n * The function checks only the public placeholder to gain a little performance\n * as no function in Lamb is built with {@link module:lamb.asPartial|asPartial}.\n * @private\n * @param {Function} fn\n * @param {Array} argsHolder\n * @returns {Function|*}\n */\n function _asPartial (fn, argsHolder) {\n return function () {\n var argsLen = arguments.length;\n var lastIdx = 0;\n var newArgs = [];\n\n for (var i = 0, len = argsHolder.length, boundArg; i < len; i++) {\n boundArg = argsHolder[i];\n newArgs[i] = boundArg === __ && lastIdx < argsLen ? arguments[lastIdx++] : boundArg;\n }\n\n while (lastIdx < argsLen) {\n newArgs[i++] = arguments[lastIdx++];\n }\n\n for (i = 0; i < argsLen; i++) {\n if (arguments[i] === __) {\n return _asPartial(fn, newArgs);\n }\n }\n\n for (i = 0, len = newArgs.length; i < len; i++) {\n if (newArgs[i] === __) {\n newArgs[i] = void 0;\n }\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Decorates the received function so that it can be called with\n * placeholders to build a partial application of it.
\n * The difference with {@link module:lamb.partial|partial} is that, as long as\n * you call the generated function with placeholders, another partial application\n * of the original function will be built.
\n * The final application will happen when one of the generated functions is\n * invoked without placeholders, using the parameters collected so far.
\n * This function comes in handy when you need to build different specialized\n * functions starting from a basic one, but it's also useful when dealing with\n * optional parameters as you can decide to apply the function even if its arity\n * hasn't been entirely consumed.\n * @example Explaining the function's behaviour:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + c;\n * });\n *\n * f(4, 3, 2) // => 9\n * f(4, __, 2)(3) // => 9\n * f(__, 3, __)(4, __)(2) // => 9\n *\n * @example Exploiting optional parameters:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + (c || 0);\n * });\n *\n * var addFive = f(5, __);\n * addFive(2) // => 7\n *\n * var addNine = addFive(4, __);\n * addNine(11) // => 20\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.36.0\n * @param {Function} fn\n * @returns {Function}\n */\n function asPartial (fn) {\n return _asPartial(fn, []);\n }\n\n /**\n * Accepts a series of functions and builds a new function. The functions in the series\n * will then be applied, in order, with the values received by the function built with\n * collect.
\n * The collected results will be returned in an array.\n * @example\n * var user = {\n * id: \"jdoe\",\n * name: \"John\",\n * surname: \"Doe\",\n * scores: [2, 4, 7]\n * };\n * var getIDAndLastScore = _.collect([_.getKey(\"id\"), _.getPath(\"scores.-1\")]);\n *\n * getIDAndLastScore(user) // => [\"jdoe\", 7]\n *\n * @example\n * var minAndMax = _.collect([Math.min, Math.max]);\n *\n * minAndMax(3, 1, -2, 5, 4, -1) // => [-2, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.35.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function collect (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n return map(functions, applyTo(arguments));\n };\n }\n\n /**\n * Used by curry functions to collect arguments until the arity is consumed,\n * then applies the original function.\n * @private\n * @param {Function} fn\n * @param {Number} arity\n * @param {Boolean} isRightCurry\n * @param {Boolean} isAutoCurry\n * @param {Array} argsHolder\n * @returns {Function}\n */\n function _currier (fn, arity, isRightCurry, isAutoCurry, argsHolder) {\n return function () {\n var holderLen = argsHolder.length;\n var argsLen = arguments.length;\n var newArgsLen = holderLen + (argsLen > 1 && isAutoCurry ? argsLen : 1);\n var newArgs = Array(newArgsLen);\n\n for (var i = 0; i < holderLen; i++) {\n newArgs[i] = argsHolder[i];\n }\n\n for (; i < newArgsLen; i++) {\n newArgs[i] = arguments[i - holderLen];\n }\n\n if (newArgsLen >= arity) {\n return fn.apply(this, isRightCurry ? newArgs.reverse() : newArgs);\n } else {\n return _currier(fn, arity, isRightCurry, isAutoCurry, newArgs);\n }\n };\n }\n\n /**\n * Curries a function of arity 3.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry3 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return function (c) {\n return isRightCurry ? fn.call(this, c, b, a) : fn.call(this, a, b, c);\n };\n };\n };\n }\n\n /**\n * Prepares a function for currying. If it's not auto-currying and the arity\n * is 2 or 3 returns optimized functions, otherwise delegates the currying\n * to the _currier function.
\n * If the desumed arity isn't greater than one, it will return the received\n * function itself, instead.\n * @private\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @param {Boolean} [isRightCurry=false]\n * @param {Boolean} [isAutoCurry=false]\n * @returns {Function}\n */\n function _curry (fn, arity, isRightCurry, isAutoCurry) {\n if (arity >>> 0 !== arity) {\n arity = fn.length;\n }\n\n if (isAutoCurry && arity > 1 || arity > 3) {\n return _currier(fn, arity, isRightCurry, isAutoCurry, []);\n } else if (arity === 2) {\n return _curry2(fn, isRightCurry);\n } else if (arity === 3) {\n return _curry3(fn, isRightCurry);\n } else {\n return fn;\n }\n }\n\n /**\n * Transforms the evaluation of the given function in the evaluation of a sequence of functions\n * expecting only one argument. Each function of the sequence is a partial application of the\n * original one, which will be applied when the specified (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryRight|curryRight}\n * for right currying.\n * @example\n * var makeWithKeys = _.curry(_.make);\n * var makePerson = makeWithKeys([\"name\", \"surname\"]);\n *\n * makePerson([\"John\", \"Doe\"]) // => {name: \"John\", surname: \"Doe\"};\n * makePerson([\"Mario\", \"Rossi\"]) // => {name: \"Mario\", surname: \"Rossi\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curry (fn, arity) {\n return _curry(fn, arity, false);\n }\n\n /**\n * Builds an auto-curried function. The resulting function can be called multiple times with\n * any number of arguments, and the original function will be applied only when the specified\n * (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryableRight|curryableRight}\n * for right currying.\n * @example\n * var collectFourElements = _.curryable(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2)(3, 4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3, 4, 5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3)(4, 5) // => [2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.6.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryable (fn, arity) {\n return _curry(fn, arity, false, true);\n }\n\n /**\n * Same as {@link module:lamb.curryable|curryable}, but currying starts from the rightmost argument.\n * @example\n * var collectFourElements = _.curryableRight(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2)(3, 4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3, 4, 5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3)(4, 5) // => [5, 4, 3, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryable|curryable}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryableRight (fn, arity) {\n return _curry(fn, arity, true, true);\n }\n\n /**\n * Same as {@link module:lamb.curry|curry}, but currying starts from the rightmost argument.\n * @example\n * var makeWithValues = _.curryRight(_.make);\n * var makeJohnDoe = makeWithValues([\"John\", \"Doe\"]);\n *\n * makeJohnDoe([\"name\", \"surname\"]) // => {name: \"John\", surname: \"Doe\"};\n * makeJohnDoe([\"firstName\", \"lastName\"]) // => {firstName: \"John\", lastName: \"Doe\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curry|curry}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryRight (fn, arity) {\n return _curry(fn, arity, true);\n }\n\n /**\n * Returns a function that will execute the given function only if it stops being called for the\n * specified timespan.
\n * See also {@link module:lamb.throttle|throttle} for a different behaviour where the first call\n * happens immediately.\n * @example A common use case of debounce in a browser environment:\n * var updateLayout = function () {\n * // some heavy DOM operations here\n * };\n *\n * window.addEventListener(\"resize\", _.debounce(updateLayout, 200), false);\n *\n * // The resize event is fired repeteadly until the user stops resizing the\n * // window, while the `updateLayout` function is called only once: 200 ms\n * // after he stopped.\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.throttle|throttle}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds\n * @returns {Function}\n */\n function debounce (fn, timespan) {\n var timeoutID;\n\n return function () {\n var args = arguments;\n var debounced = function () {\n timeoutID = null;\n fn.apply(this, args);\n }.bind(this);\n\n clearTimeout(timeoutID);\n timeoutID = setTimeout(debounced, timespan);\n };\n }\n\n /**\n * Returns a function that applies the original function with the arguments in reverse order.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n * _.flip(_.list)(1, 2, 3) // => [3, 2, 1]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n function flip (fn) {\n return function () {\n var args = list.apply(null, arguments).reverse();\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Builds a function that returns the argument received at the given index.
\n * As with {@link module:lamb.getAt|getAt} negative indexes are allowed.
\n * The resulting function will return undefined if no arguments are\n * passed or if the index is out of bounds.\n * @example\n * var getFirstArg = _.getArgAt(0);\n * var getLastArg = _.getArgAt(-1);\n *\n * getFirstArg(1, 2, 3) // => 1\n * getLastArg(1, 2, 3) // => 3\n *\n * _.getArgAt()(1, 2, 3) // => undefined\n * _.getArgAt(6)(1, 2, 3) // => undefined\n * _.getArgAt(1)() // => undefined\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.17.0\n * @param {Number} idx\n * @returns {Function}\n */\n function getArgAt (idx) {\n return function () {\n return arguments[_toNaturalIndex(idx, arguments.length)];\n };\n }\n\n /**\n * Builds an array with the received arguments excluding the first one.
\n * To be used with the arguments object, which needs to be passed to the apply\n * method of this function.\n * @private\n * @function\n * @param {...*} value\n * @returns {Array}\n */\n var _argsTail = _argsToArrayFrom(1);\n\n /**\n * If a method with the given name exists on the target, applies it to the provided\n * arguments and returns the result. Returns undefined otherwise.
\n * The arguments for the method are built by concatenating the array of bound arguments,\n * optionally received by {@link module:lamb.invoker|invoker}, with the final set of, also\n * optional, args.\n * @private\n * @param {Array} boundArgs\n * @param {String} methodName\n * @param {Object} target\n * @param {...*} [args]\n * @returns {*}\n */\n function _invoker (boundArgs, methodName, target) {\n var method = target[methodName];\n\n if (typeof method !== \"function\") {\n return void 0;\n }\n\n var boundArgsLen = boundArgs.length;\n var ofs = 3 - boundArgsLen;\n var len = arguments.length - ofs;\n var args = Array(len);\n\n for (var i = 0; i < boundArgsLen; i++) {\n args[i] = boundArgs[i];\n }\n\n for (; i < len; i++) {\n args[i] = arguments[i + ofs];\n }\n\n return method.apply(target, args);\n }\n\n /**\n * Builds a function that will invoke the given method name on any received object and\n * return the result. If no method with such name is found the function will return\n * undefined.
\n * Along with the method name it's possible to supply some arguments that will be bound to the\n * method call. Further arguments can also be passed when the function is actually called, and\n * they will be concatenated to the bound ones.
\n * Returning undefined is a behaviour meant to quickly create a case for\n * {@link module:lamb.adapter|adapter} without the need to check for the existence of the\n * desired method.
\n * See also {@link module:lamb.generic|generic} to create functions out of object methods.\n * @example Basic polymorphism with invoker:\n * var polySlice = _.invoker(\"slice\");\n *\n * polySlice([1, 2, 3, 4, 5], 1, 3) // => [2, 3]\n * polySlice(\"Hello world\", 1, 3) // => \"el\"\n *\n * @example With bound arguments:\n * var substrFrom2 = _.invoker(\"substr\", 2);\n * substrFrom2(\"Hello world\") // => \"llo world\"\n * substrFrom2(\"Hello world\", 5) // => \"llo w\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invokerOn|invokerOn}\n * @since 0.1.0\n * @param {String} methodName\n * @param {...*} [boundArg]\n * @returns {Function}\n */\n function invoker (methodName) {\n return partial(_invoker, [_argsTail.apply(null, arguments), methodName]);\n }\n\n /**\n * Accepts an object and builds a function expecting a method name, and optionally arguments,\n * to call on such object.\n * Like {@link module:lamb.invoker|invoker}, if no method with the given name is found the\n * function will return undefined.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var arr = [1, 2, 3, 4, 5];\n * var invokerOnArr = _.invokerOn(arr);\n *\n * invokerOnArr(\"filter\", isEven) // => [2, 4]\n * invokerOnArr(\"slice\", 1, 3) // => [2, 3]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.15.0\n * @param {Object} target\n * @returns {Function}\n */\n function invokerOn (target) {\n return partial(_invoker, [[], __, target]);\n }\n\n /**\n * Builds a function that allows to map over the received arguments before applying them\n * to the original one.\n * @example\n * var __ = _.__;\n * var sumArray = _.reduceWith(_.sum);\n * var sumArgs = _.compose(sumArray, _.list);\n *\n * sumArgs(1, 2, 3, 4, 5) // => 15\n *\n * var square = _.partial(Math.pow, [__, 2]);\n * var sumSquares = _.mapArgs(sumArgs, square);\n *\n * sumSquares(1, 2, 3, 4, 5) // => 55\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.tapArgs|tapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {ListIteratorCallback} mapper\n * @returns {Function}\n */\n function mapArgs (fn, mapper) {\n return pipe([list, mapWith(mapper), apply(fn)]);\n }\n\n /**\n * Builds a function that allows to \"tap\" into the arguments of the original one.\n * This allows to extract simple values from complex ones, transform arguments or simply intercept them.\n * If a \"tapper\" isn't found the argument is passed as it is.\n * @example\n * var someObject = {count: 5};\n * var someArrayData = [2, 3, 123, 5, 6, 7, 54, 65, 76, 0];\n * var getDataAmount = _.tapArgs(_.sum, [_.getKey(\"count\"), _.getKey(\"length\")]);\n *\n * getDataAmount(someObject, someArrayData); // => 15\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.mapArgs|mapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {Function[]} tappers\n * @returns {Function}\n */\n function tapArgs (fn, tappers) {\n return function () {\n var len = arguments.length;\n var tappersLen = tappers.length;\n var args = [];\n\n for (var i = 0; i < len; i++) {\n args.push(i < tappersLen ? tappers[i](arguments[i]) : arguments[i]);\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Returns a function that will invoke the passed function at most once in the given timespan.
\n * The first call in this case happens as soon as the function is invoked; see also\n * {@link module:lamb.debounce|debounce} for a different behaviour where the first call is delayed.\n * @example\n * var log = _.throttle(console.log.bind(console), 5000);\n *\n * log(\"Hi\"); // console logs \"Hi\"\n * log(\"Hi again\"); // nothing happens\n * // after five seconds\n * log(\"Hello world\"); // console logs \"Hello world\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.debounce|debounce}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds.\n * @returns {Function}\n */\n function throttle (fn, timespan) {\n var result;\n var lastCall = 0;\n\n return function () {\n var now = Date.now();\n\n if (now - lastCall >= timespan) {\n lastCall = now;\n result = fn.apply(this, arguments);\n }\n\n return result;\n };\n }\n\n /**\n * Builds a function that passes only one argument to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * _.map(weights, _.unary(parseInt)) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.binary|binary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function unary (fn) {\n return function (a) {\n return fn.call(this, a);\n };\n }\n\n /**\n * Accepts a series of functions and builds a function that applies the received\n * arguments to each one and returns the first non-undefined value.
\n * Meant to work in synergy with {@link module:lamb.case|case} and\n * {@link module:lamb.invoker|invoker}, can be useful as a strategy pattern for functions,\n * to mimic conditional logic or pattern matching, and also to build polymorphic functions.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var filterString = _.compose(_.invoker(\"join\", \"\"), _.filter);\n * var filterAdapter = _.adapter([\n * _.invoker(\"filter\"),\n * _.case(_.isType(\"String\"), filterString)\n * ]);\n *\n * filterAdapter([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterAdapter(\"123456\", isEven) // => \"246\"\n * filterAdapter({}, isEven) // => undefined\n *\n * // by its nature is composable\n * var filterWithDefault = _.adapter([filterAdapter, _.always(\"Not implemented\")]);\n *\n * filterWithDefault([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterWithDefault(\"123456\", isEven) // => \"246\"\n * filterWithDefault({}, isEven) // => \"Not implemented\"\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.case|case}\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.6.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function adapter (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n var len = functions.length;\n var result;\n\n for (var i = 0; i < len; i++) {\n result = functions[i].apply(this, arguments);\n\n if (!isUndefined(result)) {\n break;\n }\n }\n\n return result;\n };\n }\n\n /**\n * Creates a function to check the given predicates.
\n * Used to build the {@link module:lamb.allOf|allOf} and the\n * {@link module:lamb.anyOf|anyOf} functions.\n * @private\n * @param {Boolean} checkAll\n * @returns {Function}\n */\n function _checkPredicates (checkAll) {\n return function (predicates) {\n if (!Array.isArray(predicates)) {\n throw _makeTypeErrorFor(predicates, \"array\");\n }\n\n return function () {\n for (var i = 0, len = predicates.length, result; i < len; i++) {\n result = predicates[i].apply(this, arguments);\n\n if (checkAll && !result) {\n return false;\n } else if (!checkAll && result) {\n return true;\n }\n }\n\n return checkAll;\n };\n };\n }\n\n /**\n * Accepts an array of predicates and builds a new one that returns true if they are all satisfied\n * by the same arguments. The functions in the array will be applied one at a time until a\n * false value is produced, which is returned immediately.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isPositiveEven = _.allOf([isEven, _.isGT(0)]);\n *\n * isPositiveEven(-2) // => false\n * isPositiveEven(11) // => false\n * isPositiveEven(6) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.anyOf|anyOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\n var allOf = _checkPredicates(true);\n\n /**\n * Accepts an array of predicates and builds a new one that returns true if at least one of them is\n * satisfied by the received arguments. The functions in the array will be applied one at a time\n * until a true value is produced, which is returned immediately.\n * @example\n * var users = [\n * {id: 1, name: \"John\", group: \"guest\"},\n * {id: 2, name: \"Jane\", group: \"root\"},\n * {id: 3, name: \"Mario\", group: \"admin\"}\n * ];\n * var isInGroup = _.partial(_.hasKeyValue, [\"group\"]);\n * var isSuperUser = _.anyOf([isInGroup(\"admin\"), isInGroup(\"root\")]);\n *\n * isSuperUser(users[0]) // => false\n * isSuperUser(users[1]) // => true\n * isSuperUser(users[2]) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.allOf|allOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\n var anyOf = _checkPredicates(false);\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValue\" comparison.
\n * Note that this doesn't behave as the strict equality operator, but rather as a shim of ES6's\n * [Object.is]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is}.\n * Differences are that 0 and -0 aren't the same value and, finally,\n * NaN is equal to itself.
\n * See also {@link module:lamb.is|is} for a curried version building a predicate and\n * {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ} to perform a \"SameValueZero\"\n * comparison.\n * @example\n * var testObject = {};\n *\n * _.areSame({}, testObject) // => false\n * _.areSame(testObject, testObject) // => true\n * _.areSame(\"foo\", \"foo\") // => true\n * _.areSame(0, -0) // => false\n * _.areSame(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.is|is}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSame (a, b) {\n return a === 0 && b === 0 ? 1 / a === 1 / b : areSVZ(a, b);\n }\n\n /**\n * Builds a case for {@link module:lamb.adapter|adapter}.
\n * The function will apply the received arguments to fn if the predicate is satisfied\n * with the same arguments, otherwise will return undefined.
\n * See also {@link module:lamb.condition|condition} to build a condition with two branching functions\n * and {@link module:lamb.unless|unless} and {@link module:lamb.when|when} where one of the branches\n * is the identity function.\n * @example\n * var halveIfNumber = _.case(_.isType(\"Number\"), _.divideBy(2));\n *\n * halveIfNumber(2) // => 1\n * halveIfNumber(\"2\") // => undefined\n *\n * @alias module:lamb.case\n * @category Logic\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @since 0.51.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function case_ (predicate, fn) {\n return function () {\n return predicate.apply(this, arguments) ? fn.apply(this, arguments) : void 0;\n };\n }\n\n /**\n * Builds a function that will apply the received arguments to trueFn,\n * if the predicate is satisfied with the same arguments, or to falseFn otherwise.
\n * Although you can use other conditions as trueFn or falseFn,\n * it's probably better to use {@link module:lamb.adapter|adapter} to build more complex behaviours.
\n * See also {@link module:lamb.unless|unless} and {@link module:lamb.when|when} as they are\n * shortcuts to common use cases.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveEvenAndDoubleOdd = _.condition(isEven, _.divideBy(2), _.multiplyBy(2));\n *\n * halveEvenAndDoubleOdd(5) // => 10\n * halveEvenAndDoubleOdd(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.2.0\n * @param {Function} predicate\n * @param {Function} trueFn\n * @param {Function} falseFn\n * @returns {Function}\n */\n function condition (predicate, trueFn, falseFn) {\n return function () {\n return (predicate.apply(this, arguments) ? trueFn : falseFn).apply(this, arguments);\n };\n }\n\n /**\n * Verifies that the first given value is greater than the second.
\n * Wraps the native > operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.gt(today, pastDate) // => true\n * _.gt(pastDate, today) // => false\n * _.gt(3, 4) // => false\n * _.gt(3, 3) // => false\n * _.gt(3, 2) // => true\n * _.gt(0, -0) // => false\n * _.gt(-0, 0) // => false\n * _.gt(\"a\", \"A\") // => true\n * _.gt(\"b\", \"a\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gt (a, b) {\n return a > b;\n }\n\n /**\n * Verifies that the first given value is greater than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * >= operator, so -0 === 0.\n * @example\n * _.gte(3, 4) // => false\n * _.gte(3, 3) // => true\n * _.gte(3, 2) // => true\n * _.gte(0, -0) // => true\n * _.gte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gt|gt}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gte (a, b) {\n return a >= b;\n }\n\n /**\n * A curried version of {@link module:lamb.areSame|areSame}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValue\"\n * comparison.
\n * See also {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ}\n * to perform a \"SameValueZero\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.is(john);\n * var isNegativeZero = _.is(-0);\n * var isReallyNaN = _.is(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isNegativeZero(0) // => false\n * isNegativeZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSame|areSame}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var is = _curry2(areSame);\n\n /**\n * A right curried version of {@link module:lamb.gt|gt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than the one received by the predicate.\n * @example\n * var isGreaterThan5 = _.isGT(5);\n *\n * isGreaterThan5(3) // => false\n * isGreaterThan5(5) // => false\n * isGreaterThan5(7) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGT = _curry2(gt, true);\n\n /**\n * A right curried version of {@link module:lamb.gte|gte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than or equal to the one received by the predicate.\n * @example\n * var isPositiveOrZero = _.isGTE(0);\n *\n * isPositiveOrZero(-3) // => false\n * isPositiveOrZero(-0) // => true\n * isPositiveOrZero(0) // => true\n * isPositiveOrZero(5) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGT|isGT}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGTE = _curry2(gte, true);\n\n /**\n * Verifies that the first given value is less than the second.
\n * Wraps the native < operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.lt(today, pastDate) // => false\n * _.lt(pastDate, today) // => true\n * _.lt(3, 4) // => true\n * _.lt(3, 3) // => false\n * _.lt(3, 2) // => false\n * _.lt(0, -0) // => false\n * _.lt(-0, 0) // => false\n * _.lt(\"a\", \"A\") // => false\n * _.lt(\"a\", \"b\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lt (a, b) {\n return a < b;\n }\n\n /**\n * A right curried version of {@link module:lamb.lt|lt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than the one received by the predicate.\n * @example\n * var isLessThan5 = _.isLT(5);\n *\n * isLessThan5(7) // => false\n * isLessThan5(5) // => false\n * isLessThan5(3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLT = _curry2(lt, true);\n\n /**\n * Verifies that the first given value is less than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * <= operator, so -0 === 0.\n * @example\n * _.lte(3, 4) // => true\n * _.lte(3, 3) // => true\n * _.lte(3, 2) // => false\n * _.lte(0, -0) // => true\n * _.lte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lt|lt}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lte (a, b) {\n return a <= b;\n }\n\n /**\n * A right curried version of {@link module:lamb.lte|lte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than or equal to the one received by the predicate.\n * @example\n * var isNegativeOrZero = _.isLTE(0);\n *\n * isNegativeOrZero(5) // => false\n * isNegativeOrZero(-0) // => true\n * isNegativeOrZero(0) // => true\n * isNegativeOrZero(-3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLT|isLT}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLTE = _curry2(lte, true);\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate isn't satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.when|when} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its trueFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveUnlessIsEven = _.unless(isEven, _.divideBy(2));\n *\n * halveUnlessIsEven(5) // => 2.5\n * halveUnlessIsEven(6) // => 6\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function unless (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? value : fn.call(this, value);\n };\n }\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate is satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.unless|unless} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its falseFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var halveIfEven = _.when(isEven, _.divideBy(2));\n *\n * halveIfEven(5) // => 5\n * halveIfEven(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function when (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? fn.call(this, value) : value;\n };\n }\n\n /**\n * Sums two numbers.\n * @example\n * _.sum(4, 5) // => 9\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.add|add}\n * @since 0.50.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function sum (a, b) {\n return a + b;\n }\n\n /**\n * A curried version of {@link module:lamb.sum|sum}.\n * @example\n * var add5 = _.add(5);\n *\n * _.add5(4) // => 9\n * _.add5(-2) // => 3\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.sum|sum}\n * @since 0.1.0\n * @param {Number} a\n * @returns {Function}\n */\n var add = _curry2(sum, true);\n\n /**\n * Subtracts two numbers.\n * @example\n * _.subtract(5, 3) // => 2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.deduct|deduct}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function subtract (a, b) {\n return a - b;\n }\n\n /**\n * A curried version of {@link module:lamb.subtract|subtract} that expects the\n * subtrahend to build a function waiting for the minuend.\n * @example\n * var deduct5 = _.deduct(5);\n *\n * deduct5(12) // => 7\n * deduct5(3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.subtract|subtract}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var deduct = _curry2(subtract, true);\n\n /**\n * Divides two numbers.\n * @example\n * _.divide(5, 2) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.divideBy|divideBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function divide (a, b) {\n return a / b;\n }\n\n /**\n * A curried version of {@link module:lamb.divide|divide} that expects a divisor to\n * build a function waiting for the dividend.\n * @example\n * var halve = divideBy(2);\n *\n * halve(10) // => 5\n * halve(5) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.divide|divide}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var divideBy = _curry2(divide, true);\n\n /**\n * Generates a sequence of values of the desired length with the provided iteratee.\n * The values being iterated, and received by the iteratee, are the results generated so far.\n * @example\n * var fibonacci = function (n, idx, results) {\n * return n + (results[idx - 1] || 0);\n * };\n *\n * _.generate(1, 10, fibonacci) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.range|range}\n * @since 0.21.0\n * @param {*} start - The starting value\n * @param {Number} len - The desired length for the sequence\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function generate (start, len, iteratee) {\n var result = [start];\n\n for (var i = 0, limit = len - 1; i < limit; i++) {\n result.push(iteratee(result[i], i, result));\n }\n\n return result;\n }\n\n /**\n * Verifies whether the received value is a finite number.
\n * Behaves almost as a shim of ES6's [Number.isFinite]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isFinite(5) // => true\n * _.isFinite(new Number(5)) // => true\n * _.isFinite(Infinity) // => false\n * _.isFinite(-Infinity) // => false\n * _.isFinite(\"5\") // => false\n * _.isFinite(NaN) // => false\n * _.isFinite(null) // => false\n *\n * @alias module:lamb.isFinite\n * @category Math\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isFinite_ (value) {\n return type(value) === \"Number\" && isFinite(value);\n }\n\n /**\n * Verifies whether the received value is a number and an integer.\n * Behaves almost as a shim of ES6's [Number.isInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isInteger(5) // => true\n * _.isInteger(new Number(5)) // => true\n * _.isInteger(2.5) // => false\n * _.isInteger(Infinity) // => false\n * _.isInteger(-Infinity) // => false\n * _.isInteger(\"5\") // => false\n * _.isInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isSafeInteger|isSafeInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isInteger (value) {\n return type(value) === \"Number\" && value % 1 === 0;\n }\n\n /**\n * Verifies whether the received value is a \"safe integer\", meaning that is a number and that\n * can be exactly represented as an IEEE-754 double precision number.\n * The safe integers consist of all integers from -(253 - 1) inclusive to\n * 253 - 1 inclusive.
\n * Behaves almost as a shim of ES6's [Number.isSafeInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isSafeInteger(5) // => true\n * _.isSafeInteger(new Number(5)) // => true\n * _.isSafeInteger(Math.pow(2, 53) - 1) // => true\n * _.isSafeInteger(Math.pow(2, 53)) // => false\n * _.isSafeInteger(2e32) // => false\n * _.isSafeInteger(2.5) // => false\n * _.isSafeInteger(Infinity) // => false\n * _.isSafeInteger(-Infinity) // => false\n * _.isSafeInteger(\"5\") // => false\n * _.isSafeInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isInteger|isInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isSafeInteger (value) {\n return isInteger(value) && Math.abs(value) <= MAX_SAFE_INTEGER;\n }\n\n /**\n * Performs the modulo operation and should not be confused with the\n * {@link module:lamb.remainder|remainder}.\n * The function performs a floored division to calculate the result and not\n * a truncated one, hence the sign of the dividend is not kept, unlike the\n * {@link module:lamb.remainder|remainder}.\n * @example\n * _.modulo(5, 3) // => 2\n * _.remainder(5, 3) // => 2\n *\n * _.modulo(-5, 3) // => 1\n * _.remainder(-5, 3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.remainder|remainder}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function modulo (a, b) {\n return a - (b * Math.floor(a / b));\n }\n\n /**\n * Multiplies two numbers.\n * @example\n * _.multiply(5, 3) // => 15\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.multiplyBy|multiplyBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function multiply (a, b) {\n return a * b;\n }\n\n /**\n * A curried version of {@link module:lamb.multiply|multiply}.\n * @example\n * var double = _.multiplyBy(2);\n *\n * double(5) // => 10\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.multiply|multiply}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var multiplyBy = _curry2(multiply, true);\n\n /**\n * Generates a random integer between two given integers, both included.\n * Note that no safety measure is taken if the provided arguments aren't integers, so\n * you may end up with unexpected (not really) results.\n * For example randomInt(0.1, 1.2) could be 2.\n * @example\n *\n * _.randomInt(1, 10) // => an integer >=1 && <= 10\n *\n * @memberof module:lamb\n * @category Math\n * @since 0.1.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function randomInt (min, max) {\n return Math.floor(Math.random() * (max - min + 1) + min);\n }\n\n /**\n * Converts a value to a number and returns it if it's not NaN, otherwise\n * returns zero.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _forceToNumber (value) {\n var n = +value;\n\n return n === n ? n : 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * Generates an arithmetic progression of numbers starting from start up to,\n * but not including, limit, using the given step.\n * @example\n * _.range(2, 10) // => [2, 3, 4, 5, 6, 7, 8, 9]\n * _.range(1, -10, -2) // => [1, -1, -3, -5, -7, -9]\n * _.range(0, 3, 1) // => [0, 1, 2]\n * _.range(-0, 3, 1) // => [-0, 1, 2]\n * _.range(1, -10, 2) // => []\n * _.range(3, 5, -1) // => []\n *\n * @example Behaviour if step happens to be zero:\n * _.range(2, 10, 0) // => [2]\n * _.range(2, -10, 0) // => [2]\n * _.range(2, 2, 0) // => []\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.generate|generate}\n * @since 0.1.0\n * @param {Number} start\n * @param {Number} limit\n * @param {Number} [step=1]\n * @returns {Number[]}\n */\n function range (start, limit, step) {\n start = _forceToNumber(start);\n limit = _forceToNumber(limit);\n step = arguments.length === 3 ? _forceToNumber(step) : 1;\n\n if (step === 0) {\n return limit === start ? [] : [start];\n }\n\n var len = Math.max(Math.ceil((limit - start) / step), 0);\n var result = Array(len);\n\n for (var i = 0, last = start; i < len; i++) {\n result[i] = last;\n last += step;\n }\n\n return result;\n }\n\n /**\n * Gets the remainder of the division of two numbers.\n * Not to be confused with the {@link module:lamb.modulo|modulo} as the remainder\n * keeps the sign of the dividend and may lead to some unexpected results.\n * @example\n * // example of wrong usage of the remainder\n * // (in this case the modulo operation should be used)\n * var isOdd = function (n) { return _.remainder(n, 2) === 1; };\n * isOdd(-3) // => false as -3 % 2 === -1\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.modulo|modulo}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function remainder (a, b) {\n return a % b;\n }\n\n /**\n * Checks whether the specified key is a own enumerable property of the given object or not.\n * @private\n * @function\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var _isOwnEnumerable = generic(Object.prototype.propertyIsEnumerable);\n\n /**\n * Builds a list of the enumerable properties of an object.\n * The function is null-safe, unlike the public one.\n * @private\n * @param {Object} obj\n * @returns {String[]}\n */\n function _safeEnumerables (obj) {\n var result = [];\n\n for (var key in obj) {\n result.push(key);\n }\n\n return result;\n }\n\n /**\n * Checks whether the specified key is an enumerable property of the given object or not.\n * @private\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function _isEnumerable (obj, key) {\n return key in Object(obj) && (_isOwnEnumerable(obj, key) || ~_safeEnumerables(obj).indexOf(key));\n }\n\n /**\n * Helper to retrieve the correct key while evaluating a path.\n * @private\n * @param {Object} target\n * @param {String} key\n * @param {Boolean} includeNonEnumerables\n * @returns {String|Number|Undefined}\n */\n function _getPathKey (target, key, includeNonEnumerables) {\n if (includeNonEnumerables && key in Object(target) || _isEnumerable(target, key)) {\n return key;\n }\n\n var n = +key;\n var len = target && target.length;\n\n return n >= -len && n < len ? n < 0 ? n + len : n : void 0;\n }\n\n /**\n * Checks if a path is valid in the given object and retrieves the path target.\n * @private\n * @param {Object} obj\n * @param {String[]} parts\n * @param {Boolean} walkNonEnumerables\n * @returns {Object}\n */\n function _getPathInfo (obj, parts, walkNonEnumerables) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n var target = obj;\n var i = -1;\n var len = parts.length;\n var key;\n\n while (++i < len) {\n key = _getPathKey(target, parts[i], walkNonEnumerables);\n\n if (isUndefined(key)) {\n break;\n }\n\n target = target[key];\n }\n\n return i === len ? { isValid: true, target: target } : { isValid: false, target: void 0 };\n }\n\n /**\n * Splits a sting path using the provided separator and returns an array\n * of path parts.\n * @private\n * @param {String} path\n * @param {String} separator\n * @returns {String[]}\n */\n function _toPathParts (path, separator) {\n return String(path).split(separator || \".\");\n }\n\n /**\n * Gets a nested property value from an object using the given path.
\n * The path is a string with property names separated by dots by default, but\n * it can be customised with the optional third parameter.
\n * You can use integers in the path, even negative ones, to refer to array-like\n * object indexes, but the priority will be given to existing object keys:\n * the last example explains this particular case.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * },\n * scores: [\n * {id: 1, value: 10},\n * {id: 2, value: 20},\n * {id: 3, value: 30}\n * ]\n * };\n *\n * _.getPathIn(user, \"name\") // => \"John\"\n * _.getPathIn(user, \"login.password\") // => \"abc123\";\n * _.getPathIn(user, \"login/user.name\", \"/\") // => \"jdoe\"\n * _.getPathIn(user, \"name.foo\") // => undefined\n * _.getPathIn(user, \"name.foo.bar\") // => undefined\n *\n * @example Accessing array-like objects indexes:\n * _.getPathIn(user, \"login.password.1\") // => \"b\"\n * _.getPathIn(user, \"scores.0\") // => {id: 1, value: 10}\n * _.getPathIn(user, \"scores.-1.value\") // => 30\n *\n * @example Priority will be given to existing object keys over indexes:\n * _.getPathIn(user, \"scores.-1\") // => {id: 3, value: 30}\n *\n * // let's do something funny\n * user.scores[\"-1\"] = \"foo bar\";\n *\n * _.getPathIn(user, \"scores.-1\") // => \"foo bar\";\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getPath|getPath}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {Object|ArrayLike} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {*}\n */\n function getPathIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).target;\n }\n\n /**\n * Builds a checker function meant to be used with\n * {@link module:lamb.validate|validate}.
\n * Note that the function accepts multiple keyPaths as a means to\n * compare their values. In other words all the received keyPaths will be\n * passed as arguments to the predicate to run the test.
\n * If you want to run the same single property check with multiple properties, you should build\n * multiple checkers and combine them with {@link module:lamb.validate|validate}.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\",\n * passwordConfirm: \"abc123\"\n * }\n * };\n * var pwdMatch = _.checker(\n * _.areSame,\n * \"Passwords don't match\",\n * [\"login.password\", \"login.passwordConfirm\"]\n * );\n *\n * pwdMatch(user) // => []\n *\n * var newUser = _.setPathIn(user, \"login.passwordConfirm\", \"avc123\");\n *\n * pwdMatch(newUser) // => [\"Passwords don't match\", [\"login.password\", \"login.passwordConfirm\"]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validate|validate}, {@link module:lamb.validateWith|validateWith}\n * @since 0.1.0\n * @param {Function} predicate - The predicate to test the object properties\n * @param {String} message - The error message\n * @param {String[]} keyPaths - The array of keys, or {@link module:lamb.getPathIn|paths}, to test.\n * @param {String} [pathSeparator=\".\"]\n * @returns {Function} A checker function which returns an error in the form\n * [\"message\", [\"propertyA\", \"propertyB\"]] or an empty array.\n */\n function checker (predicate, message, keyPaths, pathSeparator) {\n return function (obj) {\n var getValues = partial(getPathIn, [obj, __, pathSeparator]);\n\n return predicate.apply(obj, map(keyPaths, getValues)) ? [] : [message, keyPaths];\n };\n }\n\n /**\n * Creates a non-null-safe version of the provided \"getKeys\" function.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _unsafeKeyListFrom = _curry2(function (getKeys, obj) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n return getKeys(obj);\n });\n\n /**\n * Creates an array with all the enumerable properties of the given object.\n * @example Showing the difference with {@link module:lamb.keys|keys}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.keys(foo) // => [\"d\"]\n * _.enumerables(foo) // => [\"d\", \"a\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.keys|keys}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {String[]}\n */\n var enumerables = _unsafeKeyListFrom(_safeEnumerables);\n\n /**\n * Builds an object from a list of key / value pairs like the one\n * returned by {@link module:lamb.pairs|pairs} or {@link module:lamb.ownPairs|ownPairs}.
\n * In case of duplicate keys the last key / value pair is used.\n * @example\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"c\", 3]]) // => {\"a\": 1, \"b\": 2, \"c\": 3}\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"a\", 3]]) // => {\"a\": 3, \"b\": 2}\n * _.fromPairs([[1], [void 0, 2], [null, 3]]) // => {\"1\": undefined, \"undefined\": 2, \"null\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.ownPairs|ownPairs}, {@link module:lamb.pairs|pairs}\n * @since 0.8.0\n * @param {Array>} pairsList\n * @returns {Object}\n */\n function fromPairs (pairsList) {\n var result = {};\n\n forEach(pairsList, function (pair) {\n result[pair[0]] = pair[1];\n });\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.getPathIn|getPathIn} with the given\n * path and separator, expecting the object to act upon.
\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * }\n * };\n *\n * var getPwd = _.getPath(\"login.password\");\n * var getUsername = _.getPath(\"login/user.name\", \"/\");\n *\n * getPwd(user) // => \"abc123\";\n * getUsername(user) // => \"jdoe\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getPathIn|getPathIn}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var getPath = _makePartial3(getPathIn);\n\n /**\n * Verifies the existence of a property in an object.\n * @example\n * var user1 = {name: \"john\"};\n *\n * _.has(user1, \"name\") // => true\n * _.has(user1, \"surname\") // => false\n * _.has(user1, \"toString\") // => true\n *\n * var user2 = Object.create(null);\n *\n * // not inherited through the prototype chain\n * _.has(user2, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function has (obj, key) {\n if (typeof obj !== \"object\" && !isUndefined(obj)) {\n obj = Object(obj);\n }\n\n return key in obj;\n }\n\n /**\n * Curried version of {@link module:lamb.has|has}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {};\n * var hasName = _.hasKey(\"name\");\n *\n * hasName(user1) // => true\n * hasName(user2) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.has|has}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasKey = _curry2(has, true);\n\n /**\n * Verifies if an object has the specified property and that the property isn't inherited through\n * the prototype chain.
\n * @example Comparison with has:\n * var user = {name: \"john\"};\n *\n * _.has(user, \"name\") // => true\n * _.has(user, \"surname\") // => false\n * _.has(user, \"toString\") // => true\n *\n * _.hasOwn(user, \"name\") // => true\n * _.hasOwn(user, \"surname\") // => false\n * _.hasOwn(user, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var hasOwn = generic(Object.prototype.hasOwnProperty);\n\n /**\n * Curried version of {@link module:lamb.hasOwn|hasOwn}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user = {name: \"john\"};\n * var hasOwnName = _.hasOwnKey(\"name\");\n * var hasOwnToString = _.hasOwnToString(\"toString\");\n *\n * hasOwnName(user) // => true\n * hasOwnToString(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwn|hasOwn}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasOwnKey = _curry2(hasOwn, true);\n\n /**\n * Builds a predicate expecting an object to check against the given key / value pair.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var hasTheCorrectAnswer = _.hasKeyValue(\"answer\", 42);\n *\n * hasTheCorrectAnswer({answer: 2}) // false\n * hasTheCorrectAnswer({answer: 42}) // true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasPathValue|hasPathValue}\n * @since 0.1.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n function hasKeyValue (key, value) {\n return function (obj) {\n return isUndefined(value) ? has(obj, key) && obj[key] === value : areSVZ(value, obj[key]);\n };\n }\n\n /**\n * Builds a predicate to check if the given path exists in an object and holds the desired value.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * personal: {\n * age: 25,\n * gender: \"M\"\n * },\n * scores: [\n * {id: 1, value: 10, passed: false},\n * {id: 2, value: 20, passed: false},\n * {id: 3, value: 30, passed: true}\n * ]\n * };\n *\n * var isMale = _.hasPathValue(\"personal.gender\", \"M\");\n * var hasPassedFirstTest = _.hasPathValue(\"scores.0.passed\", true);\n * var hasPassedLastTest = _.hasPathValue(\"scores.-1.passed\", true);\n *\n * isMale(user) // => true\n * hasPassedFirstTest(user) // => false\n * hasPassedLastTest(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKeyValue|hasKeyValue}\n * @since 0.41.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function hasPathValue (path, value, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return pathInfo.isValid && areSVZ(pathInfo.target, value);\n };\n }\n\n /**\n * Makes an object immutable by recursively calling Object.freeze\n * on its members.\n * @private\n * @param {Object} obj\n * @param {Array} seen\n * @returns {Object} The obj parameter itself, not a copy.\n */\n function _immutable (obj, seen) {\n if (seen.indexOf(obj) === -1) {\n seen.push(Object.freeze(obj));\n\n forEach(Object.getOwnPropertyNames(obj), function (key) {\n var value = obj[key];\n\n if (typeof value === \"object\" && !isNull(value)) {\n _immutable(value, seen);\n }\n });\n }\n\n return obj;\n }\n\n /**\n * Makes an object immutable by recursively calling [Object.freeze]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze}\n * on its members.
\n * Any attempt to extend or modify the object can throw a TypeError or fail silently,\n * depending on the environment and the [strict mode]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode} directive.\n * @example\n * var user = _.immutable({\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\"\n * },\n * luckyNumbers: [13, 17]\n * });\n *\n * // All of these statements will fail and possibly\n * // throw a TypeError (see the function description)\n * user.name = \"Joe\";\n * delete user.name;\n * user.newProperty = [];\n * user.login.password = \"foo\";\n * user.luckyNumbers.push(-13);\n *\n * @memberof module:lamb\n * @category Object\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Object}\n */\n function immutable (obj) {\n return _immutable(obj, []);\n }\n\n /**\n * A null-safe version of Object.keys.\n * @private\n * @function\n * @param {Object} obj\n * @returns {String[]}\n */\n var _safeKeys = compose(Object.keys, Object);\n\n /**\n * Retrieves the list of the own enumerable properties of an object.
\n * Although [Object.keys]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys}\n * is already present in ECMAScript 5, its behaviour changed in the subsequent specifications\n * of the standard.
\n * This function shims the ECMAScript 6 version, by forcing a conversion to\n * object for any value but null and undefined.\n * @example Showing the difference with {@link module:lamb.enumerables|enumerables}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.enumerables(foo) // => [\"d\", \"a\"]\n * _.keys(foo) // => [\"d\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.enumerables|enumerables}\n * @since 0.25.1\n * @param {Object} obj\n * @returns {String[]}\n */\n var keys = _unsafeKeyListFrom(_safeKeys);\n\n /**\n * Builds a predicate to check if the given key satisfies the desired condition\n * on an object.\n * @example\n * var users = [\n * {name: \"John\", age: 25},\n * {name: \"Jane\", age: 15},\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n *\n * isAdult(users[0]) // => true\n * isAdult(users[1]) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathSatisfies|pathSatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} key\n * @returns {Function}\n */\n function keySatisfies (predicate, key) {\n return function (obj) {\n return predicate.call(this, obj[key]);\n };\n }\n\n /**\n * Builds an object from the two given lists, using the first one as keys and the last\n * one as values.
\n * If the list of keys is longer than the values one, the keys will be created with\n * undefined values.
\n * If more values than keys are supplied, the extra values will be ignored.\n * @example\n * _.make([\"a\", \"b\", \"c\"], [1, 2, 3]) // => {a: 1, b: 2, c: 3}\n * _.make([\"a\", \"b\", \"c\"], [1, 2]) // => {a: 1, b: 2, c: undefined}\n * _.make([\"a\", \"b\"], [1, 2, 3]) // => {a: 1, b: 2}\n * _.make([null, void 0, 2], [1, 2, 3]) // => {\"null\": 1, \"undefined\": 2, \"2\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.tear|tear}, {@link module:lamb.tearOwn|tearOwn} for the reverse operation\n * @since 0.8.0\n * @param {String[]} names\n * @param {ArrayLike} values\n * @returns {Object}\n */\n function make (names, values) {\n var result = {};\n var valuesLen = values.length;\n\n for (var i = 0, len = names.length; i < len; i++) {\n result[names[i]] = i < valuesLen ? values[i] : void 0;\n }\n\n return result;\n }\n\n /**\n * Creates a new object by applying the given function\n * to all enumerable properties of the source one.\n * @example\n * var weights = {\n * john: \"72.5 Kg\",\n * jane: \"52.3 Kg\"\n * };\n *\n * _.mapValues(weights, parseFloat) // => {john: 72.5, jane: 52.3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValuesWith|mapValuesWith}\n * @since 0.54.0\n * @param {Object} source\n * @param {ObjectIteratorCallback} fn\n * @returns {Object}\n */\n function mapValues (source, fn) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n result[key] = fn(source[key], key, source);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.mapValues|mapValues}.
\n * Expects a mapping function to build a new function waiting for the\n * object to act upon.\n * @example\n * var incValues = _.mapValuesWith(_.add(1));\n * var results = {\n * first: 10,\n * second: 5,\n * third: 3\n * };\n *\n * incValues(results) // => {first: 11, second: 6, third: 4}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValues|mapValues}\n * @since 0.54.0\n * @function\n * @param {ObjectIteratorCallback} fn\n * @returns {Function}\n */\n var mapValuesWith = _curry2(mapValues, true);\n\n /**\n * Merges the received objects using the provided function to retrieve their keys.\n * @private\n * @param {Function} getKeys\n * @param {Object} a\n * @param {Object} b\n * @returns {Function}\n */\n function _merge (getKeys, a, b) {\n return reduce([a, b], function (result, source) {\n forEach(getKeys(source), function (key) {\n result[key] = source[key];\n });\n\n return result;\n }, {});\n }\n\n /**\n * Merges the enumerable properties of the provided sources into a new object.
\n * In case of key homonymy the last source has precedence over the first.\n * @example\n * _.merge({a: 1, b: 3}, {b: 5, c: 4}) // => {a: 1, b: 5, c: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.merge([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.merge(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.merge({a: 2}, 99) // => {a: 2}\n * _.merge({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mergeOwn|mergeOwn} to merge own properties only\n * @since 0.10.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\n var merge = partial(_merge, [enumerables]);\n\n /**\n * Same as {@link module:lamb.merge|merge}, but only the own properties of the\n * sources are taken into account.\n * @example Showing the difference with merge:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * var bar = {d: 4};\n *\n * _.merge(foo, bar) // => {a: 1, b: 2, c: 3, d: 4}\n * _.mergeOwn(foo, bar) // => {c: 3, d: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.mergeOwn([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.mergeOwn(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.mergeOwn({a: 2}, 99) // => {a: 2}\n * _.mergeOwn({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.merge|merge} to merge all enumerable properties\n * @since 0.12.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\n var mergeOwn = partial(_merge, [keys]);\n\n /**\n * Accepts an object and build a function expecting a key to create a \"pair\" with the key\n * and its value.\n * @private\n * @function\n * @param {Object} obj\n * @returns {Function}\n */\n var _keyToPairIn = _curry2(function (obj, key) {\n return [key, obj[key]];\n });\n\n /**\n * Using the provided function to retrieve the keys, builds a new function\n * expecting an object to create a list of key / value pairs.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _pairsFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), _keyToPairIn(obj));\n });\n\n /**\n * Same as {@link module:lamb.pairs|pairs}, but only the own enumerable properties of the object are\n * taken into account.
\n * See also {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example Showing the difference with pairs:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.pairs(foo) // => [[\"c\", 3], [\"b\", 2], [\"a\", 1]]\n * _.ownPairs(foo) // => [[\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pairs|pairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var ownPairs = _pairsFrom(keys);\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create the list of values for such keys.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _valuesFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), function (key) {\n return obj[key];\n });\n });\n\n /**\n * Same as {@link module:lamb.values|values}, but only the own enumerable properties of the object are\n * taken into account.
\n * @example Showing the difference with values:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.values(foo) // => [3, 2, 1]\n * _.ownValues(foo) // => [3]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.values|values}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var ownValues = _valuesFrom(keys);\n\n /**\n * Converts an object into an array of key / value pairs of its enumerable properties.
\n * See also {@link module:lamb.ownPairs|ownPairs} for picking only the own enumerable\n * properties and {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example\n * _.pairs({a: 1, b: 2, c: 3}) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownPairs|ownPairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var pairs = _pairsFrom(enumerables);\n\n /**\n * Checks if the provided path exists in the given object.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * _.pathExistsIn(user, \"address.city\") // => true\n * _.pathExistsIn(user, \"address.country\") // => false\n * _.pathExistsIn(user, \"scores.1\") // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathExists|pathExists}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {Object} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Boolean}\n */\n function pathExistsIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).isValid;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.pathExistsIn|pathExistsIn} using the given\n * path and the optional separator. The resulting function expects the object to check.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * var hasCity = _.pathExists(\"address.city\");\n * var hasCountry = _.pathExists(\"address.country\");\n * var hasAtLeastThreeScores = _.pathExists(\"scores.2\");\n *\n * hasCity(user) // => true\n * hasCountry(user) // => false\n * hasAtLeastThreeScores(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var pathExists = _makePartial3(pathExistsIn);\n\n /**\n * Builds a predicate that verifies if a condition is satisfied for the given\n * path in an object.
\n * Like the other \"path functions\" you can use integers in the path, even\n * negative ones, to refer to array-like object indexes, but the priority will\n * be given to existing object keys.\n * @example\n * var user = {\n * name: \"John\",\n * performance: {\n * scores: [1, 5, 10]\n * }\n * };\n *\n * var gotAnHighScore = _.pathSatisfies(_.contains(10), \"performance.scores\");\n * var hadAGoodStart = _.pathSatisfies(_.isGT(6), \"performance.scores.0\");\n *\n * gotAnHighScore(user) // => true\n * hadAGoodStart(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.keySatisfies|keySatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function pathSatisfies (predicate, path, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return predicate.call(this, pathInfo.target);\n };\n }\n\n /**\n * Returns an object containing only the specified properties of the given object.
\n * Non existent properties will be ignored.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.pick(user, [\"name\", \"age\"]) // => {\"name\": \"john\", \"age\": 30};\n * _.pick(user, [\"name\", \"email\"]) // => {\"name\": \"john\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pickIf|pickIf}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} whitelist\n * @returns {Object}\n */\n function pick (source, whitelist) {\n var result = {};\n\n for (var i = 0, len = whitelist.length, key; i < len; i++) {\n key = whitelist[i];\n\n if (has(source, key)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be included in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var pickIfIsString = _.pickIf(_.isType(\"String\"));\n *\n * pickIfIsString(user) // => {name: \"john\", surname: \"doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n function pickIf (predicate) {\n return function (source) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n if (predicate(source[key], key, source)) {\n result[key] = source[key];\n }\n }\n\n return result;\n };\n }\n\n /**\n * A curried version of {@link module:lamb.pick|pick}, expecting a whitelist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.pickKeys([\"id\", \"active\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var select = _.compose(_.mapWith, _.pickKeys);\n * var selectUserInfo = select([\"id\", \"active\"]);\n *\n * selectUserInfo(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickIf|pickIf}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.35.0\n * @param {String[]} whitelist\n * @returns {Function}\n */\n var pickKeys = _curry2(pick, true);\n\n /**\n * Creates a copy of the given object with its enumerable keys renamed as\n * indicated in the provided lookup table.\n * @example\n * var person = {\"firstName\": \"John\", \"lastName\": \"Doe\"};\n * var keysMap = {\"firstName\": \"name\", \"lastName\": \"surname\"};\n *\n * _.rename(person, keysMap) // => {\"name\": \"John\", \"surname\": \"Doe\"}\n *\n * @example It's safe using it to swap keys:\n * var keysMap = {\"firstName\": \"lastName\", \"lastName\": \"firstName\"};\n *\n * _.rename(person, keysMap) // => {\"lastName\": \"John\", \"firstName\": \"Doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.renameKeys|renameKeys}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} source\n * @param {Object} keysMap\n * @returns {Object}\n */\n function rename (source, keysMap) {\n keysMap = Object(keysMap);\n var result = {};\n var oldKeys = enumerables(source);\n\n for (var prop in keysMap) {\n if (~oldKeys.indexOf(prop)) {\n result[keysMap[prop]] = source[prop];\n }\n }\n\n for (var i = 0, len = oldKeys.length, key; i < len; i++) {\n key = oldKeys[i];\n\n if (!(key in keysMap || key in result)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.rename|rename} expecting a\n * keysMap to build a function waiting for the object to act upon.\n * @example\n * var persons = [\n * {\"firstName\": \"John\", \"lastName\": \"Doe\"},\n * {\"first_name\": \"Mario\", \"last_name\": \"Rossi\"},\n * ];\n * var normalizeKeys = _.renameKeys({\n * \"firstName\": \"name\",\n * \"first_name\": \"name\",\n * \"lastName\": \"surname\",\n * \"last_name\": \"surname\"\n * });\n *\n * _.map(persons, normalizeKeys) // =>\n * // [\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} keysMap\n * @returns {Function}\n */\n var renameKeys = _curry2(rename, true);\n\n /**\n * Uses the provided function as a keysMap generator and returns\n * a function expecting the object whose keys we want to {@link module:lamb.rename|rename}.\n * @example\n * var person = {\"NAME\": \"John\", \"SURNAME\": \"Doe\"};\n * var arrayToLower = _.mapWith(_.invoker(\"toLowerCase\"));\n * var makeLowerKeysMap = function (source) {\n * var sourceKeys = _.keys(source);\n *\n * return _.make(sourceKeys, arrayToLower(sourceKeys));\n * };\n * var lowerKeysFor = _.renameWith(makeLowerKeysMap);\n *\n * lowerKeysFor(person) // => {\"name\": \"John\", \"surname\": \"doe\"};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameKeys|renameKeys}\n * @since 0.26.0\n * @param {Function} fn\n * @returns {Function}\n */\n function renameWith (fn) {\n return function (source) {\n return rename(source, fn(source));\n };\n }\n\n /**\n * Sets, or creates, a property in a copy of the provided object to the desired value.\n * @private\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function _setIn (source, key, value) {\n var result = {};\n\n for (var prop in source) {\n result[prop] = source[prop];\n }\n\n result[key] = value;\n\n return result;\n }\n\n /**\n * Sets the specified key to the given value in a copy of the provided object.
\n * All the remaining enumerable keys of the source object will be simply copied in the\n * result object without breaking references.
\n * If the specified key is not part of the source object, it will be added to the\n * result.
\n * The main purpose of the function is to work on simple plain objects used as\n * data structures, such as JSON objects, and makes no effort to play nice with\n * objects created from an OOP perspective (it's not worth it).
\n * For example the prototype of the result will be Object's regardless\n * of the source's one.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n *\n * _.setIn(user, \"name\", \"Jane\") // => {name: \"Jane\", surname: \"Doe\", age: 30}\n * _.setIn(user, \"gender\", \"male\") // => {name: \"John\", surname: \"Doe\", age: 30, gender: \"male\"}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setKey|setKey}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function setIn (source, key, value) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setIn(source, key, value);\n }\n\n /**\n * Builds a partial application of {@link module:lamb.setIn|setIn} with the provided\n * key and value.
\n * The resulting function expects the object to act upon.
\n * Please refer to {@link module:lamb.setIn|setIn}'s description for explanations about\n * how the copy of the source object is made.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n * var setAgeTo40 = _.setKey(\"age\", 40);\n *\n * setAgeTo40(user) // => {name: \"john\", surname: \"doe\", age: 40}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.setIn|setIn}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n var setKey = _makePartial3(setIn);\n\n /**\n * Accepts a target object and a key name and verifies that the target is an array and that\n * the key is an existing index.\n * @private\n * @param {Object} target\n * @param {String|Number} key\n * @returns {Boolean}\n */\n function _isArrayIndex (target, key) {\n var n = +key;\n\n return Array.isArray(target) && n % 1 === 0 && !(n < 0 && _isEnumerable(target, key));\n }\n\n /**\n * Sets the object's property targeted by the given path to the desired value.
\n * Works with arrays and is able to set their indexes, even negative ones.\n * @private\n * @param {Object|Array} obj\n * @param {String[]} parts\n * @param {*} value\n * @returns {Object|Array}\n */\n function _setPathIn (obj, parts, value) {\n var key = parts[0];\n var partsLen = parts.length;\n var v;\n\n if (partsLen === 1) {\n v = value;\n } else {\n var targetKey = _getPathKey(obj, key, false);\n\n v = _setPathIn(\n isUndefined(targetKey) ? targetKey : obj[targetKey],\n slice(parts, 1, partsLen),\n value\n );\n }\n\n return _isArrayIndex(obj, key) ? _setIndex(obj, key, v) : _setIn(obj, key, v);\n }\n\n /**\n * Allows to change a nested value in a copy of the provided object.
\n * The function will delegate the \"set action\" to {@link module:lamb.setIn|setIn} or\n * {@link module:lamb.setAt|setAt} depending on the value encountered in the path,\n * so please refer to the documentation of those functions for specifics about the\n * implementation.
\n * Note anyway that the distinction will be between Arrays, delegated\n * to {@link module:lamb.setAt|setAt}, and everything else (including array-like objects),\n * which will be delegated to {@link module:lamb.setIn|setIn}.
\n * As a result of that, array-like objects will be converted to objects having numbers as keys\n * and paths targeting non-object values will be converted to empty objects.
\n * You can anyway target array elements using integers in the path, even negative ones, but\n * the priority will be given to existing, and enumerable, object keys.
\n * Non-enumerable properties encountered in the path will be considered as non-existent properties.
\n * Like {@link module:lamb.getPathIn|getPathIn} or {@link module:lamb.getPath|getPath} you can\n * use custom path separators.\n * @example\n * var user = {id: 1, status: {active : false, scores: [2, 4, 6]}};\n *\n * _.setPathIn(user, \"status.active\", true) // => {id: 1, status: {active : true, scores: [2, 4, 6]}}\n *\n * @example Targeting arrays:\n * _.setPathIn(user, \"status.scores.0\", 8) // => {id: 1, status: {active : false, scores: [8, 4, 6]}}\n *\n * // you can use negative indexes as well\n * _.setPathIn(user, \"status.scores.-1\", 8) // => {id: 1, status: {active : false, scores: [2, 4, 8]}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.setPathIn(user, \"scores.0.value\", 8);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 8, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPath|setPath}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function setPathIn (source, path, value, separator) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setPathIn(source, _toPathParts(path, separator), value);\n }\n\n /**\n * Builds a partial application of {@link module:lamb.setPathIn|setPathIn} expecting the\n * object to act upon.
\n * See {@link module:lamb.setPathIn|setPathIn} for more details and examples.\n * @example\n * var user = {id: 1, status: {active: false}};\n * var activate = _.setPath(\"status.active\", true);\n *\n * activate(user) // => {id: 1, status: {active: true}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPathIn|setPathIn}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function setPath (path, value, separator) {\n return function (source) {\n return setPathIn(source, path, value, separator);\n };\n }\n\n /**\n * Returns a copy of the source object without the specified properties.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.skip(user, [\"name\", \"age\"]) // => {surname: \"doe\"};\n * _.skip(user, [\"name\", \"email\"]) // => {surname: \"doe\", age: 30};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.skipKeys|skipKeys}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} blacklist\n * @returns {Object}\n */\n function skip (source, blacklist) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n var props = make(blacklist, []);\n\n for (var key in source) {\n if (!(key in props)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be omitted in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var skipIfIstring = _.skipIf(_.isType(\"String\"));\n *\n * skipIfIstring(user) // => {age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n var skipIf = compose(pickIf, not);\n\n /**\n * A curried version of {@link module:lamb.skip|skip}, expecting a blacklist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.skipKeys([\"name\", \"surname\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var discard = _.compose(_.mapWith, _.skipKeys);\n * var discardNames = discard([\"name\", \"surname\"]);\n *\n * discardNames(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.35.0\n * @param {String[]} blacklist\n * @returns {Function}\n */\n var skipKeys = _curry2(skip, true);\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create an array containing a list\n * of the keys in its first index and the corresponding list of values\n * in the second one.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _tearFrom = _curry2(function (getKeys, obj) {\n return reduce(getKeys(obj), function (result, key) {\n result[0].push(key);\n result[1].push(obj[key]);\n\n return result;\n }, [[], []]);\n });\n\n /**\n * Tears an object apart by transforming it in an array of two lists: one containing\n * its enumerable keys, the other containing the corresponding values.
\n * Although this \"tearing apart\" may sound as a rather violent process, the source\n * object will be unharmed.\n * @example\n * _.tear({a: 1, b: 2, c: 3}) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tearOwn|tearOwn}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tear = _tearFrom(enumerables);\n\n /**\n * Same as {@link module:lamb.tear|tear}, but only the own properties of the object are\n * taken into account.\n * @example Showing the difference with tear:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.tear(foo) // => [[\"c\", \"b\", \"a\"], [3, 2, 1]]\n * _.tearOwn(foo) // => [[\"c\"], [3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tear|tear}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tearOwn = _tearFrom(keys);\n\n /**\n * Creates a copy of the given object having the desired key value updated by applying\n * the provided function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIn(user, \"name\", toUpperCase) // => {name: \"JOHN\", visits: 2}\n * _.updateIn(user, \"surname\", toUpperCase) // => {name: \"John\", visits: 2}\n *\n * @example Non-enumerable properties will be treated as non-existent:\n * var user = Object.create({name: \"John\"}, {visits: {value: 2}});\n *\n * _.updateIn(user, \"visits\", _.add(1)) // => {name: \"John\", visits: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updateKey|updateKey}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {Object} source\n * @param {String} key\n * @param {Function} updater\n * @returns {Object}\n */\n function updateIn (source, key, updater) {\n return _isEnumerable(source, key)\n ? _setIn(source, key, updater(source[key]))\n : _merge(enumerables, source, {});\n }\n\n /**\n * Builds a partial application of {@link module:lamb.updateIn|updateIn} with the provided\n * key and updater, expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var incrementVisits = _.updateKey(\"visits\", _.add(1));\n *\n * incrementVisits(user) // => {name: \"John\", visits: 3}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.updateIn|updateIn}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {String} key\n * @param {Function} updater\n * @returns {Function}\n */\n var updateKey = _makePartial3(updateIn);\n\n /**\n * Allows to change a nested value in a copy of the given object by applying the provided\n * function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var inc = _.add(1);\n *\n * _.updatePathIn(user, \"status.visits\", inc) // => {id: 1, status: {scores: [2, 4, 6]}, visits: 1}\n *\n * @example Targeting arrays:\n * _.updatePathIn(user, \"status.scores.0\", inc) // => {id: 1, status: {scores: [3, 4, 6], visits: 0}}\n *\n * // you can use negative indexes as well\n * _.updatePathIn(user, \"status.scores.-1\", inc) // => {id: 1, status: {scores: [2, 4, 7], visits: 0}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.updatePathIn(user, \"scores.0.value\", inc);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 3, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePath|updatePath}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function updatePathIn (source, path, updater, separator) {\n var parts = _toPathParts(path, separator);\n var pathInfo = _getPathInfo(source, parts, false);\n\n if (pathInfo.isValid) {\n return _setPathIn(source, parts, updater(pathInfo.target));\n } else {\n return Array.isArray(source) ? slice(source, 0, source.length) : _merge(enumerables, source, {});\n }\n }\n\n /**\n * Builds a partial application of {@link module:lamb.updatePathIn|updatePathIn}\n * expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var incrementScores = _.updatePath(\"status.scores\", _.mapWith(_.add(1)))\n *\n * incrementScores(user) // => {id: 1, status: {scores: [3, 5, 7], visits: 0}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePathIn|updatePathIn}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function updatePath (path, updater, separator) {\n return function (source) {\n return updatePathIn(source, path, updater, separator);\n };\n }\n\n /**\n * Validates an object with the given list of {@link module:lamb.checker|checker} functions.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * _.validate(user1, userCheckers) // => []\n * _.validate(user2, userCheckers) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validateWith|validateWith}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Object} obj\n * @param {Function[]} checkers\n * @returns {Array>} An array of errors in the form returned by\n * {@link module:lamb.checker|checker}, or an empty array.\n */\n function validate (obj, checkers) {\n return reduce(checkers, function (errors, _checker) {\n var result = _checker(obj);\n\n result.length && errors.push(result);\n\n return errors;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.validate|validate} accepting a list of\n * {@link module:lamb.checker|checkers} and returning a function expecting the object to validate.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n * var validateUser = _.validateWith(userCheckers);\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * validateUser(user1) // => []\n * validateUser(user2) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.validate|validate}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Function[]} checkers\n * @returns {Function}\n */\n var validateWith = _curry2(validate, true);\n\n /**\n * Generates an array with the values of the enumerable properties of the given object.
\n * See also {@link module:lamb.ownValues|ownValues} to pick only from the own properties of the object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.values(user) // => [\"john\", \"doe\", 30]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownValues|ownValues}\n * @since 0.1.0\n * @param {Object} obj\n * @returns {Array}\n */\n var values = _valuesFrom(enumerables);\n\n /**\n * A null-safe function to repeat the source string the desired amount of times.\n * @private\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function _repeat (source, times) {\n var result = \"\";\n\n for (var i = 0; i < times; i++) {\n result += source;\n }\n\n return result;\n }\n\n /**\n * Builds the prefix or suffix to be used when padding a string.\n * @private\n * @param {String} source\n * @param {String} char\n * @param {Number} len\n * @returns {String}\n */\n function _getPadding (source, char, len) {\n if (!isNil(source) && type(source) !== \"String\") {\n source = String(source);\n }\n\n return _repeat(String(char)[0] || \"\", Math.ceil(len - source.length));\n }\n\n /**\n * Pads a string to the desired length with the given char starting from the beginning of the string.\n * @example\n * _.padLeft(\"foo\", \"-\", 0) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", -1) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", 5) // => \"--foo\"\n * _.padLeft(\"foo\", \"-\", 3) // => \"foo\"\n * _.padLeft(\"foo\", \"ab\", 7) // => \"aaaafoo\"\n * _.padLeft(\"foo\", \"\", 5) // => \"foo\"\n * _.padLeft(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padRight|padRight}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padLeft (source, char, len) {\n return _getPadding(source, char, len) + source;\n }\n\n /**\n * Pads a string to the desired length with the given char starting from the end of the string.\n * @example\n * _.padRight(\"foo\", \"-\", 0) // => \"foo\"\n * _.padRight(\"foo\", \"-\", -1) // => \"foo\"\n * _.padRight(\"foo\", \"-\", 5) // => \"foo--\"\n * _.padRight(\"foo\", \"-\", 3) // => \"foo\"\n * _.padRight(\"foo\", \"ab\", 7) // => \"fooaaaa\"\n * _.padRight(\"foo\", \"\", 5) // => \"foo\"\n * _.padRight(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padLeft|padLeft}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padRight (source, char, len) {\n return source + _getPadding(source, char, len);\n }\n\n /**\n * Builds a new string by repeating the source string the desired amount of times.
\n * Note that unlike the current ES6 proposal for\n * [String.prototype.repeat]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat},\n * this function doesn't throw a RangeError if times is negative,\n * but returns an empty string instead.\n * @example\n * _.repeat(\"Hello\", -1) // => \"\"\n * _.repeat(\"Hello\", 1) // => \"Hello\"\n * _.repeat(\"Hello\", 3) // => \"HelloHelloHello\"\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function repeat (source, times) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"string\");\n }\n\n return _repeat(source, Math.floor(times));\n }\n\n /**\n * A generic version of String.prototype.search\n * @private\n * @function\n * @param {String} s\n * @param {RegExp} pattern\n * @return {Number}\n */\n var _search = generic(String.prototype.search);\n\n /**\n * Builds a predicate expecting a string to test against the given regular expression pattern.\n * @example\n * var hasNumbersOnly = _.testWith(/^\\d+$/);\n *\n * hasNumbersOnly(\"123\") // => true\n * hasNumbersOnly(\"123 Kg\") // => false\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {RegExp} pattern\n * @returns {Function}\n */\n function testWith (pattern) {\n return function (s) {\n return _search(s, pattern) !== -1;\n };\n }\n\n /**\n * Accepts a constructor and builds a predicate expecting an object,\n * which will be tested to verify whether the prototype of the constructor\n * is in its prototype chain.
\n * Wraps in a convenient way the native\n * [instanceof]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof} operator.\n * @example\n * function SomeObjA () {}\n *\n * var a = new SomeObjA();\n * var sObj = new String(\"foo\");\n * var s = \"foo\";\n *\n * _.isInstanceOf(Object)(a) // => true\n * _.isInstanceOf(SomeObjA)(a) // => true\n *\n * _.isInstanceOf(Object)(sObj) // => true\n * _.isInstanceOf(String)(sObj) // => true\n *\n * _.isInstanceOf(Object)(s) // => false\n * _.isInstanceOf(String)(s) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.47.0\n * @param {*} constructor\n * @returns {Function}\n */\n function isInstanceOf (constructor) {\n return function (obj) {\n return obj instanceof constructor;\n };\n }\n\n /**\n * Builds a predicate that expects a value to check against the specified type.\n * @example\n * var isString = _.isType(\"String\");\n *\n * isString(\"Hello\") // => true\n * isString(new String(\"Hi\")) // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.type|type}\n * @since 0.1.0\n * @param {String} typeName\n * @returns {Function}\n */\n function isType (typeName) {\n return function (value) {\n return type(value) === typeName;\n };\n }\n\n exports.__ = __;\n exports.always = always;\n exports.areSVZ = areSVZ;\n exports.binary = binary;\n exports.clamp = clamp;\n exports.clampWithin = clampWithin;\n exports.compose = compose;\n exports.forEach = forEach;\n exports.generic = generic;\n exports.identity = identity;\n exports.isNil = isNil;\n exports.isNull = isNull;\n exports.isSVZ = isSVZ;\n exports.isUndefined = isUndefined;\n exports.map = map;\n exports.mapWith = mapWith;\n exports.partial = partial;\n exports.partialRight = partialRight;\n exports.reduce = reduce;\n exports.reduceWith = reduceWith;\n exports.slice = slice;\n exports.sliceAt = sliceAt;\n exports.type = type;\n exports.append = append;\n exports.appendTo = appendTo;\n exports.contains = contains;\n exports.count = count;\n exports.countBy = countBy;\n exports.difference = difference;\n exports.drop = drop;\n exports.dropFrom = dropFrom;\n exports.dropWhile = dropWhile;\n exports.every = every;\n exports.everyIn = everyIn;\n exports.filter = filter;\n exports.filterWith = filterWith;\n exports.find = find;\n exports.findIndex = findIndex;\n exports.findWhere = findWhere;\n exports.findIndexWhere = findIndexWhere;\n exports.flatMap = flatMap;\n exports.flatMapWith = flatMapWith;\n exports.flatten = flatten;\n exports.getAt = getAt;\n exports.getIndex = getIndex;\n exports.group = group;\n exports.groupBy = groupBy;\n exports.head = head;\n exports.index = index;\n exports.indexBy = indexBy;\n exports.init = init;\n exports.insert = insert;\n exports.insertAt = insertAt;\n exports.intersection = intersection;\n exports.isIn = isIn;\n exports.join = join;\n exports.joinWith = joinWith;\n exports.last = last;\n exports.list = list;\n exports.partition = partition;\n exports.partitionWith = partitionWith;\n exports.pluck = pluck;\n exports.pluckKey = pluckKey;\n exports.pull = pull;\n exports.pullFrom = pullFrom;\n exports.reduceRight = reduceRight;\n exports.reduceRightWith = reduceRightWith;\n exports.reverse = reverse;\n exports.rotate = rotate;\n exports.rotateBy = rotateBy;\n exports.setAt = setAt;\n exports.setIndex = setIndex;\n exports.shallowFlatten = shallowFlatten;\n exports.some = some;\n exports.someIn = someIn;\n exports.sort = sort;\n exports.sortedInsert = sortedInsert;\n exports.sorter = sorter;\n exports.sorterDesc = sorterDesc;\n exports.sortWith = sortWith;\n exports.tail = tail;\n exports.take = take;\n exports.takeFrom = takeFrom;\n exports.takeWhile = takeWhile;\n exports.transpose = transpose;\n exports.union = union;\n exports.unionBy = unionBy;\n exports.uniques = uniques;\n exports.uniquesBy = uniquesBy;\n exports.updateAt = updateAt;\n exports.updateIndex = updateIndex;\n exports.zip = zip;\n exports.zipWithIndex = zipWithIndex;\n exports.application = application;\n exports.apply = apply;\n exports.applyTo = applyTo;\n exports.asPartial = asPartial;\n exports.aritize = aritize;\n exports.collect = collect;\n exports.curry = curry;\n exports.curryable = curryable;\n exports.curryableRight = curryableRight;\n exports.curryRight = curryRight;\n exports.debounce = debounce;\n exports.flip = flip;\n exports.getArgAt = getArgAt;\n exports.invoker = invoker;\n exports.invokerOn = invokerOn;\n exports.mapArgs = mapArgs;\n exports.pipe = pipe;\n exports.tapArgs = tapArgs;\n exports.throttle = throttle;\n exports.unary = unary;\n exports.adapter = adapter;\n exports.allOf = allOf;\n exports.anyOf = anyOf;\n exports.areSame = areSame;\n exports.case = case_;\n exports.condition = condition;\n exports.gt = gt;\n exports.gte = gte;\n exports.is = is;\n exports.isGT = isGT;\n exports.isGTE = isGTE;\n exports.isLT = isLT;\n exports.isLTE = isLTE;\n exports.lt = lt;\n exports.lte = lte;\n exports.not = not;\n exports.unless = unless;\n exports.when = when;\n exports.add = add;\n exports.deduct = deduct;\n exports.divide = divide;\n exports.divideBy = divideBy;\n exports.generate = generate;\n exports.isFinite = isFinite_;\n exports.isInteger = isInteger;\n exports.isSafeInteger = isSafeInteger;\n exports.modulo = modulo;\n exports.multiply = multiply;\n exports.multiplyBy = multiplyBy;\n exports.randomInt = randomInt;\n exports.range = range;\n exports.remainder = remainder;\n exports.subtract = subtract;\n exports.sum = sum;\n exports.checker = checker;\n exports.enumerables = enumerables;\n exports.fromPairs = fromPairs;\n exports.getIn = getIn;\n exports.getKey = getKey;\n exports.getPath = getPath;\n exports.getPathIn = getPathIn;\n exports.has = has;\n exports.hasKey = hasKey;\n exports.hasOwn = hasOwn;\n exports.hasOwnKey = hasOwnKey;\n exports.hasKeyValue = hasKeyValue;\n exports.hasPathValue = hasPathValue;\n exports.immutable = immutable;\n exports.keys = keys;\n exports.keySatisfies = keySatisfies;\n exports.make = make;\n exports.mapValues = mapValues;\n exports.mapValuesWith = mapValuesWith;\n exports.merge = merge;\n exports.mergeOwn = mergeOwn;\n exports.ownPairs = ownPairs;\n exports.ownValues = ownValues;\n exports.pairs = pairs;\n exports.pathExists = pathExists;\n exports.pathExistsIn = pathExistsIn;\n exports.pathSatisfies = pathSatisfies;\n exports.pick = pick;\n exports.pickIf = pickIf;\n exports.pickKeys = pickKeys;\n exports.rename = rename;\n exports.renameKeys = renameKeys;\n exports.renameWith = renameWith;\n exports.setIn = setIn;\n exports.setKey = setKey;\n exports.setPath = setPath;\n exports.setPathIn = setPathIn;\n exports.skip = skip;\n exports.skipIf = skipIf;\n exports.skipKeys = skipKeys;\n exports.tear = tear;\n exports.tearOwn = tearOwn;\n exports.updateIn = updateIn;\n exports.updateKey = updateKey;\n exports.updatePath = updatePath;\n exports.updatePathIn = updatePathIn;\n exports.validate = validate;\n exports.validateWith = validateWith;\n exports.values = values;\n exports.padLeft = padLeft;\n exports.padRight = padRight;\n exports.repeat = repeat;\n exports.testWith = testWith;\n exports.isInstanceOf = isInstanceOf;\n exports.isType = isType;\n\n Object.defineProperty(exports, '__esModule', { value: true });\n\n}));\n"]} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index e3437fd..70e06ff 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,17 +1,17 @@ /* eslint-disable require-jsdoc */ -var gulp = require("gulp"); -var eslint = require("gulp-eslint"); -var jest = require("gulp-jest").default; -var rename = require("gulp-rename"); -var rollup = require("rollup"); -var sourcemaps = require("gulp-sourcemaps"); -var uglify = require("gulp-uglify"); - -var jestBaseConfig = require("./jest.config"); -var pkg = require("./package.json"); - -var intro = [ +const gulp = require("gulp"); +const eslint = require("gulp-eslint"); +const jest = require("jest-cli"); +const rename = require("gulp-rename"); +const rollup = require("rollup"); +const sourcemaps = require("gulp-sourcemaps"); +const uglify = require("gulp-uglify"); + +const jestBaseConfig = require("./jest.config"); +const pkg = require("./package.json"); + +const intro = [ "/**", "* @overview " + pkg.name + " - " + pkg.description, "* @author " + pkg.author.name + " <" + pkg.author.email + ">", @@ -32,66 +32,64 @@ gulp.task("set-test-env", cb => { /* build */ -gulp.task("build", function () { - return rollup.rollup({ input: "src/index.js" }).then(function (bundle) { - return bundle.write({ - banner: intro, - exports: "named", - file: "dist/lamb.js", - format: "umd", - freeze: false, - name: "lamb", - sourcemap: false, - strict: true - }); - }); -}); - -gulp.task("minify", gulp.series( - "build", - function () { - return gulp.src("dist/lamb.js") - .pipe(sourcemaps.init()) - .pipe(uglify({ output: { comments: "some" } })) - .pipe(rename({ extname: ".min.js" })) - .pipe(sourcemaps.write(".")) - .pipe(gulp.dest("dist")); - } +gulp.task("build", () => rollup + .rollup({ input: "src/index.js" }) + .then(bundle => bundle.write({ + banner: intro, + exports: "named", + file: "dist/lamb.js", + format: "umd", + freeze: false, + name: "lamb", + sourcemap: false, + strict: true + })) +); + +gulp.task("minify", gulp.series("build", () => gulp.src("dist/lamb.js") + .pipe(sourcemaps.init()) + .pipe(uglify({ output: { comments: "some" } })) + .pipe(rename({ extname: ".min.js" })) + .pipe(sourcemaps.write(".")) + .pipe(gulp.dest("dist")) )); /* lint */ -function lintWith (settings) { - return function () { - return gulp.src(settings.inputs) - .pipe(eslint(settings.configPath)) - .pipe(eslint.format()) - .pipe(eslint.failAfterError()); - }; -} +const lintWith = settings => () => gulp.src(settings.inputs) + .pipe(eslint(settings.configPath)) + .pipe(eslint.format()) + .pipe(eslint.failAfterError()); gulp.task("lint:code", lintWith({ configPath: ".eslintrc.json", - inputs: ["./*.js", "./src/**/*.js", "!./src/**/__{tests,mocks}__/**"] + inputs: ["./src/**/*.js", "!./src/**/__{tests,mocks}__/**"] })); gulp.task("lint:tests", lintWith({ configPath: ".eslintrc.test.json", - inputs: "./src/**/__{tests,mocks}__/**/*.js" + inputs: ["./*.js", "./src/**/__{tests,mocks}__/**/*.js"] })); gulp.task("lint", gulp.series("lint:code", "lint:tests")); /* test */ -function testWith (extraSettings) { - return gulp.series( - "set-test-env", - function () { - return gulp.src("./src").pipe(jest(Object.assign({}, jestBaseConfig, extraSettings))); +const testWith = extraSettings => gulp.series( + "set-test-env", + () => jest.runCLI( + Object.assign({}, jestBaseConfig, extraSettings), + [jestBaseConfig.rootDir] + ).then(({ results }) => { // eslint-disable-line consistent-return + if (!results.success) { + const message = results.numFailedTests || results.numFailedTestSuites + ? "Tests failed" + : "Coverage threshold not met"; + + return Promise.reject(new Error(message)); } - ); -} + }) +); gulp.task("test", testWith({})); diff --git a/package-lock.json b/package-lock.json index 3626a54..f7f6c09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lamb", - "version": "0.58.0-alpha.1", + "version": "0.58.0-alpha.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -14,27 +14,74 @@ } }, "@babel/core": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.2.2.tgz", - "integrity": "sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.3.4.tgz", + "integrity": "sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.2.2", + "@babel/generator": "^7.3.4", "@babel/helpers": "^7.2.0", - "@babel/parser": "^7.2.2", + "@babel/parser": "^7.3.4", "@babel/template": "^7.2.2", - "@babel/traverse": "^7.2.2", - "@babel/types": "^7.2.2", + "@babel/traverse": "^7.3.4", + "@babel/types": "^7.3.4", "convert-source-map": "^1.1.0", "debug": "^4.1.0", "json5": "^2.1.0", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "dependencies": { + "@babel/generator": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", + "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.3.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/parser": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", + "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", + "dev": true + }, + "@babel/traverse": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", + "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.3.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.3.4", + "@babel/types": "^7.3.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + } + }, + "@babel/types": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", + "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -44,6 +91,12 @@ "ms": "^2.1.1" } }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -887,6 +940,16 @@ "to-fast-properties": "^2.0.0" } }, + "@cnakazawa/watch": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", + "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, "@gulp-sourcemaps/identity-map": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz", @@ -918,18 +981,415 @@ "through2": "^2.0.3" } }, + "@jest/console": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.3.0.tgz", + "integrity": "sha512-NaCty/OOei6rSDcbPdMiCbYCI0KGFGPgGO6B09lwWt5QTxnkuhKYET9El5u5z1GAcSxkQmSMtM63e24YabCWqA==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "@types/node": "*", + "chalk": "^2.0.1", + "slash": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@jest/core": { + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.3.1.tgz", + "integrity": "sha512-orucOIBKfXgm1IJirtPT0ToprqDVGYKUNJKNc9a6v1Lww6qLPq+xj5OfxyhpJb2rWOgzEkATW1bfZzg3oqV70w==", + "dev": true, + "requires": { + "@jest/console": "^24.3.0", + "@jest/reporters": "^24.3.1", + "@jest/test-result": "^24.3.0", + "@jest/transform": "^24.3.1", + "@jest/types": "^24.3.0", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-changed-files": "^24.3.0", + "jest-config": "^24.3.1", + "jest-haste-map": "^24.3.1", + "jest-message-util": "^24.3.0", + "jest-regex-util": "^24.3.0", + "jest-resolve-dependencies": "^24.3.1", + "jest-runner": "^24.3.1", + "jest-runtime": "^24.3.1", + "jest-snapshot": "^24.3.1", + "jest-util": "^24.3.0", + "jest-validate": "^24.3.1", + "jest-watcher": "^24.3.0", + "micromatch": "^3.1.10", + "p-each-series": "^1.0.0", + "pirates": "^4.0.1", + "realpath-native": "^1.1.0", + "rimraf": "^2.5.4", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "strip-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.1.0.tgz", + "integrity": "sha512-TjxrkPONqO2Z8QDCpeE2j6n0M6EwxzyDgzEeGp+FbdvaJAt//ClYi6W5my+3ROlC/hZX2KACUwDfK49Ka5eDvg==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@jest/environment": { + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.3.1.tgz", + "integrity": "sha512-M8bqEkQqPwZVhMMFMqqCnzqIZtuM5vDMfFQ9ZvnEfRT+2T1zTA4UAOH/V4HagEi6S3BCd/mdxFdYmPgXf7GKCA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^24.3.0", + "@jest/transform": "^24.3.1", + "@jest/types": "^24.3.0", + "@types/node": "*", + "jest-mock": "^24.3.0" + } + }, + "@jest/fake-timers": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.3.0.tgz", + "integrity": "sha512-rHwVI17dGMHxHzfAhnZ04+wFznjFfZ246QugeBnbiYr7/bDosPD2P1qeNjWnJUUcfl0HpS6kkr+OB/mqSJxQFg==", + "dev": true, + "requires": { + "@jest/types": "^24.3.0", + "@types/node": "*", + "jest-message-util": "^24.3.0", + "jest-mock": "^24.3.0" + } + }, + "@jest/reporters": { + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.3.1.tgz", + "integrity": "sha512-jEIDJcvk20ReUW1Iqb+prlAcFV+kfFhQ/01poCq8X9As7/l/2y1GqVwJ3+6SaPTZuCXh0d0LVDy86zDAa8zlVA==", + "dev": true, + "requires": { + "@jest/environment": "^24.3.1", + "@jest/test-result": "^24.3.0", + "@jest/transform": "^24.3.1", + "@jest/types": "^24.3.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "istanbul-api": "^2.1.1", + "istanbul-lib-coverage": "^2.0.2", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-source-maps": "^3.0.1", + "jest-haste-map": "^24.3.1", + "jest-resolve": "^24.3.1", + "jest-runtime": "^24.3.1", + "jest-util": "^24.3.0", + "jest-worker": "^24.3.1", + "node-notifier": "^5.2.1", + "slash": "^2.0.0", + "source-map": "^0.6.0", + "string-length": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@jest/source-map": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.3.0.tgz", + "integrity": "sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.1.15", + "source-map": "^0.6.0" + }, + "dependencies": { + "callsites": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz", + "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/test-result": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.3.0.tgz", + "integrity": "sha512-j7UZ49T8C4CVipEY99nLttnczVTtLyVzFfN20OiBVn7awOs0U3endXSTq7ouPrLR5y4YjI5GDcbcvDUjgeamzg==", + "dev": true, + "requires": { + "@jest/console": "^24.3.0", + "@jest/types": "^24.3.0", + "@types/istanbul-lib-coverage": "^1.1.0" + } + }, + "@jest/transform": { + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.3.1.tgz", + "integrity": "sha512-PpjylI5goT4Si69+qUjEeHuKjex0LjjrqJzrMYzlOZn/+SCumGKuGC0UQFeEPThyGsFvWH1Q4gj0R66eOHnIpw==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.3.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.3.1", + "jest-regex-util": "^24.3.0", + "jest-util": "^24.3.0", + "micromatch": "^3.1.10", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@jest/types": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.3.0.tgz", + "integrity": "sha512-VoO1F5tU2n/93QN/zaZ7Q8SeV/Rj+9JJOgbvKbBwy4lenvmdj1iDaQEPXGTKrO6OSvDeb2drTFipZJYxgo6kIQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^1.1.0", + "@types/yargs": "^12.0.9" + } + }, + "@types/babel__core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.0.tgz", + "integrity": "sha512-wJTeJRt7BToFx3USrCDs2BhEi4ijBInTQjOIukj6a/5tEkwpFMVZ+1ppgmE+Q/FQyc5P/VWUbx7I9NELrKruHA==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.0.2.tgz", + "integrity": "sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.6.tgz", + "integrity": "sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, "@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, + "@types/istanbul-lib-coverage": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz", + "integrity": "sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ==", + "dev": true + }, "@types/node": { "version": "11.10.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-11.10.5.tgz", "integrity": "sha512-DuIRlQbX4K+d5I+GMnv+UfnGh+ist0RdlvOp+JZ7ePJ6KQONCFQv/gKYSU1ZzbVdFSUCKZOltjmpFAGGv5MdYA==", "dev": true }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/yargs": { + "version": "12.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-12.0.9.tgz", + "integrity": "sha512-sCZy4SxP9rN2w30Hlmg5dtdRwgYQfYRiLo9usw8X9cxlf+H4FqM1xX7+sNH7NNKVdbXMJWqva7iyy+fxh/V7fA==", + "dev": true + }, "abab": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", @@ -953,9 +1413,9 @@ }, "dependencies": { "acorn": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.0.tgz", - "integrity": "sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", "dev": true } } @@ -1238,12 +1698,20 @@ "dev": true }, "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "^4.17.11" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + } } }, "async-done": { @@ -1323,13 +1791,16 @@ } }, "babel-jest": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.1.0.tgz", - "integrity": "sha512-MLcagnVrO9ybQGLEfZUqnOzv36iQzU7Bj4elm39vCukumLVSfoX+tRy3/jW7lUKc7XdpRmB/jech6L/UCsSZjw==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.3.1.tgz", + "integrity": "sha512-6KaXyUevY0KAxD5Ba+EBhyfwvc+R2f7JV7BpBZ5T8yJGgj0M1hYDfRhDq35oD5MzprMf/ggT81nEuLtMyxfDIg==", "dev": true, "requires": { + "@jest/transform": "^24.3.1", + "@jest/types": "^24.3.0", + "@types/babel__core": "^7.1.0", "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.1.0", + "babel-preset-jest": "^24.3.0", "chalk": "^2.4.2", "slash": "^2.0.0" }, @@ -1366,9 +1837,9 @@ } }, "babel-plugin-istanbul": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.0.tgz", - "integrity": "sha512-CLoXPRSUWiR8yao8bShqZUIC6qLfZVVY3X1wj+QPNXu0wfmrRRfarh1LYy+dYMVI+bDj0ghy3tuqFFRFZmL1Nw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.1.tgz", + "integrity": "sha512-RNNVv2lsHAXJQsEJ5jonQwrJVWK8AcZpG1oxhnjCUaAjL7xahYLANhPUZbzEQHjKy1NMYUwn+0NPKQc8iSY4xQ==", "dev": true, "requires": { "find-up": "^3.0.0", @@ -1388,19 +1859,22 @@ } }, "babel-plugin-jest-hoist": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.1.0.tgz", - "integrity": "sha512-gljYrZz8w1b6fJzKcsfKsipSru2DU2DmQ39aB6nV3xQ0DDv3zpIzKGortA5gknrhNnPN8DweaEgrnZdmbGmhnw==", - "dev": true + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.3.0.tgz", + "integrity": "sha512-nWh4N1mVH55Tzhx2isvUN5ebM5CDUvIpXPZYMRazQughie/EqGnbR+czzoQlhUmJG9pPJmYDRhvocotb2THl1w==", + "dev": true, + "requires": { + "@types/babel__traverse": "^7.0.6" + } }, "babel-preset-jest": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.1.0.tgz", - "integrity": "sha512-FfNLDxFWsNX9lUmtwY7NheGlANnagvxq8LZdl5PKnVG3umP+S/g0XbVBfwtA4Ai3Ri/IMkWabBz3Tyk9wdspcw==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.3.0.tgz", + "integrity": "sha512-VGTV2QYBa/Kn3WCOKdfS31j9qomaXSgJqi65B6o05/1GsJyj9LVhSljM9ro4S+IBGj/ENhNBuH9bpqzztKAQSw==", "dev": true, "requires": { "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.1.0" + "babel-plugin-jest-hoist": "^24.3.0" } }, "bach": { @@ -1630,9 +2104,9 @@ "dev": true }, "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", + "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==", "dev": true }, "caniuse-lite": { @@ -2050,9 +2524,9 @@ "dev": true }, "cssstyle": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.1.1.tgz", - "integrity": "sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.1.tgz", + "integrity": "sha512-7DYm8qe+gPx/h77QlCyFmX80+fGaE/6A/Ekl0zaszYOubvySO2saYFdQ78P29D0UsULxFKCetDGNaNRUdSF+2A==", "dev": true, "requires": { "cssom": "0.3.x" @@ -2280,9 +2754,9 @@ "dev": true }, "diff-sequences": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.0.0.tgz", - "integrity": "sha512-46OkIuVGBBnrC0soO/4LHu5LHGHx0uhP65OVz8XOrAJpqiCB2aVIuESvjI1F9oqebuvY8lekS1pt6TN7vt7qsw==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.3.0.tgz", + "integrity": "sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw==", "dev": true }, "doctrine": { @@ -2477,9 +2951,9 @@ "dev": true }, "escodegen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", - "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz", + "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==", "dev": true, "requires": { "esprima": "^3.1.3", @@ -2752,13 +3226,10 @@ } }, "exec-sh": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz", - "integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==", - "dev": true, - "requires": { - "merge": "^1.2.0" - } + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.2.tgz", + "integrity": "sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg==", + "dev": true }, "execa": { "version": "1.0.0", @@ -2826,16 +3297,17 @@ } }, "expect": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.1.0.tgz", - "integrity": "sha512-lVcAPhaYkQcIyMS+F8RVwzbm1jro20IG8OkvxQ6f1JfqhVZyyudCwYogQ7wnktlf14iF3ii7ArIUO/mqvrW9Gw==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.3.1.tgz", + "integrity": "sha512-xnmobSlaqhg4FKqjb5REk4AobQzFMJoctDdREKfSGqrtzRfCWYbfqt3WmikAvQz/J8mCNQhORgYdEjPMJbMQPQ==", "dev": true, "requires": { + "@jest/types": "^24.3.0", "ansi-styles": "^3.2.0", - "jest-get-type": "^24.0.0", - "jest-matcher-utils": "^24.0.0", - "jest-message-util": "^24.0.0", - "jest-regex-util": "^24.0.0" + "jest-get-type": "^24.3.0", + "jest-matcher-utils": "^24.3.1", + "jest-message-util": "^24.3.0", + "jest-regex-util": "^24.3.0" }, "dependencies": { "ansi-styles": { @@ -4154,16 +4626,6 @@ "plugin-error": "^1.0.1" } }, - "gulp-jest": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp-jest/-/gulp-jest-4.0.2.tgz", - "integrity": "sha512-+ir9/nZCQQDwjBC4XZObJ8Xx1Ks5bMFLYnJbGL+67Bx1y8uclMMFk8USMM2zuR7yu4yg5GwRuG5he4JthMxVlw==", - "dev": true, - "requires": { - "plugin-error": "^1.0.1", - "through2": "^2.0.1" - } - }, "gulp-rename": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.4.0.tgz", @@ -4831,9 +5293,9 @@ "dev": true }, "istanbul-api": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.0.tgz", - "integrity": "sha512-+Ygg4t1StoiNlBGc6x0f8q/Bv26FbZqP/+jegzfNpU7Q8o+4ZRoJxJPhBkgE/UonpAjtxnE4zCZIyJX+MwLRMQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.1.tgz", + "integrity": "sha512-kVmYrehiwyeBAk/wE71tW6emzLiHGjYIiDrc8sfyty4F8M02/lrgXSm+R1kXysmF20zArvmZXjlE/mg24TVPJw==", "dev": true, "requires": { "async": "^2.6.1", @@ -4844,7 +5306,7 @@ "istanbul-lib-instrument": "^3.1.0", "istanbul-lib-report": "^2.0.4", "istanbul-lib-source-maps": "^3.0.2", - "istanbul-reports": "^2.1.0", + "istanbul-reports": "^2.1.1", "js-yaml": "^3.12.0", "make-dir": "^1.3.0", "minimatch": "^3.0.4", @@ -4852,9 +5314,9 @@ }, "dependencies": { "js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", + "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -4969,76 +5431,46 @@ } }, "istanbul-reports": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.1.0.tgz", - "integrity": "sha512-azQdSX+dtTtkQEfqq20ICxWi6eOHXyHIgMFw1VOOVi8iIPWeCWRgCyFh/CsBKIhcgskMI8ExXmU7rjXTRCIJ+A==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.1.1.tgz", + "integrity": "sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw==", "dev": true, "requires": { - "handlebars": "^4.0.11" + "handlebars": "^4.1.0" } }, "jest-changed-files": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.0.0.tgz", - "integrity": "sha512-nnuU510R9U+UX0WNb5XFEcsrMqriSiRLeO9KWDFgPrpToaQm60prfQYpxsXigdClpvNot5bekDY440x9dNGnsQ==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.3.0.tgz", + "integrity": "sha512-fTq0YAUR6644fgsqLC7Zi2gXA/bAplMRvfXQdutmkwgrCKK6upkj+sgXqsUfUZRm15CVr3YSojr/GRNn71IMvg==", "dev": true, "requires": { + "@jest/types": "^24.3.0", "execa": "^1.0.0", "throat": "^4.0.0" } }, "jest-cli": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.1.0.tgz", - "integrity": "sha512-U/iyWPwOI0T1CIxVLtk/2uviOTJ/OiSWJSe8qt6X1VkbbgP+nrtLJlmT9lPBe4lK78VNFJtrJ7pttcNv/s7yCw==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.3.1.tgz", + "integrity": "sha512-HdwMgigvDQdlWX7gwM2QMkJJRqSk7tTYKq7kVplblK28RarqquJMWV/lOCN8CukuG9u3DZTeXpCDXR7kpGfB3w==", "dev": true, "requires": { - "ansi-escapes": "^3.0.0", + "@jest/core": "^24.3.1", + "@jest/test-result": "^24.3.0", + "@jest/types": "^24.3.0", "chalk": "^2.0.1", "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.1.15", "import-local": "^2.0.0", "is-ci": "^2.0.0", - "istanbul-api": "^2.0.8", - "istanbul-lib-coverage": "^2.0.2", - "istanbul-lib-instrument": "^3.0.1", - "istanbul-lib-source-maps": "^3.0.1", - "jest-changed-files": "^24.0.0", - "jest-config": "^24.1.0", - "jest-environment-jsdom": "^24.0.0", - "jest-get-type": "^24.0.0", - "jest-haste-map": "^24.0.0", - "jest-message-util": "^24.0.0", - "jest-regex-util": "^24.0.0", - "jest-resolve-dependencies": "^24.1.0", - "jest-runner": "^24.1.0", - "jest-runtime": "^24.1.0", - "jest-snapshot": "^24.1.0", - "jest-util": "^24.0.0", - "jest-validate": "^24.0.0", - "jest-watcher": "^24.0.0", - "jest-worker": "^24.0.0", - "micromatch": "^3.1.10", - "node-notifier": "^5.2.1", - "p-each-series": "^1.0.0", - "pirates": "^4.0.0", + "jest-config": "^24.3.1", + "jest-util": "^24.3.0", + "jest-validate": "^24.3.1", "prompts": "^2.0.1", - "realpath-native": "^1.0.0", - "rimraf": "^2.5.4", - "slash": "^2.0.0", - "string-length": "^2.0.0", - "strip-ansi": "^5.0.0", - "which": "^1.2.12", + "realpath-native": "^1.1.0", "yargs": "^12.0.2" }, "dependencies": { - "ansi-regex": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", - "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", - "dev": true - }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -5059,21 +5491,6 @@ "supports-color": "^5.3.0" } }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, - "strip-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", - "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", - "dev": true, - "requires": { - "ansi-regex": "^4.0.0" - } - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -5086,26 +5503,27 @@ } }, "jest-config": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.1.0.tgz", - "integrity": "sha512-FbbRzRqtFC6eGjG5VwsbW4E5dW3zqJKLWYiZWhB0/4E5fgsMw8GODLbGSrY5t17kKOtCWb/Z7nsIThRoDpuVyg==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.3.1.tgz", + "integrity": "sha512-ujHQywsM//vKFvJwEC02KNZgKAGOzGz1bFPezmTQtuj8XdfsAVq8p6N/dw4yodXV11gSf6TJ075i4ehM+mKatA==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "babel-jest": "^24.1.0", + "@jest/types": "^24.3.0", + "babel-jest": "^24.3.1", "chalk": "^2.0.1", "glob": "^7.1.1", - "jest-environment-jsdom": "^24.0.0", - "jest-environment-node": "^24.0.0", - "jest-get-type": "^24.0.0", - "jest-jasmine2": "^24.1.0", - "jest-regex-util": "^24.0.0", - "jest-resolve": "^24.1.0", - "jest-util": "^24.0.0", - "jest-validate": "^24.0.0", + "jest-environment-jsdom": "^24.3.1", + "jest-environment-node": "^24.3.1", + "jest-get-type": "^24.3.0", + "jest-jasmine2": "^24.3.1", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.3.1", + "jest-util": "^24.3.0", + "jest-validate": "^24.3.1", "micromatch": "^3.1.10", - "pretty-format": "^24.0.0", - "realpath-native": "^1.0.2" + "pretty-format": "^24.3.1", + "realpath-native": "^1.1.0" }, "dependencies": { "ansi-styles": { @@ -5140,15 +5558,15 @@ } }, "jest-diff": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.0.0.tgz", - "integrity": "sha512-XY5wMpRaTsuMoU+1/B2zQSKQ9RdE9gsLkGydx3nvApeyPijLA8GtEvIcPwISRCer+VDf9W1mStTYYq6fPt8ryA==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.3.1.tgz", + "integrity": "sha512-YRVzDguyzShP3Pb9wP/ykBkV7Z+O4wltrMZ2P4LBtNxrHNpxwI2DECrpD9XevxWubRy5jcE8sSkxyX3bS7W+rA==", "dev": true, "requires": { "chalk": "^2.0.1", - "diff-sequences": "^24.0.0", - "jest-get-type": "^24.0.0", - "pretty-format": "^24.0.0" + "diff-sequences": "^24.3.0", + "jest-get-type": "^24.3.0", + "pretty-format": "^24.3.1" }, "dependencies": { "ansi-styles": { @@ -5183,24 +5601,25 @@ } }, "jest-docblock": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.0.0.tgz", - "integrity": "sha512-KfAKZ4SN7CFOZpWg4i7g7MSlY0M+mq7K0aMqENaG2vHuhC9fc3vkpU/iNN9sOus7v3h3Y48uEjqz3+Gdn2iptA==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.3.0.tgz", + "integrity": "sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg==", "dev": true, "requires": { "detect-newline": "^2.1.0" } }, "jest-each": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.0.0.tgz", - "integrity": "sha512-gFcbY4Cu55yxExXMkjrnLXov3bWO3dbPAW7HXb31h/DNWdNc/6X8MtxGff8nh3/MjkF9DpVqnj0KsPKuPK0cpA==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.3.1.tgz", + "integrity": "sha512-GTi+nxDaWwSgOPLiiqb/p4LURy0mv3usoqsA2eoTYSmRsLgjgZ6VUyRpUBH5JY9EMBx33suNFXk0iyUm29WRpw==", "dev": true, "requires": { + "@jest/types": "^24.3.0", "chalk": "^2.0.1", - "jest-get-type": "^24.0.0", - "jest-util": "^24.0.0", - "pretty-format": "^24.0.0" + "jest-get-type": "^24.3.0", + "jest-util": "^24.3.0", + "pretty-format": "^24.3.1" }, "dependencies": { "ansi-styles": { @@ -5235,46 +5654,53 @@ } }, "jest-environment-jsdom": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.0.0.tgz", - "integrity": "sha512-1YNp7xtxajTRaxbylDc2pWvFnfDTH5BJJGyVzyGAKNt/lEULohwEV9zFqTgG4bXRcq7xzdd+sGFws+LxThXXOw==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.3.1.tgz", + "integrity": "sha512-rz2OSYJiQerDqWDwjisqRwhVNpwkqFXdtyMzEuJ47Ip9NRpRQ+qy7/+zFujPUy/Z+zjWRO5seHLB/dOD4VpEVg==", "dev": true, "requires": { - "jest-mock": "^24.0.0", - "jest-util": "^24.0.0", + "@jest/environment": "^24.3.1", + "@jest/fake-timers": "^24.3.0", + "@jest/types": "^24.3.0", + "jest-mock": "^24.3.0", + "jest-util": "^24.3.0", "jsdom": "^11.5.1" } }, "jest-environment-node": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.0.0.tgz", - "integrity": "sha512-62fOFcaEdU0VLaq8JL90TqwI7hLn0cOKOl8vY2n477vRkCJRojiRRtJVRzzCcgFvs6gqU97DNqX5R0BrBP6Rxg==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.3.1.tgz", + "integrity": "sha512-Xy+/yFem/yUs9OkzbcawQT237vwDjBhAVLjac1KYAMYVjGb0Vb/Ovw4g61PunVdrEIpfcXNtRUltM4+9c7lARQ==", "dev": true, "requires": { - "jest-mock": "^24.0.0", - "jest-util": "^24.0.0" + "@jest/environment": "^24.3.1", + "@jest/fake-timers": "^24.3.0", + "@jest/types": "^24.3.0", + "jest-mock": "^24.3.0", + "jest-util": "^24.3.0" } }, "jest-get-type": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.0.0.tgz", - "integrity": "sha512-z6/Eyf6s9ZDGz7eOvl+fzpuJmN9i0KyTt1no37/dHu8galssxz5ZEgnc1KaV8R31q1khxyhB4ui/X5ZjjPk77w==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.3.0.tgz", + "integrity": "sha512-HYF6pry72YUlVcvUx3sEpMRwXEWGEPlJ0bSPVnB3b3n++j4phUEoSPcS6GC0pPJ9rpyPSe4cb5muFo6D39cXow==", "dev": true }, "jest-haste-map": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.0.0.tgz", - "integrity": "sha512-CcViJyUo41IQqttLxXVdI41YErkzBKbE6cS6dRAploCeutePYfUimWd3C9rQEWhX0YBOQzvNsC0O9nYxK2nnxQ==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.3.1.tgz", + "integrity": "sha512-OTMQle+astr1lWKi62Ccmk2YWn6OtUoU/8JpJdg8zdsnpFIry/k0S4sQ4nWocdM07PFdvqcthWc78CkCE6sXvA==", "dev": true, "requires": { + "@jest/types": "^24.3.0", "fb-watchman": "^2.0.0", "graceful-fs": "^4.1.15", "invariant": "^2.2.4", - "jest-serializer": "^24.0.0", - "jest-util": "^24.0.0", - "jest-worker": "^24.0.0", + "jest-serializer": "^24.3.0", + "jest-util": "^24.3.0", + "jest-worker": "^24.3.1", "micromatch": "^3.1.10", - "sane": "^3.0.0" + "sane": "^4.0.3" }, "dependencies": { "graceful-fs": { @@ -5286,22 +5712,26 @@ } }, "jest-jasmine2": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.1.0.tgz", - "integrity": "sha512-H+o76SdSNyCh9fM5K8upK45YTo/DiFx5w2YAzblQebSQmukDcoVBVeXynyr7DDnxh+0NTHYRCLwJVf3tC518wg==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.3.1.tgz", + "integrity": "sha512-STo6ar1IyPlIPq9jPxDQhM7lC0dAX7KKN0LmCLMlgJeXwX+1XiVdtZDv1a4zyg6qhNdpo1arOBGY0BcovUK7ug==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", + "@jest/environment": "^24.3.1", + "@jest/test-result": "^24.3.0", + "@jest/types": "^24.3.0", "chalk": "^2.0.1", "co": "^4.6.0", - "expect": "^24.1.0", + "expect": "^24.3.1", "is-generator-fn": "^2.0.0", - "jest-each": "^24.0.0", - "jest-matcher-utils": "^24.0.0", - "jest-message-util": "^24.0.0", - "jest-snapshot": "^24.1.0", - "jest-util": "^24.0.0", - "pretty-format": "^24.0.0", + "jest-each": "^24.3.1", + "jest-matcher-utils": "^24.3.1", + "jest-message-util": "^24.3.0", + "jest-runtime": "^24.3.1", + "jest-snapshot": "^24.3.1", + "jest-util": "^24.3.0", + "pretty-format": "^24.3.1", "throat": "^4.0.0" }, "dependencies": { @@ -5337,24 +5767,24 @@ } }, "jest-leak-detector": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.0.0.tgz", - "integrity": "sha512-ZYHJYFeibxfsDSKowjDP332pStuiFT2xfc5R67Rjm/l+HFJWJgNIOCOlQGeXLCtyUn3A23+VVDdiCcnB6dTTrg==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.3.1.tgz", + "integrity": "sha512-GncRwEtAw/SohdSyY4bk2RE06Ac1dZrtQGZQ2j35hSuN4gAAAKSYMszJS2WDixsAEaFN+GHBHG+d8pjVGklKyw==", "dev": true, "requires": { - "pretty-format": "^24.0.0" + "pretty-format": "^24.3.1" } }, "jest-matcher-utils": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.0.0.tgz", - "integrity": "sha512-LQTDmO+aWRz1Tf9HJg+HlPHhDh1E1c65kVwRFo5mwCVp5aQDzlkz4+vCvXhOKFjitV2f0kMdHxnODrXVoi+rlA==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.3.1.tgz", + "integrity": "sha512-P5VIsUTJeI0FYvWVMwEHjxK1L83vEkDiKMV0XFPIrT2jzWaWPB2+dPCHkP2ID9z4eUKElaHqynZnJiOdNVHfXQ==", "dev": true, "requires": { "chalk": "^2.0.1", - "jest-diff": "^24.0.0", - "jest-get-type": "^24.0.0", - "pretty-format": "^24.0.0" + "jest-diff": "^24.3.1", + "jest-get-type": "^24.3.0", + "pretty-format": "^24.3.1" }, "dependencies": { "ansi-styles": { @@ -5389,12 +5819,15 @@ } }, "jest-message-util": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.0.0.tgz", - "integrity": "sha512-J9ROJIwz/IeC+eV1XSwnRK4oAwPuhmxEyYx1+K5UI+pIYwFZDSrfZaiWTdq0d2xYFw4Xiu+0KQWsdsQpgJMf3Q==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.3.0.tgz", + "integrity": "sha512-lXM0YgKYGqN5/eH1NGw4Ix+Pk2I9Y77beyRas7xM24n+XTTK3TbT0VkT3L/qiyS7WkW0YwyxoXnnAaGw4hsEDA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.3.0", + "@jest/types": "^24.3.0", + "@types/stack-utils": "^1.0.1", "chalk": "^2.0.1", "micromatch": "^3.1.10", "slash": "^2.0.0", @@ -5433,26 +5866,30 @@ } }, "jest-mock": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.0.0.tgz", - "integrity": "sha512-sQp0Hu5fcf5NZEh1U9eIW2qD0BwJZjb63Yqd98PQJFvf/zzUTBoUAwv/Dc/HFeNHIw1f3hl/48vNn+j3STaI7A==", - "dev": true + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.3.0.tgz", + "integrity": "sha512-AhAo0qjbVWWGvcbW5nChFjR0ObQImvGtU6DodprNziDOt+pP0CBdht/sYcNIOXeim8083QUi9bC8QdKB8PTK4Q==", + "dev": true, + "requires": { + "@jest/types": "^24.3.0" + } }, "jest-regex-util": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.0.0.tgz", - "integrity": "sha512-Jv/uOTCuC+PY7WpJl2mpoI+WbY2ut73qwwO9ByJJNwOCwr1qWhEW2Lyi2S9ZewUdJqeVpEBisdEVZSI+Zxo58Q==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.3.0.tgz", + "integrity": "sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg==", "dev": true }, "jest-resolve": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.1.0.tgz", - "integrity": "sha512-TPiAIVp3TG6zAxH28u/6eogbwrvZjBMWroSLBDkwkHKrqxB/RIdwkWDye4uqPlZIXWIaHtifY3L0/eO5Z0f2wg==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.3.1.tgz", + "integrity": "sha512-N+Q3AcVuKxpn/kjQMxUVLwBk32ZE1diP4MPcHyjVwcKpCUuKrktfRR3Mqe/T2HoD25wyccstaqcPUKIudl41bg==", "dev": true, "requires": { + "@jest/types": "^24.3.0", "browser-resolve": "^1.11.3", "chalk": "^2.0.1", - "realpath-native": "^1.0.0" + "realpath-native": "^1.1.0" }, "dependencies": { "ansi-styles": { @@ -5487,33 +5924,39 @@ } }, "jest-resolve-dependencies": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.1.0.tgz", - "integrity": "sha512-2VwPsjd3kRPu7qe2cpytAgowCObk5AKeizfXuuiwgm1a9sijJDZe8Kh1sFj6FKvSaNEfCPlBVkZEJa2482m/Uw==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.3.1.tgz", + "integrity": "sha512-9JUejNImGnJjbNR/ttnod+zQIWANpsrYMPt18s2tYGK6rP191qFsyEQ2BhAQMdYDRkTmi8At+Co9tL+jTPqdpw==", "dev": true, "requires": { - "jest-regex-util": "^24.0.0", - "jest-snapshot": "^24.1.0" + "@jest/types": "^24.3.0", + "jest-regex-util": "^24.3.0", + "jest-snapshot": "^24.3.1" } }, "jest-runner": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.1.0.tgz", - "integrity": "sha512-CDGOkT3AIFl16BLL/OdbtYgYvbAprwJ+ExKuLZmGSCSldwsuU2dEGauqkpvd9nphVdAnJUcP12e/EIlnTX0QXg==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.3.1.tgz", + "integrity": "sha512-Etc9hQ5ruwg+q7DChm+E8qzHHdNTLeUdlo+whPQRSpNSgl0AEgc2r2mT4lxODREqmnHg9A8JHA44pIG4GE0Gzg==", "dev": true, "requires": { + "@jest/console": "^24.3.0", + "@jest/environment": "^24.3.1", + "@jest/test-result": "^24.3.0", + "@jest/types": "^24.3.0", "chalk": "^2.4.2", "exit": "^0.1.2", "graceful-fs": "^4.1.15", - "jest-config": "^24.1.0", - "jest-docblock": "^24.0.0", - "jest-haste-map": "^24.0.0", - "jest-jasmine2": "^24.1.0", - "jest-leak-detector": "^24.0.0", - "jest-message-util": "^24.0.0", - "jest-runtime": "^24.1.0", - "jest-util": "^24.0.0", - "jest-worker": "^24.0.0", + "jest-config": "^24.3.1", + "jest-docblock": "^24.3.0", + "jest-haste-map": "^24.3.1", + "jest-jasmine2": "^24.3.1", + "jest-leak-detector": "^24.3.1", + "jest-message-util": "^24.3.0", + "jest-resolve": "^24.3.1", + "jest-runtime": "^24.3.1", + "jest-util": "^24.3.0", + "jest-worker": "^24.3.1", "source-map-support": "^0.5.6", "throat": "^4.0.0" }, @@ -5556,32 +5999,33 @@ } }, "jest-runtime": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.1.0.tgz", - "integrity": "sha512-59/BY6OCuTXxGeDhEMU7+N33dpMQyXq7MLK07cNSIY/QYt2QZgJ7Tjx+rykBI0skAoigFl0A5tmT8UdwX92YuQ==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.3.1.tgz", + "integrity": "sha512-Qz/tJWbZ2naFJ2Kvy1p+RhhRgsPYh4e6wddVRy6aHBr32FTt3Ja33bfV7pkMFWXFbVuAsJMJVdengbvdhWzq4A==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "babel-plugin-istanbul": "^5.1.0", + "@jest/console": "^24.3.0", + "@jest/environment": "^24.3.1", + "@jest/source-map": "^24.3.0", + "@jest/transform": "^24.3.1", + "@jest/types": "^24.3.0", + "@types/yargs": "^12.0.2", "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", "exit": "^0.1.2", - "fast-json-stable-stringify": "^2.0.0", "glob": "^7.1.3", "graceful-fs": "^4.1.15", - "jest-config": "^24.1.0", - "jest-haste-map": "^24.0.0", - "jest-message-util": "^24.0.0", - "jest-regex-util": "^24.0.0", - "jest-resolve": "^24.1.0", - "jest-snapshot": "^24.1.0", - "jest-util": "^24.0.0", - "jest-validate": "^24.0.0", - "micromatch": "^3.1.10", - "realpath-native": "^1.0.0", + "jest-config": "^24.3.1", + "jest-haste-map": "^24.3.1", + "jest-message-util": "^24.3.0", + "jest-mock": "^24.3.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.3.1", + "jest-snapshot": "^24.3.1", + "jest-util": "^24.3.0", + "jest-validate": "^24.3.1", + "realpath-native": "^1.1.0", "slash": "^2.0.0", "strip-bom": "^3.0.0", - "write-file-atomic": "2.4.1", "yargs": "^12.0.2" }, "dependencies": { @@ -5623,26 +6067,28 @@ } }, "jest-serializer": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.0.0.tgz", - "integrity": "sha512-9FKxQyrFgHtx3ozU+1a8v938ILBE7S8Ko3uiAVjT8Yfi2o91j/fj81jacCQZ/Ihjiff/VsUCXVgQ+iF1XdImOw==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.3.0.tgz", + "integrity": "sha512-RiSpqo2OFbVLJN/PgAOwQIUeHDfss6NBUDTLhjiJM8Bb5rMrwRqHfkaqahIsOf9cXXB5UjcqDCzbQ7AIoMqWkg==", "dev": true }, "jest-snapshot": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.1.0.tgz", - "integrity": "sha512-th6TDfFqEmXvuViacU1ikD7xFb7lQsPn2rJl7OEmnfIVpnrx3QNY2t3PE88meeg0u/mQ0nkyvmC05PBqO4USFA==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.3.1.tgz", + "integrity": "sha512-7wbNJWh0sBjmoaexTOWqS7nleTQME7o2W9XKU6CHCxG49Thjct4aVPC/QPNF5NHnvf4M/VDmudIDbwz6noJTRA==", "dev": true, "requires": { "@babel/types": "^7.0.0", + "@jest/types": "^24.3.0", "chalk": "^2.0.1", - "jest-diff": "^24.0.0", - "jest-matcher-utils": "^24.0.0", - "jest-message-util": "^24.0.0", - "jest-resolve": "^24.1.0", + "expect": "^24.3.1", + "jest-diff": "^24.3.1", + "jest-matcher-utils": "^24.3.1", + "jest-message-util": "^24.3.0", + "jest-resolve": "^24.3.1", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "pretty-format": "^24.0.0", + "pretty-format": "^24.3.1", "semver": "^5.5.0" }, "dependencies": { @@ -5684,16 +6130,21 @@ } }, "jest-util": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.0.0.tgz", - "integrity": "sha512-QxsALc4wguYS7cfjdQSOr5HTkmjzkHgmZvIDkcmPfl1ib8PNV8QUWLwbKefCudWS0PRKioV+VbQ0oCUPC691fQ==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.3.0.tgz", + "integrity": "sha512-eKIAC+MTKWZthUUVOwZ3Tc5a0cKMnxalQHr6qZ4kPzKn6k09sKvsmjCygqZ1SxVVfUKoa8Sfn6XDv9uTJ1iXTg==", "dev": true, "requires": { + "@jest/console": "^24.3.0", + "@jest/fake-timers": "^24.3.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.3.0", + "@jest/types": "^24.3.0", + "@types/node": "*", "callsites": "^3.0.0", "chalk": "^2.0.1", "graceful-fs": "^4.1.15", "is-ci": "^2.0.0", - "jest-message-util": "^24.0.0", "mkdirp": "^0.5.1", "slash": "^2.0.0", "source-map": "^0.6.0" @@ -5749,16 +6200,17 @@ } }, "jest-validate": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.0.0.tgz", - "integrity": "sha512-vMrKrTOP4BBFIeOWsjpsDgVXATxCspC9S1gqvbJ3Tnn/b9ACsJmteYeVx9830UMV28Cob1RX55x96Qq3Tfad4g==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.3.1.tgz", + "integrity": "sha512-ww3+IPNCOEMi1oKlrHdSnBXetXtdrrdSh0bqLNTVkWglduhORf94RJWd1ko9oEPU2TcEQS5QIPacYziQIUzc4A==", "dev": true, "requires": { + "@jest/types": "^24.3.0", "camelcase": "^5.0.0", "chalk": "^2.0.1", - "jest-get-type": "^24.0.0", + "jest-get-type": "^24.3.0", "leven": "^2.1.0", - "pretty-format": "^24.0.0" + "pretty-format": "^24.3.1" }, "dependencies": { "ansi-styles": { @@ -5793,14 +6245,18 @@ } }, "jest-watcher": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.0.0.tgz", - "integrity": "sha512-GxkW2QrZ4YxmW1GUWER05McjVDunBlKMFfExu+VsGmXJmpej1saTEKvONdx5RJBlVdpPI5x6E3+EDQSIGgl53g==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.3.0.tgz", + "integrity": "sha512-EpJS/aUG8D3DMuy9XNA4fnkKWy3DQdoWhY92ZUdlETIeEn1xya4Np/96MBSh4II5YvxwKe6JKwbu3Bnzfwa7vA==", "dev": true, "requires": { + "@jest/test-result": "^24.3.0", + "@jest/types": "^24.3.0", + "@types/node": "*", + "@types/yargs": "^12.0.9", "ansi-escapes": "^3.0.0", "chalk": "^2.0.1", - "jest-util": "^24.0.0", + "jest-util": "^24.3.0", "string-length": "^2.0.0" }, "dependencies": { @@ -5836,11 +6292,12 @@ } }, "jest-worker": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.0.0.tgz", - "integrity": "sha512-s64/OThpfQvoCeHG963MiEZOAAxu8kHsaL/rCMF7lpdzo7vgF0CtPml9hfguOMgykgH/eOm4jFP4ibfHLruytg==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.3.1.tgz", + "integrity": "sha512-ZCoAe/iGLzTJvWHrO8fyx3bmEQhpL16SILJmWHKe8joHhyF3z00psF1sCRT54DoHw5GJG0ZpUtGy+ylvwA4haA==", "dev": true, "requires": { + "@types/node": "*", "merge-stream": "^1.0.1", "supports-color": "^6.1.0" }, @@ -6338,12 +6795,6 @@ } } }, - "merge": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", - "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", - "dev": true - }, "merge-stream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", @@ -6606,9 +7057,9 @@ "dev": true }, "nwsapi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.0.tgz", - "integrity": "sha512-ZG3bLAvdHmhIjaQ/Db1qvBxsGvFMLIRpQszyqbg31VJ53UP++uZX1/gf3Ut96pdwN9AuDwlMqIYLm0UPCdUeHg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.1.tgz", + "integrity": "sha512-T5GaA1J/d34AC8mkrFD2O0DR17kwJ702ZOtJOsS8RpbsQZVOC2/xYFb1i/cw+xdM54JIlMuojjDOYct8GIWtwg==", "dev": true }, "oauth-sign": { @@ -6872,9 +7323,9 @@ "dev": true }, "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -7040,9 +7491,9 @@ } }, "pirates": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.0.tgz", - "integrity": "sha512-8t5BsXy1LUIjn3WWOlOuFDuKswhQb/tkak641lvBgmPOBUQHXveORtlMCp6OdPV1dtuTaEahKA8VNz6uLfKBtA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", "dev": true, "requires": { "node-modules-regexp": "^1.0.0" @@ -7105,19 +7556,21 @@ "dev": true }, "pretty-format": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.0.0.tgz", - "integrity": "sha512-LszZaKG665djUcqg5ZQq+XzezHLKrxsA86ZABTozp+oNhkdqa+tG2dX4qa6ERl5c/sRDrAa3lHmwnvKoP+OG/g==", + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.3.1.tgz", + "integrity": "sha512-NZGH1NWS6o4i9pvRWLsxIK00JB9pqOUzVrO7yWT6vjI2thdxwvxefBJO6O5T24UAhI8P5dMceZ7x5wphgVI7Mg==", "dev": true, "requires": { + "@jest/types": "^24.3.0", "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0" + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" }, "dependencies": { "ansi-regex": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", - "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "ansi-styles": { @@ -7156,9 +7609,9 @@ "dev": true }, "prompts": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.0.2.tgz", - "integrity": "sha512-Pc/c53d2WZHJWZr78/BhZ5eHsdQtltbyBjHoA4T0cs/4yKJqCcoOHrq2SNKwtspVE0C+ebqAR5u0/mXwrHaADQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.0.3.tgz", + "integrity": "sha512-H8oWEoRZpybm6NV4to9/1limhttEo13xK62pNvn2JzY0MA03p7s0OjtmhXyon3uJmxiJJVSuUwEJFFssI3eBiQ==", "dev": true, "requires": { "kleur": "^3.0.2", @@ -7198,6 +7651,12 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, + "react-is": { + "version": "16.8.4", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.4.tgz", + "integrity": "sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA==", + "dev": true + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -7288,9 +7747,9 @@ } }, "realpath-native": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.0.2.tgz", - "integrity": "sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", + "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", "dev": true, "requires": { "util.promisify": "^1.0.0" @@ -7482,23 +7941,31 @@ } }, "request-promise-core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", - "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", + "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", "dev": true, "requires": { - "lodash": "^4.13.1" + "lodash": "^4.17.11" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + } } }, "request-promise-native": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", - "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", + "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", "dev": true, "requires": { - "request-promise-core": "1.1.1", - "stealthy-require": "^1.1.0", - "tough-cookie": ">=2.3.3" + "request-promise-core": "1.1.2", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" } }, "require-directory": { @@ -7631,9 +8098,9 @@ } }, "rollup": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.5.0.tgz", - "integrity": "sha512-xs32mjZhXmUPL+1u300YKFoN/Oqa0VoOkVu/5/bf2n60NpHgoO2L1mevuZg4ltkjrcO2dUfaTvCZzD3BPuAyQQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.6.0.tgz", + "integrity": "sha512-qu9iWyuiOxAuBM8cAwLuqPclYdarIpayrkfQB7aTGTiyYPbvx+qVF33sIznfq4bxZCiytQux/FvZieUBAXivCw==", "dev": true, "requires": { "@types/estree": "0.0.39", @@ -7695,21 +8162,20 @@ "dev": true }, "sane": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-3.1.0.tgz", - "integrity": "sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.0.3.tgz", + "integrity": "sha512-hSLkC+cPHiBQs7LSyXkotC3UUtyn8C4FMn50TNaacRyvBlI+3ebcxMpqckmTdtXVtel87YS7GXN3UIOj7NiGVQ==", "dev": true, "requires": { + "@cnakazawa/watch": "^1.0.3", "anymatch": "^2.0.0", "capture-exit": "^1.2.0", - "exec-sh": "^0.2.0", + "exec-sh": "^0.3.2", "execa": "^1.0.0", "fb-watchman": "^2.0.0", - "fsevents": "^1.2.3", "micromatch": "^3.1.4", "minimist": "^1.1.1", - "walker": "~1.0.5", - "watch": "~0.18.0" + "walker": "~1.0.5" } }, "sax": { @@ -9004,16 +9470,6 @@ "makeerror": "1.0.x" } }, - "watch": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz", - "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=", - "dev": true, - "requires": { - "exec-sh": "^0.2.0", - "minimist": "^1.2.0" - } - }, "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", diff --git a/package.json b/package.json index d6f6e57..1ed297b 100644 --- a/package.json +++ b/package.json @@ -58,18 +58,17 @@ "unpkg": "dist/lamb.min.js", "sideEffects": false, "tonicExample": "var _ = require('lamb');", - "version": "0.58.0-alpha.1", + "version": "0.58.0-alpha.2", "devDependencies": { "@babel/preset-env": "^7.3.4", "coveralls": "^3.0.3", "gulp": "^4.0.0", "gulp-eslint": "^5.0.0", - "gulp-jest": "^4.0.2", "gulp-rename": "^1.4.0", "gulp-sourcemaps": "^2.6.5", "gulp-uglify": "^3.0.2", - "jest-cli": "^24.1.0", - "rollup": "^1.5.0" + "jest-cli": "^24.3.1", + "rollup": "^1.6.0" }, "dependencies": {} } diff --git a/src/object/updateIn.js b/src/object/updateIn.js index 5006096..5a232a7 100644 --- a/src/object/updateIn.js +++ b/src/object/updateIn.js @@ -32,9 +32,9 @@ import enumerables from "./enumerables"; * @returns {Object} */ function updateIn (source, key, updater) { - return _isEnumerable(source, key) ? - _setIn(source, key, updater(source[key])) : - _merge(enumerables, source, {}); + return _isEnumerable(source, key) + ? _setIn(source, key, updater(source[key])) + : _merge(enumerables, source, {}); } export default updateIn;