diff --git a/README.md b/README.md
index b2fcee4fb..38ee8c6af 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# lodash v4.0.0
+# lodash v4.0.1
The [lodash](https://lodash.com/) library exported as [Node.js](https://nodejs.org/) modules.
@@ -11,24 +11,26 @@ $ lodash -d -o ./lodash.js
## Installation
Using npm:
-
```bash
$ {sudo -H} npm i -g npm
$ npm i --save lodash
```
In Node.js:
-
```js
-// load the modern build
+// load the full build
var _ = require('lodash');
+// load the core build
+var _ = require('lodash/core');
+// load the fp build
+var _ = require('lodash/fp');
// or a method category
var array = require('lodash/array');
// or a method (great for smaller builds with browserify/webpack)
var chunk = require('lodash/chunk');
```
-See the [package source](https://github.com/lodash/lodash/tree/4.0.0-npm) for more details.
+See the [package source](https://github.com/lodash/lodash/tree/4.0.1-npm) for more details.
**Note:**
Don’t assign values to the [special variable](http://nodejs.org/api/repl.html#repl_repl_features) `_` when in the REPL.
@@ -36,7 +38,7 @@ Install [n_](https://www.npmjs.com/package/n_) for a REPL that includes lodash b
## Module formats
-lodash is also available in a variety of other builds & module formats.
+Lodash is also available in a variety of other builds & module formats.
* [lodash](https://www.npmjs.com/package/lodash) & [per method](https://www.npmjs.com/browse/keyword/lodash-modularized) packages
* [lodash-amd](https://www.npmjs.com/package/lodash-amd)
@@ -52,5 +54,5 @@ lodash is also available in a variety of other builds & module formats.
## Support
-Tested in Chrome 46-47, Firefox 42-43, IE 9-11, Edge 13, Safari 8-9, Node.js 0.10.x, 0.12.x, 4.x, & 5.x, & PhantomJS 1.9.8.
+Tested in Chrome 46-47, Firefox 42-43, IE 9-11, Edge 13, Safari 8-9, Node.js 0.10.x, 0.12.x, 4.x, & 5.x, & PhantomJS 1.9.8.
Automated [browser](https://saucelabs.com/u/lodash) & [CI](https://travis-ci.org/lodash/lodash/) test runs are available. Special thanks to [Sauce Labs](https://saucelabs.com/) for providing automated browser testing.
diff --git a/assignInWith.js b/assignInWith.js
index 50c80f174..81a71b181 100644
--- a/assignInWith.js
+++ b/assignInWith.js
@@ -29,7 +29,7 @@ var copyObjectWith = require('./internal/copyObjectWith'),
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
* // => { 'a': 1, 'b': 2 }
*/
-var assignInWith = createAssigner(function(object, source, customizer) {
+var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
copyObjectWith(source, keysIn(source), object, customizer);
});
diff --git a/assignWith.js b/assignWith.js
index 0e2eb96c1..8b32b89de 100644
--- a/assignWith.js
+++ b/assignWith.js
@@ -28,7 +28,7 @@ var copyObjectWith = require('./internal/copyObjectWith'),
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
* // => { 'a': 1, 'b': 2 }
*/
-var assignWith = createAssigner(function(object, source, customizer) {
+var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
copyObjectWith(source, keys(source), object, customizer);
});
diff --git a/cloneDeepWith.js b/cloneDeepWith.js
index a306cfc32..c814cf50f 100644
--- a/cloneDeepWith.js
+++ b/cloneDeepWith.js
@@ -17,7 +17,7 @@ var baseClone = require('./internal/baseClone');
* }
* }
*
- * var el = _.cloneDeep(document.body, customizer);
+ * var el = _.cloneDeepWith(document.body, customizer);
*
* console.log(el === document.body);
* // => false
diff --git a/cloneWith.js b/cloneWith.js
index fdd6b063c..e436b1e8c 100644
--- a/cloneWith.js
+++ b/cloneWith.js
@@ -4,7 +4,7 @@ var baseClone = require('./internal/baseClone');
* This method is like `_.clone` except that it accepts `customizer` which
* is invoked to produce the cloned value. If `customizer` returns `undefined`
* cloning is handled by the method instead. The `customizer` is invoked with
- * up to five arguments; (value [, index|key, object, stack]).
+ * up to four arguments; (value [, index|key, object, stack]).
*
* @static
* @memberOf _
@@ -20,7 +20,7 @@ var baseClone = require('./internal/baseClone');
* }
* }
*
- * var el = _.clone(document.body, customizer);
+ * var el = _.cloneWith(document.body, customizer);
*
* console.log(el === document.body);
* // => false
diff --git a/concat.js b/concat.js
index b023ca447..ecee6f893 100644
--- a/concat.js
+++ b/concat.js
@@ -25,8 +25,11 @@ var arrayConcat = require('./internal/arrayConcat'),
* // => [1]
*/
var concat = rest(function(array, values) {
+ if (!isArray(array)) {
+ array = array == null ? [] : [Object(array)];
+ }
values = baseFlatten(values);
- return arrayConcat(isArray(array) ? array : [Object(array)], values);
+ return arrayConcat(array, values);
});
module.exports = concat;
diff --git a/cond.js b/cond.js
index 99d40eaf6..d04cfd909 100644
--- a/cond.js
+++ b/cond.js
@@ -23,7 +23,7 @@ var FUNC_ERROR_TEXT = 'Expected a function';
* [_.matches({ 'a': 1 }), _.constant('matches A')],
* [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
* [_.constant(true), _.constant('no match')]
- * ])
+ * ]);
*
* func({ 'a': 1, 'b': 2 });
* // => 'matches A'
diff --git a/core.js b/core.js
new file mode 100644
index 000000000..9aa3e4df8
--- /dev/null
+++ b/core.js
@@ -0,0 +1,3857 @@
+/**
+ * @license
+ * lodash 4.0.1 (Custom Build)
+ * Build: `lodash core -o ./dist/lodash.core.js`
+ * Copyright 2012-2016 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+;(function() {
+
+ /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+ var undefined;
+
+ /** Used as the semantic version number. */
+ var VERSION = '4.0.1';
+
+ /** Used to compose bitmasks for wrapper metadata. */
+ var BIND_FLAG = 1,
+ PARTIAL_FLAG = 32;
+
+ /** Used to compose bitmasks for comparison styles. */
+ var UNORDERED_COMPARE_FLAG = 1,
+ PARTIAL_COMPARE_FLAG = 2;
+
+ /** Used as the `TypeError` message for "Functions" methods. */
+ var FUNC_ERROR_TEXT = 'Expected a function';
+
+ /** Used as references for various `Number` constants. */
+ var MAX_SAFE_INTEGER = 9007199254740991;
+
+ /** `Object#toString` result references. */
+ var argsTag = '[object Arguments]',
+ arrayTag = '[object Array]',
+ boolTag = '[object Boolean]',
+ dateTag = '[object Date]',
+ errorTag = '[object Error]',
+ funcTag = '[object Function]',
+ genTag = '[object GeneratorFunction]',
+ numberTag = '[object Number]',
+ objectTag = '[object Object]',
+ regexpTag = '[object RegExp]',
+ stringTag = '[object String]';
+
+ /** Used to match HTML entities and HTML characters. */
+ var reUnescapedHtml = /[&<>"'`]/g,
+ reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
+
+ /** Used to detect unsigned integer values. */
+ var reIsUint = /^(?:0|[1-9]\d*)$/;
+
+ /** Used to map characters to HTML entities. */
+ var htmlEscapes = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": ''',
+ '`': '`'
+ };
+
+ /** Used to determine if values are of the language type `Object`. */
+ var objectTypes = {
+ 'function': true,
+ 'object': true
+ };
+
+ /** Detect free variable `exports`. */
+ var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null;
+
+ /** Detect free variable `module`. */
+ var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null;
+
+ /** Detect free variable `global` from Node.js. */
+ var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
+
+ /** Detect free variable `self`. */
+ var freeSelf = checkGlobal(objectTypes[typeof self] && self);
+
+ /** Detect free variable `window`. */
+ var freeWindow = checkGlobal(objectTypes[typeof window] && window);
+
+ /** Detect the popular CommonJS extension `module.exports`. */
+ var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null;
+
+ /** Detect `this` as the global object. */
+ var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
+
+ /**
+ * Used as a reference to the global object.
+ *
+ * The `this` value is used if it's the global object to avoid Greasemonkey's
+ * restricted `window` object, otherwise the `window` object is used.
+ */
+ var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Creates a new array concatenating `array` with `other`.
+ *
+ * @private
+ * @param {Array} array The first array to concatenate.
+ * @param {Array} other The second array to concatenate.
+ * @returns {Array} Returns the new concatenated array.
+ */
+ function arrayConcat(array, other) {
+ return arrayPush(copyArray(array), values);
+ }
+
+ /**
+ * Appends the elements of `values` to `array`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to append.
+ * @returns {Array} Returns `array`.
+ */
+ function arrayPush(array, values) {
+ var index = -1,
+ length = values.length,
+ offset = array.length;
+
+ while (++index < length) {
+ array[offset + index] = values[index];
+ }
+ return array;
+ }
+
+ /**
+ * The base implementation of methods like `_.max` and `_.min` which accepts a
+ * `comparator` to determine the extremum value.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The iteratee invoked per iteration.
+ * @param {Function} comparator The comparator used to compare values.
+ * @returns {*} Returns the extremum value.
+ */
+ function baseExtremum(array, iteratee, comparator) {
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ var value = array[index],
+ current = iteratee(value);
+
+ if (current != null && (computed === undefined
+ ? current === current
+ : comparator(current, computed)
+ )) {
+ var computed = current,
+ result = value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of methods like `_.find` and `_.findKey`, without
+ * support for iteratee shorthands, which iterates over `collection` using
+ * `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to search.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @param {boolean} [retKey] Specify returning the key of the found element instead of the element itself.
+ * @returns {*} Returns the found element or its key, else `undefined`.
+ */
+ function baseFind(collection, predicate, eachFunc, retKey) {
+ var result;
+ eachFunc(collection, function(value, key, collection) {
+ if (predicate(value, key, collection)) {
+ result = retKey ? key : value;
+ return false;
+ }
+ });
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.reduce` and `_.reduceRight`, without support
+ * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} accumulator The initial value.
+ * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @returns {*} Returns the accumulated value.
+ */
+ function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
+ eachFunc(collection, function(value, index, collection) {
+ accumulator = initAccum
+ ? (initAccum = false, value)
+ : iteratee(accumulator, value, index, collection);
+ });
+ return accumulator;
+ }
+
+ /**
+ * The base implementation of `_.times` without support for iteratee shorthands
+ * or max array length checks.
+ *
+ * @private
+ * @param {number} n The number of times to invoke `iteratee`.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the array of results.
+ */
+ function baseTimes(n, iteratee) {
+ var index = -1,
+ result = Array(n);
+
+ while (++index < n) {
+ result[index] = iteratee(index);
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.values` and `_.valuesIn` which creates an
+ * array of `object` property values corresponding to the property names
+ * of `props`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} props The property names to get values for.
+ * @returns {Object} Returns the array of property values.
+ */
+ function baseValues(object, props) {
+ return baseMap(props, function(key) {
+ return object[key];
+ });
+ }
+
+ /**
+ * Checks if `value` is a global object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {null|Object} Returns `value` if it's a global object, else `null`.
+ */
+ function checkGlobal(value) {
+ return (value && value.Object === Object) ? value : null;
+ }
+
+ /**
+ * Compares values to sort them in ascending order.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {number} Returns the sort order indicator for `value`.
+ */
+ function compareAscending(value, other) {
+ if (value !== other) {
+ var valIsNull = value === null,
+ valIsUndef = value === undefined,
+ valIsReflexive = value === value;
+
+ var othIsNull = other === null,
+ othIsUndef = other === undefined,
+ othIsReflexive = other === other;
+
+ if ((value > other && !othIsNull) || !valIsReflexive ||
+ (valIsNull && !othIsUndef && othIsReflexive) ||
+ (valIsUndef && othIsReflexive)) {
+ return 1;
+ }
+ if ((value < other && !valIsNull) || !othIsReflexive ||
+ (othIsNull && !valIsUndef && valIsReflexive) ||
+ (othIsUndef && valIsReflexive)) {
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Used by `_.escape` to convert characters to HTML entities.
+ *
+ * @private
+ * @param {string} chr The matched character to escape.
+ * @returns {string} Returns the escaped character.
+ */
+ function escapeHtmlChar(chr) {
+ return htmlEscapes[chr];
+ }
+
+ /**
+ * Checks if `value` is a host object in IE < 9.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
+ */
+ function isHostObject(value) {
+ // Many host objects are `Object` objects that can coerce to strings
+ // despite having improperly defined `toString` methods.
+ var result = false;
+ if (value != null && typeof value.toString != 'function') {
+ try {
+ result = !!(value + '');
+ } catch (e) {}
+ }
+ return result;
+ }
+
+ /**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+ function isIndex(value, length) {
+ value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
+ length = length == null ? MAX_SAFE_INTEGER : length;
+ return value > -1 && value % 1 == 0 && value < length;
+ }
+
+ /**
+ * Converts `iterator` to an array.
+ *
+ * @private
+ * @param {Object} iterator The iterator to convert.
+ * @returns {Array} Returns the converted array.
+ */
+ function iteratorToArray(iterator) {
+ var data,
+ result = [];
+
+ while (!(data = iterator.next()).done) {
+ result.push(data.value);
+ }
+ return result;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /** Used for built-in method references. */
+ var arrayProto = Array.prototype,
+ objectProto = Object.prototype;
+
+ /** Used to check objects for own properties. */
+ var hasOwnProperty = objectProto.hasOwnProperty;
+
+ /** Used to generate unique IDs. */
+ var idCounter = 0;
+
+ /**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+ var objectToString = objectProto.toString;
+
+ /** Used to restore the original `_` reference in `_.noConflict`. */
+ var oldDash = root._;
+
+ /** Built-in value references. */
+ var Reflect = root.Reflect,
+ Symbol = root.Symbol,
+ Uint8Array = root.Uint8Array,
+ enumerate = Reflect ? Reflect.enumerate : undefined,
+ propertyIsEnumerable = objectProto.propertyIsEnumerable;
+
+ /* Built-in method references for those with the same name as other `lodash` methods. */
+ var nativeIsFinite = root.isFinite,
+ nativeKeys = Object.keys,
+ nativeMax = Math.max;
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates a `lodash` object which wraps `value` to enable implicit method
+ * chaining. Methods that operate on and return arrays, collections, and
+ * functions can be chained together. Methods that retrieve a single value or
+ * may return a primitive value will automatically end the chain sequence and
+ * return the unwrapped value. Otherwise, the value must be unwrapped with
+ * `_#value`.
+ *
+ * Explicit chaining, which must be unwrapped with `_#value` in all cases,
+ * may be enabled using `_.chain`.
+ *
+ * The execution of chained methods is lazy, that is, it's deferred until
+ * `_#value` is implicitly or explicitly called.
+ *
+ * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
+ * fusion is an optimization to merge iteratee calls; this avoids the creation
+ * of intermediate arrays and can greatly reduce the number of iteratee executions.
+ * Sections of a chain sequence qualify for shortcut fusion if the section is
+ * applied to an array of at least two hundred elements and any iteratees
+ * accept only one argument. The heuristic for whether a section qualifies
+ * for shortcut fusion is subject to change.
+ *
+ * Chaining is supported in custom builds as long as the `_#value` method is
+ * directly or indirectly included in the build.
+ *
+ * In addition to lodash methods, wrappers have `Array` and `String` methods.
+ *
+ * The wrapper `Array` methods are:
+ * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
+ *
+ * The wrapper `String` methods are:
+ * `replace` and `split`
+ *
+ * The wrapper methods that support shortcut fusion are:
+ * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
+ * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
+ * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
+ *
+ * The chainable wrapper methods are:
+ * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`,
+ * `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`,
+ * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
+ * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
+ * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
+ * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
+ * `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
+ * `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invokeMap`,
+ * `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`,
+ * `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`,
+ * `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`,
+ * `over`, `overArgs`, `overEvery`, `overSome`, `partial`, `partialRight`,
+ * `partition`, `pick`, `pickBy`, `plant`, `property`, `propertyOf`, `pull`,
+ * `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`,
+ * `reject`, `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`,
+ * `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`,
+ * `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`,
+ * `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`,
+ * `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`,
+ * `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, `without`,
+ * `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, and `zipWith`
+ *
+ * The wrapper methods that are **not** chainable by default are:
+ * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
+ * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
+ * `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
+ * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`,
+ * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
+ * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
+ * `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`,
+ * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`,
+ * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`, `isMatchWith`,
+ * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`,
+ * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isString`, `isUndefined`,
+ * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`,
+ * `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`,
+ * `noConflict`, `noop`, `now`, `pad`, `padEnd`, `padStart`, `parseInt`,
+ * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`,
+ * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
+ * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`,
+ * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toLower`,
+ * `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`,
+ * `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
+ * `upperCase`, `upperFirst`, `value`, and `words`
+ *
+ * @name _
+ * @constructor
+ * @category Seq
+ * @param {*} value The value to wrap in a `lodash` instance.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * var wrapped = _([1, 2, 3]);
+ *
+ * // returns an unwrapped value
+ * wrapped.reduce(_.add);
+ * // => 6
+ *
+ * // returns a wrapped value
+ * var squares = wrapped.map(square);
+ *
+ * _.isArray(squares);
+ * // => false
+ *
+ * _.isArray(squares.value());
+ * // => true
+ */
+ function lodash(value) {
+ if (isObjectLike(value) && !isArray(value)) {
+ if (value instanceof LodashWrapper) {
+ return value;
+ }
+ if (hasOwnProperty.call(value, '__wrapped__')) {
+ return wrapperClone(value);
+ }
+ }
+ return new LodashWrapper(value);
+ }
+
+ /**
+ * The base constructor for creating `lodash` wrapper objects.
+ *
+ * @private
+ * @param {*} value The value to wrap.
+ * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
+ */
+ function LodashWrapper(value, chainAll) {
+ this.__wrapped__ = value;
+ this.__actions__ = [];
+ this.__chain__ = !!chainAll;
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Used by `_.defaults` to customize its `_.assignIn` use.
+ *
+ * @private
+ * @param {*} objValue The destination value.
+ * @param {*} srcValue The source value.
+ * @param {string} key The key of the property to assign.
+ * @param {Object} object The parent object of `objValue`.
+ * @returns {*} Returns the value to assign.
+ */
+ function assignInDefaults(objValue, srcValue, key, object) {
+ if (objValue === undefined ||
+ (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
+ return srcValue;
+ }
+ return objValue;
+ }
+
+ /**
+ * Assigns `value` to `key` of `object` if the existing value is not equivalent
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons.
+ *
+ * @private
+ * @param {Object} object The object to modify.
+ * @param {string} key The key of the property to assign.
+ * @param {*} value The value to assign.
+ */
+ function assignValue(object, key, value) {
+ var objValue = object[key];
+ if ((!eq(objValue, value) ||
+ (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) ||
+ (value === undefined && !(key in object))) {
+ object[key] = value;
+ }
+ }
+
+ /**
+ * The base implementation of `_.create` without support for assigning
+ * properties to the created object.
+ *
+ * @private
+ * @param {Object} prototype The object to inherit from.
+ * @returns {Object} Returns the new object.
+ */
+ var baseCreate = (function() {
+ function object() {}
+ return function(prototype) {
+ if (isObject(prototype)) {
+ object.prototype = prototype;
+ var result = new object;
+ object.prototype = undefined;
+ }
+ return result || {};
+ };
+ }());
+
+ /**
+ * The base implementation of `_.delay` and `_.defer` which accepts an array
+ * of `func` arguments.
+ *
+ * @private
+ * @param {Function} func The function to delay.
+ * @param {number} wait The number of milliseconds to delay invocation.
+ * @param {Object} args The arguments provide to `func`.
+ * @returns {number} Returns the timer id.
+ */
+ function baseDelay(func, wait, args) {
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ return setTimeout(function() { func.apply(undefined, args); }, wait);
+ }
+
+ /**
+ * The base implementation of `_.forEach` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ */
+ var baseEach = createBaseEach(baseForOwn);
+
+ /**
+ * The base implementation of `_.every` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`
+ */
+ function baseEvery(collection, predicate) {
+ var result = true;
+ baseEach(collection, function(value, index, collection) {
+ result = !!predicate(value, index, collection);
+ return result;
+ });
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.filter` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ */
+ function baseFilter(collection, predicate) {
+ var result = [];
+ baseEach(collection, function(value, index, collection) {
+ if (predicate(value, index, collection)) {
+ result.push(value);
+ }
+ });
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.flatten` with support for restricting flattening.
+ *
+ * @private
+ * @param {Array} array The array to flatten.
+ * @param {boolean} [isDeep] Specify a deep flatten.
+ * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
+ * @param {Array} [result=[]] The initial result value.
+ * @returns {Array} Returns the new flattened array.
+ */
+ function baseFlatten(array, isDeep, isStrict, result) {
+ result || (result = []);
+
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ var value = array[index];
+ if (isArrayLikeObject(value) &&
+ (isStrict || isArray(value) || isArguments(value))) {
+ if (isDeep) {
+ // Recursively flatten arrays (susceptible to call stack limits).
+ baseFlatten(value, isDeep, isStrict, result);
+ } else {
+ arrayPush(result, value);
+ }
+ } else if (!isStrict) {
+ result[result.length] = value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * The base implementation of `baseForIn` and `baseForOwn` which iterates
+ * over `object` properties returned by `keysFunc` invoking `iteratee` for
+ * each property. Iteratee functions may exit iteration early by explicitly
+ * returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+ var baseFor = createBaseFor();
+
+ /**
+ * The base implementation of `_.forOwn` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+ function baseForOwn(object, iteratee) {
+ return object && baseFor(object, iteratee, keys);
+ }
+
+ /**
+ * The base implementation of `_.functions` which creates an array of
+ * `object` function property names filtered from those provided.
+ *
+ * @private
+ * @param {Object} object The object to inspect.
+ * @param {Array} props The property names to filter.
+ * @returns {Array} Returns the new array of filtered property names.
+ */
+ function baseFunctions(object, props) {
+ return baseFilter(props, function(key) {
+ return isFunction(object[key]);
+ });
+ }
+
+ /**
+ * The base implementation of `_.isEqual` which supports partial comparisons
+ * and tracks traversed objects.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {boolean} [bitmask] The bitmask of comparison flags.
+ * The bitmask may be composed of the following flags:
+ * 1 - Unordered comparison
+ * 2 - Partial comparison
+ * @param {Object} [stack] Tracks traversed `value` and `other` objects.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ */
+ function baseIsEqual(value, other, customizer, bitmask, stack) {
+ if (value === other) {
+ return true;
+ }
+ if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
+ return value !== value && other !== other;
+ }
+ return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
+ }
+
+ /**
+ * A specialized version of `baseIsEqual` for arrays and objects which performs
+ * deep comparisons and tracks traversed objects enabling objects with circular
+ * references to be compared.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @param {Object} [stack] Tracks traversed `object` and `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+ function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
+ var objIsArr = isArray(object),
+ othIsArr = isArray(other),
+ objTag = arrayTag,
+ othTag = arrayTag;
+
+ if (!objIsArr) {
+ objTag = objectToString.call(object);
+ if (objTag == argsTag) {
+ objTag = objectTag;
+ }
+ }
+ if (!othIsArr) {
+ othTag = objectToString.call(other);
+ if (othTag == argsTag) {
+ othTag = objectTag;
+ }
+ }
+ var objIsObj = objTag == objectTag && !isHostObject(object),
+ othIsObj = othTag == objectTag && !isHostObject(other),
+ isSameTag = objTag == othTag;
+
+ if (isSameTag && !(objIsArr || objIsObj)) {
+ return equalByTag(object, other, objTag, equalFunc, customizer, bitmask);
+ }
+ var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
+ if (!isPartial) {
+ var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
+ othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
+
+ if (objIsWrapped || othIsWrapped) {
+ return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, bitmask, stack);
+ }
+ }
+ if (!isSameTag) {
+ return false;
+ }
+ stack || (stack = []);
+ var stacked = find(stack, function(entry) {
+ return entry[0] === object;
+ });
+ if (stacked && stacked[1]) {
+ return stacked[1] == other;
+ }
+ stack.push([object, other]);
+ var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, bitmask, stack);
+ stack.pop();
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.iteratee`.
+ *
+ * @private
+ * @param {*} [value=_.identity] The value to convert to an iteratee.
+ * @returns {Function} Returns the iteratee.
+ */
+ function baseIteratee(func) {
+ var type = typeof func;
+ if (type == 'function') {
+ return func;
+ }
+ return func == null
+ ? identity
+ : (type == 'object' ? baseMatches : baseProperty)(func);
+ }
+
+ /**
+ * The base implementation of `_.keys` which doesn't skip the constructor
+ * property of prototypes or treat sparse arrays as dense.
+ *
+ * @private
+ * @type Function
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+ function baseKeys(object) {
+ return nativeKeys(Object(object));
+ }
+
+ /**
+ * The base implementation of `_.keysIn` which doesn't skip the constructor
+ * property of prototypes or treat sparse arrays as dense.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+ function baseKeysIn(object) {
+ object = object == null ? object : Object(object);
+
+ var result = [];
+ for (var key in object) {
+ result.push(key);
+ }
+ return result;
+ }
+
+ // Fallback for IE < 9 with es6-shim.
+ if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
+ baseKeysIn = function(object) {
+ return iteratorToArray(enumerate(object));
+ };
+ }
+
+ /**
+ * The base implementation of `_.map` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */
+ function baseMap(collection, iteratee) {
+ var index = -1,
+ result = isArrayLike(collection) ? Array(collection.length) : [];
+
+ baseEach(collection, function(value, key, collection) {
+ result[++index] = iteratee(value, key, collection);
+ });
+ return result;
+ }
+
+ /**
+ * The base implementation of `_.matches` which doesn't clone `source`.
+ *
+ * @private
+ * @param {Object} source The object of property values to match.
+ * @returns {Function} Returns the new function.
+ */
+ function baseMatches(source) {
+ var props = keys(source);
+ return function(object) {
+ var length = props.length;
+ if (object == null) {
+ return !length;
+ }
+ object = Object(object);
+ while (length--) {
+ var key = props[length];
+ if (!(key in object &&
+ baseIsEqual(source[key], object[key], undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG)
+ )) {
+ return false;
+ }
+ }
+ return true;
+ };
+ }
+
+ /**
+ * The base implementation of `_.pick` without support for individual
+ * property names.
+ *
+ * @private
+ * @param {Object} object The source object.
+ * @param {string[]} props The property names to pick.
+ * @returns {Object} Returns the new object.
+ */
+ function basePick(object, props) {
+ object = Object(object);
+ return reduce(props, function(result, key) {
+ if (key in object) {
+ result[key] = object[key];
+ }
+ return result;
+ }, {});
+ }
+
+ /**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+ function baseProperty(key) {
+ return function(object) {
+ return object == null ? undefined : object[key];
+ };
+ }
+
+ /**
+ * The base implementation of `_.slice` without an iteratee call guard.
+ *
+ * @private
+ * @param {Array} array The array to slice.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the slice of `array`.
+ */
+ function baseSlice(array, start, end) {
+ var index = -1,
+ length = array.length;
+
+ if (start < 0) {
+ start = -start > length ? 0 : (length + start);
+ }
+ end = end > length ? length : end;
+ if (end < 0) {
+ end += length;
+ }
+ length = start > end ? 0 : ((end - start) >>> 0);
+ start >>>= 0;
+
+ var result = Array(length);
+ while (++index < length) {
+ result[index] = array[index + start];
+ }
+ return result;
+ }
+
+ /**
+ * Copies the values of `source` to `array`.
+ *
+ * @private
+ * @param {Array} source The array to copy values from.
+ * @param {Array} [array=[]] The array to copy values to.
+ * @returns {Array} Returns `array`.
+ */
+ function copyArray(source) {
+ return baseSlice(source, 0, source.length);
+ }
+
+ /**
+ * The base implementation of `_.some` without support for iteratee shorthands.
+ *
+ * @private
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
+ */
+ function baseSome(collection, predicate) {
+ var result;
+
+ baseEach(collection, function(value, index, collection) {
+ result = predicate(value, index, collection);
+ return !result;
+ });
+ return !!result;
+ }
+
+ /**
+ * The base implementation of `wrapperValue` which returns the result of
+ * performing a sequence of actions on the unwrapped `value`, where each
+ * successive action is supplied the return value of the previous.
+ *
+ * @private
+ * @param {*} value The unwrapped value.
+ * @param {Array} actions Actions to perform to resolve the unwrapped value.
+ * @returns {*} Returns the resolved value.
+ */
+ function baseWrapperValue(value, actions) {
+ var result = value;
+ return reduce(actions, function(result, action) {
+ return action.func.apply(action.thisArg, arrayPush([result], action.args));
+ }, result);
+ }
+
+ /**
+ * Copies properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property names to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @returns {Object} Returns `object`.
+ */
+ var copyObject = copyObjectWith;
+
+ /**
+ * This function is like `copyObject` except that it accepts a function to
+ * customize copied values.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property names to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @param {Function} [customizer] The function to customize copied values.
+ * @returns {Object} Returns `object`.
+ */
+ function copyObjectWith(source, props, object, customizer) {
+ object || (object = {});
+
+ var index = -1,
+ length = props.length;
+
+ while (++index < length) {
+ var key = props[index],
+ newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key];
+
+ assignValue(object, key, newValue);
+ }
+ return object;
+ }
+
+ /**
+ * Creates a function like `_.assign`.
+ *
+ * @private
+ * @param {Function} assigner The function to assign values.
+ * @returns {Function} Returns the new assigner function.
+ */
+ function createAssigner(assigner) {
+ return rest(function(object, sources) {
+ var index = -1,
+ length = sources.length,
+ customizer = length > 1 ? sources[length - 1] : undefined;
+
+ customizer = typeof customizer == 'function' ? (length--, customizer) : undefined;
+ object = Object(object);
+ while (++index < length) {
+ var source = sources[index];
+ if (source) {
+ assigner(object, source, index, customizer);
+ }
+ }
+ return object;
+ });
+ }
+
+ /**
+ * Creates a `baseEach` or `baseEachRight` function.
+ *
+ * @private
+ * @param {Function} eachFunc The function to iterate over a collection.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+ function createBaseEach(eachFunc, fromRight) {
+ return function(collection, iteratee) {
+ if (collection == null) {
+ return collection;
+ }
+ if (!isArrayLike(collection)) {
+ return eachFunc(collection, iteratee);
+ }
+ var length = collection.length,
+ index = fromRight ? length : -1,
+ iterable = Object(collection);
+
+ while ((fromRight ? index-- : ++index < length)) {
+ if (iteratee(iterable[index], index, iterable) === false) {
+ break;
+ }
+ }
+ return collection;
+ };
+ }
+
+ /**
+ * Creates a base function for methods like `_.forIn`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+ function createBaseFor(fromRight) {
+ return function(object, iteratee, keysFunc) {
+ var index = -1,
+ iterable = Object(object),
+ props = keysFunc(object),
+ length = props.length;
+
+ while (length--) {
+ var key = props[fromRight ? length : ++index];
+ if (iteratee(iterable[key], key, iterable) === false) {
+ break;
+ }
+ }
+ return object;
+ };
+ }
+
+ /**
+ * Creates a function that produces an instance of `Ctor` regardless of
+ * whether it was invoked as part of a `new` expression or by `call` or `apply`.
+ *
+ * @private
+ * @param {Function} Ctor The constructor to wrap.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createCtorWrapper(Ctor) {
+ return function() {
+ // Use a `switch` statement to work with class constructors.
+ // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
+ // for more details.
+ var args = arguments;
+ var thisBinding = baseCreate(Ctor.prototype),
+ result = Ctor.apply(thisBinding, args);
+
+ // Mimic the constructor's `return` behavior.
+ // See https://es5.github.io/#x13.2.2 for more details.
+ return isObject(result) ? result : thisBinding;
+ };
+ }
+
+ /**
+ * Creates a function that wraps `func` to invoke it with the optional `this`
+ * binding of `thisArg` and the `partials` prepended to those provided to
+ * the wrapper.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {Array} partials The arguments to prepend to those provided to the new function.
+ * @returns {Function} Returns the new wrapped function.
+ */
+ function createPartialWrapper(func, bitmask, thisArg, partials) {
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ var isBind = bitmask & BIND_FLAG,
+ Ctor = createCtorWrapper(func);
+
+ function wrapper() {
+ var argsIndex = -1,
+ argsLength = arguments.length,
+ leftIndex = -1,
+ leftLength = partials.length,
+ args = Array(leftLength + argsLength),
+ fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
+
+ while (++leftIndex < leftLength) {
+ args[leftIndex] = partials[leftIndex];
+ }
+ while (argsLength--) {
+ args[leftIndex++] = arguments[++argsIndex];
+ }
+ return fn.apply(isBind ? thisArg : this, args);
+ }
+ return wrapper;
+ }
+
+ /**
+ * A specialized version of `baseIsEqualDeep` for arrays with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Array} array The array to compare.
+ * @param {Array} other The other array to compare.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @param {Object} [stack] Tracks traversed `array` and `other` objects.
+ * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
+ */
+ function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
+ var index = -1,
+ isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+ isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
+ arrLength = array.length,
+ othLength = other.length;
+
+ if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
+ return false;
+ }
+ var result = true;
+
+ // Ignore non-index properties.
+ while (++index < arrLength) {
+ var arrValue = array[index],
+ othValue = other[index];
+
+ var compared;
+ if (compared !== undefined) {
+ if (compared) {
+ continue;
+ }
+ result = false;
+ break;
+ }
+ // Recursively compare arrays (susceptible to call stack limits).
+ if (isUnordered) {
+ if (!baseSome(other, function(othValue) {
+ return arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack);
+ })) {
+ result = false;
+ break;
+ }
+ } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
+ result = false;
+ break;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * A specialized version of `baseIsEqualDeep` for comparing objects of
+ * the same `toStringTag`.
+ *
+ * **Note:** This function only supports comparing values with tags of
+ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {string} tag The `toStringTag` of the objects to compare.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+ function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
+ switch (tag) {
+
+ case boolTag:
+ case dateTag:
+ // Coerce dates and booleans to numbers, dates to milliseconds and booleans
+ // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
+ return +object == +other;
+
+ case errorTag:
+ return object.name == other.name && object.message == other.message;
+
+ case numberTag:
+ // Treat `NaN` vs. `NaN` as equal.
+ return (object != +object) ? other != +other : object == +other;
+
+ case regexpTag:
+ case stringTag:
+ // Coerce regexes to strings and treat strings primitives and string
+ // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
+ return object == (other + '');
+
+ }
+ return false;
+ }
+
+ /**
+ * A specialized version of `baseIsEqualDeep` for objects with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparisons.
+ * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` for more details.
+ * @param {Object} [stack] Tracks traversed `object` and `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+ function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
+ var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+ objProps = keys(object),
+ objLength = objProps.length,
+ othProps = keys(other),
+ othLength = othProps.length;
+
+ if (objLength != othLength && !isPartial) {
+ return false;
+ }
+ var index = objLength;
+ while (index--) {
+ var key = objProps[index];
+ if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
+ return false;
+ }
+ }
+ var result = true;
+
+ var skipCtor = isPartial;
+ while (++index < objLength) {
+ key = objProps[index];
+ var objValue = object[key],
+ othValue = other[key];
+
+ var compared;
+ // Recursively compare objects (susceptible to call stack limits).
+ if (!(compared === undefined
+ ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
+ : compared
+ )) {
+ result = false;
+ break;
+ }
+ skipCtor || (skipCtor = key == 'constructor');
+ }
+ if (result && !skipCtor) {
+ var objCtor = object.constructor,
+ othCtor = other.constructor;
+
+ // Non `Object` object instances with different constructors are not equal.
+ if (objCtor != othCtor &&
+ ('constructor' in object && 'constructor' in other) &&
+ !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
+ typeof othCtor == 'function' && othCtor instanceof othCtor)) {
+ result = false;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Gets the "length" property value of `object`.
+ *
+ * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
+ * that affects Safari on at least iOS 8.1-8.3 ARM64.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {*} Returns the "length" value.
+ */
+ var getLength = baseProperty('length');
+
+ /**
+ * Creates an array of index keys for `object` values of arrays,
+ * `arguments` objects, and strings, otherwise `null` is returned.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array|null} Returns index keys, else `null`.
+ */
+ function indexKeys(object) {
+ var length = object ? object.length : undefined;
+ return (isLength(length) && (isArray(object) || isString(object) || isArguments(object)))
+ ? baseTimes(length, String)
+ : null;
+ }
+
+ /**
+ * Checks if `value` is likely a prototype object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
+ */
+ function isPrototype(value) {
+ var Ctor = value && value.constructor,
+ proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
+
+ return value === proto;
+ }
+
+ /**
+ * Converts `value` to a function if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Function} Returns the function.
+ */
+ function toFunction(value) {
+ return typeof value == 'function' ? value : identity;
+ }
+
+ /**
+ * Creates a clone of `wrapper`.
+ *
+ * @private
+ * @param {Object} wrapper The wrapper to clone.
+ * @returns {Object} Returns the cloned wrapper.
+ */
+ function wrapperClone(wrapper) {
+ var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
+ result.__actions__ = copyArray(wrapper.__actions__);
+ return result;
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates an array with all falsey values removed. The values `false`, `null`,
+ * `0`, `""`, `undefined`, and `NaN` are falsey.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to compact.
+ * @returns {Array} Returns the new array of filtered values.
+ * @example
+ *
+ * _.compact([0, 1, false, 2, '', 3]);
+ * // => [1, 2, 3]
+ */
+ function compact(array) {
+ return baseFilter(array, Boolean);
+ }
+
+ /**
+ * Creates a new array concatenating `array` with any additional arrays
+ * and/or values.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to concatenate.
+ * @param {...*} [values] The values to concatenate.
+ * @returns {Array} Returns the new concatenated array.
+ * @example
+ *
+ * var array = [1];
+ * var other = _.concat(array, 2, [3], [[4]]);
+ *
+ * console.log(other);
+ * // => [1, 2, 3, [4]]
+ *
+ * console.log(array);
+ * // => [1]
+ */
+ var concat = rest(function(array, values) {
+ if (!isArray(array)) {
+ array = array == null ? [] : [Object(array)];
+ }
+ values = baseFlatten(values);
+ return arrayConcat(array, values);
+ });
+
+ /**
+ * Flattens `array` a single level.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to flatten.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * _.flatten([1, [2, 3, [4]]]);
+ * // => [1, 2, 3, [4]]
+ */
+ function flatten(array) {
+ var length = array ? array.length : 0;
+ return length ? baseFlatten(array) : [];
+ }
+
+ /**
+ * This method is like `_.flatten` except that it recursively flattens `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to recursively flatten.
+ * @returns {Array} Returns the new flattened array.
+ * @example
+ *
+ * _.flattenDeep([1, [2, 3, [4]]]);
+ * // => [1, 2, 3, 4]
+ */
+ function flattenDeep(array) {
+ var length = array ? array.length : 0;
+ return length ? baseFlatten(array, true) : [];
+ }
+
+ /**
+ * Gets the first element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @alias first
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the first element of `array`.
+ * @example
+ *
+ * _.head([1, 2, 3]);
+ * // => 1
+ *
+ * _.head([]);
+ * // => undefined
+ */
+ function head(array) {
+ return array ? array[0] : undefined;
+ }
+
+ /**
+ * Gets the index at which the first occurrence of `value` is found in `array`
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons. If `fromIndex` is negative, it's used as the offset
+ * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
+ * performs a faster binary search.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.indexOf([1, 2, 1, 2], 2);
+ * // => 1
+ *
+ * // using `fromIndex`
+ * _.indexOf([1, 2, 1, 2], 2, 2);
+ * // => 3
+ */
+ function indexOf(array, value, fromIndex) {
+ var length = array ? array.length : 0;
+ if (typeof fromIndex == 'number') {
+ fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
+ } else {
+ fromIndex = 0;
+ }
+ var index = (fromIndex || 0) - 1,
+ isReflexive = value === value;
+
+ while (++index < length) {
+ var other = array[index];
+ if ((isReflexive ? other === value : other !== other)) {
+ return index;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Gets the last element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the last element of `array`.
+ * @example
+ *
+ * _.last([1, 2, 3]);
+ * // => 3
+ */
+ function last(array) {
+ var length = array ? array.length : 0;
+ return length ? array[length - 1] : undefined;
+ }
+
+ /**
+ * Creates a slice of `array` from `start` up to, but not including, `end`.
+ *
+ * **Note:** This method is used instead of [`Array#slice`](https://mdn.io/Array/slice)
+ * to ensure dense arrays are returned.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to slice.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the slice of `array`.
+ */
+ function slice(array, start, end) {
+ var length = array ? array.length : 0;
+ start = start == null ? 0 : +start;
+ end = end === undefined ? length : +end;
+ return length ? baseSlice(array, start, end) : [];
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates a `lodash` object that wraps `value` with explicit method chaining enabled.
+ * The result of such method chaining must be unwrapped with `_#value`.
+ *
+ * @static
+ * @memberOf _
+ * @category Seq
+ * @param {*} value The value to wrap.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 },
+ * { 'user': 'pebbles', 'age': 1 }
+ * ];
+ *
+ * var youngest = _
+ * .chain(users)
+ * .sortBy('age')
+ * .map(function(o) {
+ * return o.user + ' is ' + o.age;
+ * })
+ * .head()
+ * .value();
+ * // => 'pebbles is 1'
+ */
+ function chain(value) {
+ var result = lodash(value);
+ result.__chain__ = true;
+ return result;
+ }
+
+ /**
+ * This method invokes `interceptor` and returns `value`. The interceptor is
+ * invoked with one argument; (value). The purpose of this method is to "tap into"
+ * a method chain in order to perform operations on intermediate results within
+ * the chain.
+ *
+ * @static
+ * @memberOf _
+ * @category Seq
+ * @param {*} value The value to provide to `interceptor`.
+ * @param {Function} interceptor The function to invoke.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * _([1, 2, 3])
+ * .tap(function(array) {
+ * array.pop();
+ * })
+ * .reverse()
+ * .value();
+ * // => [2, 1]
+ */
+ function tap(value, interceptor) {
+ interceptor(value);
+ return value;
+ }
+
+ /**
+ * This method is like `_.tap` except that it returns the result of `interceptor`.
+ *
+ * @static
+ * @memberOf _
+ * @category Seq
+ * @param {*} value The value to provide to `interceptor`.
+ * @param {Function} interceptor The function to invoke.
+ * @returns {*} Returns the result of `interceptor`.
+ * @example
+ *
+ * _(' abc ')
+ * .chain()
+ * .trim()
+ * .thru(function(value) {
+ * return [value];
+ * })
+ * .value();
+ * // => ['abc']
+ */
+ function thru(value, interceptor) {
+ return interceptor(value);
+ }
+
+ /**
+ * Enables explicit method chaining on the wrapper object.
+ *
+ * @name chain
+ * @memberOf _
+ * @category Seq
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 }
+ * ];
+ *
+ * // without explicit chaining
+ * _(users).head();
+ * // => { 'user': 'barney', 'age': 36 }
+ *
+ * // with explicit chaining
+ * _(users)
+ * .chain()
+ * .head()
+ * .pick('user')
+ * .value();
+ * // => { 'user': 'barney' }
+ */
+ function wrapperChain() {
+ return chain(this);
+ }
+
+ /**
+ * Executes the chained sequence to extract the unwrapped value.
+ *
+ * @name value
+ * @memberOf _
+ * @alias toJSON, valueOf
+ * @category Seq
+ * @returns {*} Returns the resolved unwrapped value.
+ * @example
+ *
+ * _([1, 2, 3]).value();
+ * // => [1, 2, 3]
+ */
+ function wrapperValue() {
+ return baseWrapperValue(this.__wrapped__, this.__actions__);
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Checks if `predicate` returns truthy for **all** elements of `collection`.
+ * Iteration is stopped once `predicate` returns falsey. The predicate is
+ * invoked with three arguments: (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {boolean} Returns `true` if all elements pass the predicate check, else `false`.
+ * @example
+ *
+ * _.every([true, 1, null, 'yes'], Boolean);
+ * // => false
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': false },
+ * { 'user': 'fred', 'active': false }
+ * ];
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.every(users, { 'user': 'barney', 'active': false });
+ * // => false
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.every(users, ['active', false]);
+ * // => true
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.every(users, 'active');
+ * // => false
+ */
+ function every(collection, predicate, guard) {
+ predicate = guard ? undefined : predicate;
+ return baseEvery(collection, baseIteratee(predicate));
+ }
+
+ /**
+ * Iterates over elements of `collection`, returning an array of all elements
+ * `predicate` returns truthy for. The predicate is invoked with three arguments:
+ * (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new filtered array.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': true },
+ * { 'user': 'fred', 'age': 40, 'active': false }
+ * ];
+ *
+ * _.filter(users, function(o) { return !o.active; });
+ * // => objects for ['fred']
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.filter(users, { 'age': 36, 'active': true });
+ * // => objects for ['barney']
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.filter(users, ['active', false]);
+ * // => objects for ['fred']
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.filter(users, 'active');
+ * // => objects for ['barney']
+ */
+ function filter(collection, predicate) {
+ return baseFilter(collection, baseIteratee(predicate));
+ }
+
+ /**
+ * Iterates over elements of `collection`, returning the first element
+ * `predicate` returns truthy for. The predicate is invoked with three arguments:
+ * (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to search.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @returns {*} Returns the matched element, else `undefined`.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': true },
+ * { 'user': 'fred', 'age': 40, 'active': false },
+ * { 'user': 'pebbles', 'age': 1, 'active': true }
+ * ];
+ *
+ * _.find(users, function(o) { return o.age < 40; });
+ * // => object for 'barney'
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.find(users, { 'age': 1, 'active': true });
+ * // => object for 'pebbles'
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.find(users, ['active', false]);
+ * // => object for 'fred'
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.find(users, 'active');
+ * // => object for 'barney'
+ */
+ function find(collection, predicate) {
+ return baseFind(collection, baseIteratee(predicate), baseEach);
+ }
+
+ /**
+ * Iterates over elements of `collection` invoking `iteratee` for each element.
+ * The iteratee is invoked with three arguments: (value, index|key, collection).
+ * Iteratee functions may exit iteration early by explicitly returning `false`.
+ *
+ * **Note:** As with other "Collections" methods, objects with a "length" property
+ * are iterated like arrays. To avoid this behavior use `_.forIn` or `_.forOwn`
+ * for object iteration.
+ *
+ * @static
+ * @memberOf _
+ * @alias each
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array|Object} Returns `collection`.
+ * @example
+ *
+ * _([1, 2]).forEach(function(value) {
+ * console.log(value);
+ * });
+ * // => logs `1` then `2`
+ *
+ * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
+ * console.log(key);
+ * });
+ * // => logs 'a' then 'b' (iteration order is not guaranteed)
+ */
+ function forEach(collection, iteratee) {
+ return baseEach(collection, toFunction(iteratee));
+ }
+
+ /**
+ * Invokes the method at `path` of each element in `collection`, returning
+ * an array of the results of each invoked method. Any additional arguments
+ * are provided to each invoked method. If `methodName` is a function it's
+ * invoked for, and `this` bound to, each element in `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Array|Function|string} path The path of the method to invoke or
+ * the function invoked per iteration.
+ * @param {...*} [args] The arguments to invoke each method with.
+ * @returns {Array} Returns the array of results.
+ * @example
+ *
+ * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
+ * // => [[1, 5, 7], [1, 2, 3]]
+ *
+ * _.invokeMap([123, 456], String.prototype.split, '');
+ * // => [['1', '2', '3'], ['4', '5', '6']]
+ */
+ var invokeMap = rest(function(collection, path, args) {
+ var isFunc = typeof path == 'function';
+ return baseMap(collection, function(value) {
+ var func = isFunc ? path : value[path];
+ return func == null ? func : func.apply(value, args);
+ });
+ });
+
+ /**
+ * Creates an array of values by running each element in `collection` through
+ * `iteratee`. The iteratee is invoked with three arguments:
+ * (value, index|key, collection).
+ *
+ * Many lodash methods are guarded to work as iteratees for methods like
+ * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
+ *
+ * The guarded methods are:
+ * `ary`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, `fill`,
+ * `invert`, `parseInt`, `random`, `range`, `rangeRight`, `slice`, `some`,
+ * `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimEnd`, `trimStart`,
+ * and `words`
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ * @example
+ *
+ * function square(n) {
+ * return n * n;
+ * }
+ *
+ * _.map([4, 8], square);
+ * // => [16, 64]
+ *
+ * _.map({ 'a': 4, 'b': 8 }, square);
+ * // => [16, 64] (iteration order is not guaranteed)
+ *
+ * var users = [
+ * { 'user': 'barney' },
+ * { 'user': 'fred' }
+ * ];
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.map(users, 'user');
+ * // => ['barney', 'fred']
+ */
+ function map(collection, iteratee) {
+ return baseMap(collection, baseIteratee(iteratee));
+ }
+
+ /**
+ * Reduces `collection` to a value which is the accumulated result of running
+ * each element in `collection` through `iteratee`, where each successive
+ * invocation is supplied the return value of the previous. If `accumulator`
+ * is not provided the first element of `collection` is used as the initial
+ * value. The iteratee is invoked with four arguments:
+ * (accumulator, value, index|key, collection).
+ *
+ * Many lodash methods are guarded to work as iteratees for methods like
+ * `_.reduce`, `_.reduceRight`, and `_.transform`.
+ *
+ * The guarded methods are:
+ * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
+ * and `sortBy`
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @returns {*} Returns the accumulated value.
+ * @example
+ *
+ * _.reduce([1, 2], function(sum, n) {
+ * return sum + n;
+ * });
+ * // => 3
+ *
+ * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
+ * (result[value] || (result[value] = [])).push(key);
+ * return result;
+ * }, {});
+ * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
+ */
+ function reduce(collection, iteratee, accumulator) {
+ return baseReduce(collection, baseIteratee(iteratee), accumulator, arguments.length < 3, baseEach);
+ }
+
+ /**
+ * Gets the size of `collection` by returning its length for array-like
+ * values or the number of own enumerable properties for objects.
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to inspect.
+ * @returns {number} Returns the collection size.
+ * @example
+ *
+ * _.size([1, 2, 3]);
+ * // => 3
+ *
+ * _.size({ 'a': 1, 'b': 2 });
+ * // => 2
+ *
+ * _.size('pebbles');
+ * // => 7
+ */
+ function size(collection) {
+ if (collection == null) {
+ return 0;
+ }
+ collection = isArrayLike(collection) ? collection : keys(collection);
+ return collection.length;
+ }
+
+ /**
+ * Checks if `predicate` returns truthy for **any** element of `collection`.
+ * Iteration is stopped once `predicate` returns truthy. The predicate is
+ * invoked with three arguments: (value, index|key, collection).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {boolean} Returns `true` if any element passes the predicate check, else `false`.
+ * @example
+ *
+ * _.some([null, 0, 'yes', false], Boolean);
+ * // => true
+ *
+ * var users = [
+ * { 'user': 'barney', 'active': true },
+ * { 'user': 'fred', 'active': false }
+ * ];
+ *
+ * // using the `_.matches` iteratee shorthand
+ * _.some(users, { 'user': 'barney', 'active': false });
+ * // => false
+ *
+ * // using the `_.matchesProperty` iteratee shorthand
+ * _.some(users, ['active', false]);
+ * // => true
+ *
+ * // using the `_.property` iteratee shorthand
+ * _.some(users, 'active');
+ * // => true
+ */
+ function some(collection, predicate, guard) {
+ predicate = guard ? undefined : predicate;
+ return baseSome(collection, baseIteratee(predicate));
+ }
+
+ /**
+ * Creates an array of elements, sorted in ascending order by the results of
+ * running each element in a collection through each iteratee. This method
+ * performs a stable sort, that is, it preserves the original sort order of
+ * equal elements. The iteratees are invoked with one argument: (value).
+ *
+ * @static
+ * @memberOf _
+ * @category Collection
+ * @param {Array|Object} collection The collection to iterate over.
+ * @param {...(Function|Function[]|Object|Object[]|string|string[])} [iteratees=[_.identity]]
+ * The iteratees to sort by, specified individually or in arrays.
+ * @returns {Array} Returns the new sorted array.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'fred', 'age': 48 },
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 42 },
+ * { 'user': 'barney', 'age': 34 }
+ * ];
+ *
+ * _.sortBy(users, function(o) { return o.user; });
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
+ *
+ * _.sortBy(users, ['user', 'age']);
+ * // => objects for [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]]
+ *
+ * _.sortBy(users, 'user', function(o) {
+ * return Math.floor(o.age / 10);
+ * });
+ * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]]
+ */
+ function sortBy(collection, iteratee) {
+ var index = 0;
+ iteratee = baseIteratee(iteratee);
+
+ return baseMap(baseMap(collection, function(value, key, collection) {
+ return { 'value': value, 'index': index++, 'criteria': iteratee(value, key, collection) };
+ }).sort(function(object, other) {
+ return compareAscending(object.criteria, other.criteria) || (object.index - other.index);
+ }), baseProperty('value'));
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Gets the timestamp of the number of milliseconds that have elapsed since
+ * the Unix epoch (1 January 1970 00:00:00 UTC).
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Date
+ * @returns {number} Returns the timestamp.
+ * @example
+ *
+ * _.defer(function(stamp) {
+ * console.log(_.now() - stamp);
+ * }, _.now());
+ * // => logs the number of milliseconds it took for the deferred function to be invoked
+ */
+ var now = Date.now;
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates a function that invokes `func`, with the `this` binding and arguments
+ * of the created function, while it's called less than `n` times. Subsequent
+ * calls to the created function return the result of the last `func` invocation.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {number} n The number of calls at which `func` is no longer invoked.
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * jQuery(element).on('click', _.before(5, addContactToList));
+ * // => allows adding up to 4 contacts to the list
+ */
+ function before(n, func) {
+ var result;
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ n = toInteger(n);
+ return function() {
+ if (--n > 0) {
+ result = func.apply(this, arguments);
+ }
+ if (n <= 1) {
+ func = undefined;
+ }
+ return result;
+ };
+ }
+
+ /**
+ * Creates a function that invokes `func` with the `this` binding of `thisArg`
+ * and prepends any additional `_.bind` arguments to those provided to the
+ * bound function.
+ *
+ * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
+ * may be used as a placeholder for partially applied arguments.
+ *
+ * **Note:** Unlike native `Function#bind` this method doesn't set the "length"
+ * property of bound functions.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to bind.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {...*} [partials] The arguments to be partially applied.
+ * @returns {Function} Returns the new bound function.
+ * @example
+ *
+ * var greet = function(greeting, punctuation) {
+ * return greeting + ' ' + this.user + punctuation;
+ * };
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * var bound = _.bind(greet, object, 'hi');
+ * bound('!');
+ * // => 'hi fred!'
+ *
+ * // using placeholders
+ * var bound = _.bind(greet, object, _, '!');
+ * bound('hi');
+ * // => 'hi fred!'
+ */
+ var bind = rest(function(func, thisArg, partials) {
+ return createPartialWrapper(func, BIND_FLAG | PARTIAL_FLAG, thisArg, partials);
+ });
+
+ /**
+ * Defers invoking the `func` until the current call stack has cleared. Any
+ * additional arguments are provided to `func` when it's invoked.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to defer.
+ * @param {...*} [args] The arguments to invoke `func` with.
+ * @returns {number} Returns the timer id.
+ * @example
+ *
+ * _.defer(function(text) {
+ * console.log(text);
+ * }, 'deferred');
+ * // logs 'deferred' after one or more milliseconds
+ */
+ var defer = rest(function(func, args) {
+ return baseDelay(func, 1, args);
+ });
+
+ /**
+ * Invokes `func` after `wait` milliseconds. Any additional arguments are
+ * provided to `func` when it's invoked.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to delay.
+ * @param {number} wait The number of milliseconds to delay invocation.
+ * @param {...*} [args] The arguments to invoke `func` with.
+ * @returns {number} Returns the timer id.
+ * @example
+ *
+ * _.delay(function(text) {
+ * console.log(text);
+ * }, 1000, 'later');
+ * // => logs 'later' after one second
+ */
+ var delay = rest(function(func, wait, args) {
+ return baseDelay(func, toNumber(wait) || 0, args);
+ });
+
+ /**
+ * Creates a function that negates the result of the predicate `func`. The
+ * `func` predicate is invoked with the `this` binding and arguments of the
+ * created function.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} predicate The predicate to negate.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * function isEven(n) {
+ * return n % 2 == 0;
+ * }
+ *
+ * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
+ * // => [1, 3, 5]
+ */
+ function negate(predicate) {
+ if (typeof predicate != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ return function() {
+ return !predicate.apply(this, arguments);
+ };
+ }
+
+ /**
+ * Creates a function that is restricted to invoking `func` once. Repeat calls
+ * to the function return the value of the first invocation. The `func` is
+ * invoked with the `this` binding and arguments of the created function.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to restrict.
+ * @returns {Function} Returns the new restricted function.
+ * @example
+ *
+ * var initialize = _.once(createApplication);
+ * initialize();
+ * initialize();
+ * // `initialize` invokes `createApplication` once
+ */
+ function once(func) {
+ return before(2, func);
+ }
+
+ /**
+ * Creates a function that invokes `func` with the `this` binding of the
+ * created function and arguments from `start` and beyond provided as an array.
+ *
+ * **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var say = _.rest(function(what, names) {
+ * return what + ' ' + _.initial(names).join(', ') +
+ * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
+ * });
+ *
+ * say('hello', 'fred', 'barney', 'pebbles');
+ * // => 'hello fred, barney, & pebbles'
+ */
+ function rest(func, start) {
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
+ return function() {
+ var args = arguments,
+ index = -1,
+ length = nativeMax(args.length - start, 0),
+ array = Array(length);
+
+ while (++index < length) {
+ array[index] = args[start + index];
+ }
+ var otherArgs = Array(start + 1);
+ index = -1;
+ while (++index < start) {
+ otherArgs[index] = args[index];
+ }
+ otherArgs[start] = array;
+ return func.apply(this, otherArgs);
+ };
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Creates a shallow clone of `value`.
+ *
+ * **Note:** This method is loosely based on the
+ * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
+ * and supports cloning arrays, array buffers, booleans, date objects, maps,
+ * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
+ * arrays. The own enumerable properties of `arguments` objects are cloned
+ * as plain objects. An empty object is returned for uncloneable values such
+ * as error objects, functions, DOM nodes, and WeakMaps.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to clone.
+ * @returns {*} Returns the cloned value.
+ * @example
+ *
+ * var objects = [{ 'a': 1 }, { 'b': 2 }];
+ *
+ * var shallow = _.clone(objects);
+ * console.log(shallow[0] === objects[0]);
+ * // => true
+ */
+ function clone(value) {
+ if (!isObject(value)) {
+ return value;
+ }
+ return isArray(value) ? copyArray(value) : copyObject(value, keys(value));
+ }
+
+ /**
+ * Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * comparison between two values to determine if they are equivalent.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ * var other = { 'user': 'fred' };
+ *
+ * _.eq(object, object);
+ * // => true
+ *
+ * _.eq(object, other);
+ * // => false
+ *
+ * _.eq('a', 'a');
+ * // => true
+ *
+ * _.eq('a', Object('a'));
+ * // => false
+ *
+ * _.eq(NaN, NaN);
+ * // => true
+ */
+ function eq(value, other) {
+ return value === other || (value !== value && other !== other);
+ }
+
+ /**
+ * Checks if `value` is greater than `other`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`.
+ * @example
+ *
+ * _.gt(3, 1);
+ * // => true
+ *
+ * _.gt(3, 3);
+ * // => false
+ *
+ * _.gt(1, 3);
+ * // => false
+ */
+ function gt(value, other) {
+ return value > other;
+ }
+
+ /**
+ * Checks if `value` is likely an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */
+ function isArguments(value) {
+ // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
+ return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
+ (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
+ }
+
+ /**
+ * Checks if `value` is classified as an `Array` object.
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArray([1, 2, 3]);
+ * // => true
+ *
+ * _.isArray(document.body.children);
+ * // => false
+ *
+ * _.isArray('abc');
+ * // => false
+ *
+ * _.isArray(_.noop);
+ * // => false
+ */
+ var isArray = Array.isArray;
+
+ /**
+ * Checks if `value` is array-like. A value is considered array-like if it's
+ * not a function and has a `value.length` that's an integer greater than or
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ * @example
+ *
+ * _.isArrayLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLike(document.body.children);
+ * // => true
+ *
+ * _.isArrayLike('abc');
+ * // => true
+ *
+ * _.isArrayLike(_.noop);
+ * // => false
+ */
+ function isArrayLike(value) {
+ return value != null &&
+ !(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
+ }
+
+ /**
+ * This method is like `_.isArrayLike` except that it also checks if `value`
+ * is an object.
+ *
+ * @static
+ * @memberOf _
+ * @type Function
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
+ * @example
+ *
+ * _.isArrayLikeObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLikeObject(document.body.children);
+ * // => true
+ *
+ * _.isArrayLikeObject('abc');
+ * // => false
+ *
+ * _.isArrayLikeObject(_.noop);
+ * // => false
+ */
+ function isArrayLikeObject(value) {
+ return isObjectLike(value) && isArrayLike(value);
+ }
+
+ /**
+ * Checks if `value` is classified as a boolean primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isBoolean(false);
+ * // => true
+ *
+ * _.isBoolean(null);
+ * // => false
+ */
+ function isBoolean(value) {
+ return value === true || value === false ||
+ (isObjectLike(value) && objectToString.call(value) == boolTag);
+ }
+
+ /**
+ * Checks if `value` is classified as a `Date` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isDate(new Date);
+ * // => true
+ *
+ * _.isDate('Mon April 23 2012');
+ * // => false
+ */
+ function isDate(value) {
+ return isObjectLike(value) && objectToString.call(value) == dateTag;
+ }
+
+ /**
+ * Checks if `value` is empty. A value is considered empty unless it's an
+ * `arguments` object, array, string, or jQuery-like collection with a length
+ * greater than `0` or an object with own enumerable properties.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {Array|Object|string} value The value to inspect.
+ * @returns {boolean} Returns `true` if `value` is empty, else `false`.
+ * @example
+ *
+ * _.isEmpty(null);
+ * // => true
+ *
+ * _.isEmpty(true);
+ * // => true
+ *
+ * _.isEmpty(1);
+ * // => true
+ *
+ * _.isEmpty([1, 2, 3]);
+ * // => false
+ *
+ * _.isEmpty({ 'a': 1 });
+ * // => false
+ */
+ function isEmpty(value) {
+ return (!isObjectLike(value) || isFunction(value.splice))
+ ? !size(value)
+ : !keys(value).length;
+ }
+
+ /**
+ * Performs a deep comparison between two values to determine if they are
+ * equivalent.
+ *
+ * **Note:** This method supports comparing arrays, array buffers, booleans,
+ * date objects, error objects, maps, numbers, `Object` objects, regexes,
+ * sets, strings, symbols, and typed arrays. `Object` objects are compared
+ * by their own, not inherited, enumerable properties. Functions and DOM
+ * nodes are **not** supported.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ * var other = { 'user': 'fred' };
+ *
+ * _.isEqual(object, other);
+ * // => true
+ *
+ * object === other;
+ * // => false
+ */
+ function isEqual(value, other) {
+ return baseIsEqual(value, other);
+ }
+
+ /**
+ * Checks if `value` is a finite primitive number.
+ *
+ * **Note:** This method is based on [`Number.isFinite`](https://mdn.io/Number/isFinite).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
+ * @example
+ *
+ * _.isFinite(3);
+ * // => true
+ *
+ * _.isFinite(Number.MAX_VALUE);
+ * // => true
+ *
+ * _.isFinite(3.14);
+ * // => true
+ *
+ * _.isFinite(Infinity);
+ * // => false
+ */
+ function isFinite(value) {
+ return typeof value == 'number' && nativeIsFinite(value);
+ }
+
+ /**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */
+ function isFunction(value) {
+ // The use of `Object#toString` avoids issues with the `typeof` operator
+ // in Safari 8 which returns 'object' for typed array constructors, and
+ // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
+ var tag = isObject(value) ? objectToString.call(value) : '';
+ return tag == funcTag || tag == genTag;
+ }
+
+ /**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ * @example
+ *
+ * _.isLength(3);
+ * // => true
+ *
+ * _.isLength(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isLength(Infinity);
+ * // => false
+ *
+ * _.isLength('3');
+ * // => false
+ */
+ function isLength(value) {
+ return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+ }
+
+ /**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(_.noop);
+ * // => true
+ *
+ * _.isObject(null);
+ * // => false
+ */
+ function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return !!value && (type == 'object' || type == 'function');
+ }
+
+ /**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+ function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+ }
+
+ /**
+ * Checks if `value` is `NaN`.
+ *
+ * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4)
+ * which returns `true` for `undefined` and other non-numeric values.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
+ * @example
+ *
+ * _.isNaN(NaN);
+ * // => true
+ *
+ * _.isNaN(new Number(NaN));
+ * // => true
+ *
+ * isNaN(undefined);
+ * // => true
+ *
+ * _.isNaN(undefined);
+ * // => false
+ */
+ function isNaN(value) {
+ // An `NaN` primitive is the only value that is not equal to itself.
+ // Perform the `toStringTag` check first to avoid errors with some ActiveX objects in IE.
+ return isNumber(value) && value != +value;
+ }
+
+ /**
+ * Checks if `value` is `null`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
+ * @example
+ *
+ * _.isNull(null);
+ * // => true
+ *
+ * _.isNull(void 0);
+ * // => false
+ */
+ function isNull(value) {
+ return value === null;
+ }
+
+ /**
+ * Checks if `value` is classified as a `Number` primitive or object.
+ *
+ * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified
+ * as numbers, use the `_.isFinite` method.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isNumber(3);
+ * // => true
+ *
+ * _.isNumber(Number.MIN_VALUE);
+ * // => true
+ *
+ * _.isNumber(Infinity);
+ * // => true
+ *
+ * _.isNumber('3');
+ * // => false
+ */
+ function isNumber(value) {
+ return typeof value == 'number' ||
+ (isObjectLike(value) && objectToString.call(value) == numberTag);
+ }
+
+ /**
+ * Checks if `value` is classified as a `RegExp` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isRegExp(/abc/);
+ * // => true
+ *
+ * _.isRegExp('/abc/');
+ * // => false
+ */
+ function isRegExp(value) {
+ return isObject(value) && objectToString.call(value) == regexpTag;
+ }
+
+ /**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isString('abc');
+ * // => true
+ *
+ * _.isString(1);
+ * // => false
+ */
+ function isString(value) {
+ return typeof value == 'string' ||
+ (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
+ }
+
+ /**
+ * Checks if `value` is `undefined`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
+ * @example
+ *
+ * _.isUndefined(void 0);
+ * // => true
+ *
+ * _.isUndefined(null);
+ * // => false
+ */
+ function isUndefined(value) {
+ return value === undefined;
+ }
+
+ /**
+ * Checks if `value` is less than `other`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
+ * @example
+ *
+ * _.lt(1, 3);
+ * // => true
+ *
+ * _.lt(3, 3);
+ * // => false
+ *
+ * _.lt(3, 1);
+ * // => false
+ */
+ function lt(value, other) {
+ return value < other;
+ }
+
+ /**
+ * Converts `value` to an array.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {Array} Returns the converted array.
+ * @example
+ *
+ * _.toArray({ 'a': 1, 'b': 2 });
+ * // => [1, 2]
+ *
+ * _.toArray('abc');
+ * // => ['a', 'b', 'c']
+ *
+ * _.toArray(1);
+ * // => []
+ *
+ * _.toArray(null);
+ * // => []
+ */
+ function toArray(value) {
+ if (!isArrayLike(value)) {
+ return values(value);
+ }
+ return value.length ? copyArray(value) : [];
+ }
+
+ /**
+ * Converts `value` to an integer.
+ *
+ * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to convert.
+ * @returns {number} Returns the converted integer.
+ * @example
+ *
+ * _.toInteger(3);
+ * // => 3
+ *
+ * _.toInteger(Number.MIN_VALUE);
+ * // => 0
+ *
+ * _.toInteger(Infinity);
+ * // => 1.7976931348623157e+308
+ *
+ * _.toInteger('3');
+ * // => 3
+ */
+ var toInteger = Number;
+
+ /**
+ * Converts `value` to a number.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {number} Returns the number.
+ * @example
+ *
+ * _.toNumber(3);
+ * // => 3
+ *
+ * _.toNumber(Number.MIN_VALUE);
+ * // => 5e-324
+ *
+ * _.toNumber(Infinity);
+ * // => Infinity
+ *
+ * _.toNumber('3');
+ * // => 3
+ */
+ var toNumber = Number;
+
+ /**
+ * Converts `value` to a string if it's not one. An empty string is returned
+ * for `null` and `undefined` values. The sign of `-0` is preserved.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ * @example
+ *
+ * _.toString(null);
+ * // => ''
+ *
+ * _.toString(-0);
+ * // => '-0'
+ *
+ * _.toString([1, 2, 3]);
+ * // => '1,2,3'
+ */
+ function toString(value) {
+ if (typeof value == 'string') {
+ return value;
+ }
+ return value == null ? '' : (value + '');
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Assigns own enumerable properties of source objects to the destination
+ * object. Source objects are applied from left to right. Subsequent sources
+ * overwrite property assignments of previous sources.
+ *
+ * **Note:** This method mutates `object` and is loosely based on
+ * [`Object.assign`](https://mdn.io/Object/assign).
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function Foo() {
+ * this.c = 3;
+ * }
+ *
+ * function Bar() {
+ * this.e = 5;
+ * }
+ *
+ * Foo.prototype.d = 4;
+ * Bar.prototype.f = 6;
+ *
+ * _.assign({ 'a': 1 }, new Foo, new Bar);
+ * // => { 'a': 1, 'c': 3, 'e': 5 }
+ */
+ var assign = createAssigner(function(object, source) {
+ copyObject(source, keys(source), object);
+ });
+
+ /**
+ * This method is like `_.assign` except that it iterates over own and
+ * inherited source properties.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @alias extend
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function Foo() {
+ * this.b = 2;
+ * }
+ *
+ * function Bar() {
+ * this.d = 4;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ * Bar.prototype.e = 5;
+ *
+ * _.assignIn({ 'a': 1 }, new Foo, new Bar);
+ * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
+ */
+ var assignIn = createAssigner(function(object, source) {
+ copyObject(source, keysIn(source), object);
+ });
+
+ /**
+ * This method is like `_.assignIn` except that it accepts `customizer` which
+ * is invoked to produce the assigned values. If `customizer` returns `undefined`
+ * assignment is handled by the method instead. The `customizer` is invoked
+ * with five arguments: (objValue, srcValue, key, object, source).
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @alias extendWith
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} sources The source objects.
+ * @param {Function} [customizer] The function to customize assigned values.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function customizer(objValue, srcValue) {
+ * return _.isUndefined(objValue) ? srcValue : objValue;
+ * }
+ *
+ * var defaults = _.partialRight(_.assignInWith, customizer);
+ *
+ * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
+ * // => { 'a': 1, 'b': 2 }
+ */
+ var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
+ copyObjectWith(source, keysIn(source), object, customizer);
+ });
+
+ /**
+ * Creates an object that inherits from the `prototype` object. If a `properties`
+ * object is provided its own enumerable properties are assigned to the created object.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} prototype The object to inherit from.
+ * @param {Object} [properties] The properties to assign to the object.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * function Shape() {
+ * this.x = 0;
+ * this.y = 0;
+ * }
+ *
+ * function Circle() {
+ * Shape.call(this);
+ * }
+ *
+ * Circle.prototype = _.create(Shape.prototype, {
+ * 'constructor': Circle
+ * });
+ *
+ * var circle = new Circle;
+ * circle instanceof Circle;
+ * // => true
+ *
+ * circle instanceof Shape;
+ * // => true
+ */
+ function create(prototype, properties) {
+ var result = baseCreate(prototype);
+ return properties ? assign(result, properties) : result;
+ }
+
+ /**
+ * Assigns own and inherited enumerable properties of source objects to the
+ * destination object for all destination properties that resolve to `undefined`.
+ * Source objects are applied from left to right. Once a property is set,
+ * additional values of the same property are ignored.
+ *
+ * **Note:** This method mutates `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The destination object.
+ * @param {...Object} [sources] The source objects.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
+ * // => { 'user': 'barney', 'age': 36 }
+ */
+ var defaults = rest(function(args) {
+ args.push(undefined, assignInDefaults);
+ return assignInWith.apply(undefined, args);
+ });
+
+ /**
+ * Checks if `path` is a direct property of `object`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path to check.
+ * @returns {boolean} Returns `true` if `path` exists, else `false`.
+ * @example
+ *
+ * var object = { 'a': { 'b': { 'c': 3 } } };
+ * var other = _.create({ 'a': _.create({ 'b': _.create({ 'c': 3 }) }) });
+ *
+ * _.has(object, 'a');
+ * // => true
+ *
+ * _.has(object, 'a.b.c');
+ * // => true
+ *
+ * _.has(object, ['a', 'b', 'c']);
+ * // => true
+ *
+ * _.has(other, 'a');
+ * // => false
+ */
+ function has(object, path) {
+ return object != null && hasOwnProperty.call(object, path);
+ }
+
+ /**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */
+ function keys(object) {
+ var isProto = isPrototype(object);
+ if (!(isProto || isArrayLike(object))) {
+ return baseKeys(object);
+ }
+ var indexes = indexKeys(object),
+ skipIndexes = !!indexes,
+ result = indexes || [],
+ length = result.length;
+
+ for (var key in object) {
+ if (hasOwnProperty.call(object, key) &&
+ !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+ !(isProto && key == 'constructor')) {
+ result.push(key);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Creates an array of the own and inherited enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keysIn(new Foo);
+ * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+ */
+ function keysIn(object) {
+ var index = -1,
+ isProto = isPrototype(object),
+ props = baseKeysIn(object),
+ propsLength = props.length,
+ indexes = indexKeys(object),
+ skipIndexes = !!indexes,
+ result = indexes || [],
+ length = result.length;
+
+ while (++index < propsLength) {
+ var key = props[index];
+ if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+ !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+ result.push(key);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Creates an object composed of the picked `object` properties.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The source object.
+ * @param {...(string|string[])} [props] The property names to pick, specified
+ * individually or in arrays.
+ * @returns {Object} Returns the new object.
+ * @example
+ *
+ * var object = { 'a': 1, 'b': '2', 'c': 3 };
+ *
+ * _.pick(object, ['a', 'c']);
+ * // => { 'a': 1, 'c': 3 }
+ */
+ var pick = rest(function(object, props) {
+ return object == null ? {} : basePick(object, baseFlatten(props));
+ });
+
+ /**
+ * This method is like `_.get` except that if the resolved value is a function
+ * it's invoked with the `this` binding of its parent object and its result
+ * is returned.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @param {Array|string} path The path of the property to resolve.
+ * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
+ * @returns {*} Returns the resolved value.
+ * @example
+ *
+ * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
+ *
+ * _.result(object, 'a[0].b.c1');
+ * // => 3
+ *
+ * _.result(object, 'a[0].b.c2');
+ * // => 4
+ *
+ * _.result(object, 'a[0].b.c3', 'default');
+ * // => 'default'
+ *
+ * _.result(object, 'a[0].b.c3', _.constant('default'));
+ * // => 'default'
+ */
+ function result(object, path, defaultValue) {
+ var value = object == null ? undefined : object[path];
+ if (value === undefined) {
+ value = defaultValue;
+ }
+ return isFunction(value) ? value.call(object) : value;
+ }
+
+ /**
+ * Creates an array of the own enumerable property values of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property values.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.values(new Foo);
+ * // => [1, 2] (iteration order is not guaranteed)
+ *
+ * _.values('hi');
+ * // => ['h', 'i']
+ */
+ function values(object) {
+ return object ? baseValues(object, keys(object)) : [];
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
+ * their corresponding HTML entities.
+ *
+ * **Note:** No other characters are escaped. To escape additional
+ * characters use a third-party library like [_he_](https://mths.be/he).
+ *
+ * Though the ">" character is escaped for symmetry, characters like
+ * ">" and "/" don't need escaping in HTML and have no special meaning
+ * unless they're part of a tag or unquoted attribute value.
+ * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
+ * (under "semi-related fun fact") for more details.
+ *
+ * Backticks are escaped because in IE < 9, they can break out of
+ * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
+ * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
+ * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
+ * for more details.
+ *
+ * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
+ * to reduce XSS vectors.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to escape.
+ * @returns {string} Returns the escaped string.
+ * @example
+ *
+ * _.escape('fred, barney, & pebbles');
+ * // => 'fred, barney, & pebbles'
+ */
+ function escape(string) {
+ string = toString(string);
+ return (string && reHasUnescapedHtml.test(string))
+ ? string.replace(reUnescapedHtml, escapeHtmlChar)
+ : string;
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * This method returns the first argument provided to it.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {*} value Any value.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.identity(object) === object;
+ * // => true
+ */
+ function identity(value) {
+ return value;
+ }
+
+ /**
+ * Creates a function that invokes `func` with the arguments of the created
+ * function. If `func` is a property name the created callback returns the
+ * property value for a given element. If `func` is an object the created
+ * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {*} [func=_.identity] The value to convert to a callback.
+ * @returns {Function} Returns the callback.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36 },
+ * { 'user': 'fred', 'age': 40 }
+ * ];
+ *
+ * // create custom iteratee shorthands
+ * _.iteratee = _.wrap(_.iteratee, function(callback, func) {
+ * var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func);
+ * return !p ? callback(func) : function(object) {
+ * return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]);
+ * };
+ * });
+ *
+ * _.filter(users, 'age > 36');
+ * // => [{ 'user': 'fred', 'age': 40 }]
+ */
+ var iteratee = baseIteratee;
+
+ /**
+ * Creates a function that performs a deep partial comparison between a given
+ * object and `source`, returning `true` if the given object has equivalent
+ * property values, else `false`.
+ *
+ * **Note:** This method supports comparing the same values as `_.isEqual`.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {Object} source The object of property values to match.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var users = [
+ * { 'user': 'barney', 'age': 36, 'active': true },
+ * { 'user': 'fred', 'age': 40, 'active': false }
+ * ];
+ *
+ * _.filter(users, _.matches({ 'age': 40, 'active': false }));
+ * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
+ */
+ function matches(source) {
+ return baseMatches(assign({}, source));
+ }
+
+ /**
+ * Adds all own enumerable function properties of a source object to the
+ * destination object. If `object` is a function then methods are added to
+ * its prototype as well.
+ *
+ * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
+ * avoid conflicts caused by modifying the original.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {Function|Object} [object=lodash] The destination object.
+ * @param {Object} source The object of functions to add.
+ * @param {Object} [options] The options object.
+ * @param {boolean} [options.chain=true] Specify whether the functions added
+ * are chainable.
+ * @returns {Function|Object} Returns `object`.
+ * @example
+ *
+ * function vowels(string) {
+ * return _.filter(string, function(v) {
+ * return /[aeiou]/i.test(v);
+ * });
+ * }
+ *
+ * _.mixin({ 'vowels': vowels });
+ * _.vowels('fred');
+ * // => ['e']
+ *
+ * _('fred').vowels().value();
+ * // => ['e']
+ *
+ * _.mixin({ 'vowels': vowels }, { 'chain': false });
+ * _('fred').vowels();
+ * // => ['e']
+ */
+ function mixin(object, source, options) {
+ var props = keys(source),
+ methodNames = baseFunctions(source, props);
+
+ if (options == null &&
+ !(isObject(source) && (methodNames.length || !props.length))) {
+ options = source;
+ source = object;
+ object = this;
+ methodNames = baseFunctions(source, keys(source));
+ }
+ var chain = (isObject(options) && 'chain' in options) ? options.chain : true,
+ isFunc = isFunction(object);
+
+ baseEach(methodNames, function(methodName) {
+ var func = source[methodName];
+ object[methodName] = func;
+ if (isFunc) {
+ object.prototype[methodName] = function() {
+ var chainAll = this.__chain__;
+ if (chain || chainAll) {
+ var result = object(this.__wrapped__),
+ actions = result.__actions__ = copyArray(this.__actions__);
+
+ actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
+ result.__chain__ = chainAll;
+ return result;
+ }
+ return func.apply(object, arrayPush([this.value()], arguments));
+ };
+ }
+ });
+
+ return object;
+ }
+
+ /**
+ * Reverts the `_` variable to its previous value and returns a reference to
+ * the `lodash` function.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @returns {Function} Returns the `lodash` function.
+ * @example
+ *
+ * var lodash = _.noConflict();
+ */
+ function noConflict() {
+ if (root._ === this) {
+ root._ = oldDash;
+ }
+ return this;
+ }
+
+ /**
+ * A no-operation function that returns `undefined` regardless of the
+ * arguments it receives.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.noop(object) === undefined;
+ * // => true
+ */
+ function noop() {
+ // No operation performed.
+ }
+
+ /**
+ * Generates a unique ID. If `prefix` is provided the ID is appended to it.
+ *
+ * @static
+ * @memberOf _
+ * @category Util
+ * @param {string} [prefix] The value to prefix the ID with.
+ * @returns {string} Returns the unique ID.
+ * @example
+ *
+ * _.uniqueId('contact_');
+ * // => 'contact_104'
+ *
+ * _.uniqueId();
+ * // => '105'
+ */
+ function uniqueId(prefix) {
+ var id = ++idCounter;
+ return toString(prefix) + id;
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * Computes the maximum value of `array`. If `array` is empty or falsey
+ * `undefined` is returned.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @returns {*} Returns the maximum value.
+ * @example
+ *
+ * _.max([4, 2, 8, 6]);
+ * // => 8
+ *
+ * _.max([]);
+ * // => undefined
+ */
+ function max(array) {
+ return (array && array.length)
+ ? baseExtremum(array, identity, gt)
+ : undefined;
+ }
+
+ /**
+ * Computes the minimum value of `array`. If `array` is empty or falsey
+ * `undefined` is returned.
+ *
+ * @static
+ * @memberOf _
+ * @category Math
+ * @param {Array} array The array to iterate over.
+ * @returns {*} Returns the minimum value.
+ * @example
+ *
+ * _.min([4, 2, 8, 6]);
+ * // => 2
+ *
+ * _.min([]);
+ * // => undefined
+ */
+ function min(array) {
+ return (array && array.length)
+ ? baseExtremum(array, identity, lt)
+ : undefined;
+ }
+
+ /*------------------------------------------------------------------------*/
+
+ LodashWrapper.prototype = baseCreate(lodash.prototype);
+ LodashWrapper.prototype.constructor = LodashWrapper;
+
+ // Add functions that return wrapped values when chaining.
+ lodash.assignIn = assignIn;
+ lodash.before = before;
+ lodash.bind = bind;
+ lodash.chain = chain;
+ lodash.compact = compact;
+ lodash.concat = concat;
+ lodash.create = create;
+ lodash.defaults = defaults;
+ lodash.defer = defer;
+ lodash.delay = delay;
+ lodash.filter = filter;
+ lodash.flatten = flatten;
+ lodash.flattenDeep = flattenDeep;
+ lodash.invokeMap = invokeMap;
+ lodash.iteratee = iteratee;
+ lodash.keys = keys;
+ lodash.map = map;
+ lodash.matches = matches;
+ lodash.mixin = mixin;
+ lodash.negate = negate;
+ lodash.once = once;
+ lodash.pick = pick;
+ lodash.slice = slice;
+ lodash.sortBy = sortBy;
+ lodash.tap = tap;
+ lodash.thru = thru;
+ lodash.toArray = toArray;
+ lodash.values = values;
+
+ // Add aliases.
+ lodash.extend = assignIn;
+
+ // Add functions to `lodash.prototype`.
+ mixin(lodash, lodash);
+
+ /*------------------------------------------------------------------------*/
+
+ // Add functions that return unwrapped values when chaining.
+ lodash.clone = clone;
+ lodash.escape = escape;
+ lodash.every = every;
+ lodash.find = find;
+ lodash.forEach = forEach;
+ lodash.has = has;
+ lodash.head = head;
+ lodash.identity = identity;
+ lodash.indexOf = indexOf;
+ lodash.isArguments = isArguments;
+ lodash.isArray = isArray;
+ lodash.isBoolean = isBoolean;
+ lodash.isDate = isDate;
+ lodash.isEmpty = isEmpty;
+ lodash.isEqual = isEqual;
+ lodash.isFinite = isFinite;
+ lodash.isFunction = isFunction;
+ lodash.isNaN = isNaN;
+ lodash.isNull = isNull;
+ lodash.isNumber = isNumber;
+ lodash.isObject = isObject;
+ lodash.isRegExp = isRegExp;
+ lodash.isString = isString;
+ lodash.isUndefined = isUndefined;
+ lodash.last = last;
+ lodash.max = max;
+ lodash.min = min;
+ lodash.noConflict = noConflict;
+ lodash.noop = noop;
+ lodash.now = now;
+ lodash.reduce = reduce;
+ lodash.result = result;
+ lodash.size = size;
+ lodash.some = some;
+ lodash.uniqueId = uniqueId;
+
+ // Add aliases.
+ lodash.each = forEach;
+ lodash.first = head;
+
+ mixin(lodash, (function() {
+ var source = {};
+ baseForOwn(lodash, function(func, methodName) {
+ if (!hasOwnProperty.call(lodash.prototype, methodName)) {
+ source[methodName] = func;
+ }
+ });
+ return source;
+ }()), { 'chain': false });
+
+ /*------------------------------------------------------------------------*/
+
+ /**
+ * The semantic version number.
+ *
+ * @static
+ * @memberOf _
+ * @type string
+ */
+ lodash.VERSION = VERSION;
+
+ // Add `Array` and `String` methods to `lodash.prototype`.
+ baseEach(['pop', 'join', 'replace', 'reverse', 'split', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
+ var func = (/^(?:replace|split)$/.test(methodName) ? String.prototype : arrayProto)[methodName],
+ chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
+ retUnwrapped = /^(?:pop|join|replace|shift)$/.test(methodName);
+
+ lodash.prototype[methodName] = function() {
+ var args = arguments;
+ if (retUnwrapped && !this.__chain__) {
+ return func.apply(this.value(), args);
+ }
+ return this[chainName](function(value) {
+ return func.apply(value, args);
+ });
+ };
+ });
+
+ // Add chaining functions to the `lodash` wrapper.
+ lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
+
+ /*--------------------------------------------------------------------------*/
+
+ // Expose lodash on the free variable `window` or `self` when available. This
+ // prevents errors in cases where lodash is loaded by a script tag in the presence
+ // of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
+ (freeWindow || freeSelf || {})._ = lodash;
+
+ // Some AMD build optimizers like r.js check for condition patterns like the following:
+ if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
+ // Define as an anonymous module so, through path mapping, it can be
+ // referenced as the "underscore" module.
+ define(function() {
+ return lodash;
+ });
+ }
+ // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
+ else if (freeExports && freeModule) {
+ // Export for Node.js.
+ if (moduleExports) {
+ (freeModule.exports = lodash)._ = lodash;
+ }
+ // Export for CommonJS support.
+ freeExports._ = lodash;
+ }
+ else {
+ // Export to the global object.
+ root._ = lodash;
+ }
+}.call(this));
diff --git a/countBy.js b/countBy.js
index c5ccdfde3..074544df0 100644
--- a/countBy.js
+++ b/countBy.js
@@ -16,7 +16,7 @@ var hasOwnProperty = objectProto.hasOwnProperty;
* @memberOf _
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
diff --git a/deburr.js b/deburr.js
index 79bd9f278..944735a87 100644
--- a/deburr.js
+++ b/deburr.js
@@ -5,12 +5,16 @@ var deburrLetter = require('./internal/deburrLetter'),
var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
/** Used to compose unicode character classes. */
-var rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23';
+var rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboSymbolsRange = '\\u20d0-\\u20f0';
/** Used to compose unicode capture groups. */
-var rsCombo = '[' + rsComboRange + ']';
+var rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']';
-/** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
+/**
+ * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
+ * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
+ */
var reComboMark = RegExp(rsCombo, 'g');
/**
diff --git a/extend.js b/extend.js
new file mode 100644
index 000000000..e00166c20
--- /dev/null
+++ b/extend.js
@@ -0,0 +1 @@
+module.exports = require('./assignIn');
diff --git a/extendWith.js b/extendWith.js
new file mode 100644
index 000000000..dbdcb3b4e
--- /dev/null
+++ b/extendWith.js
@@ -0,0 +1 @@
+module.exports = require('./assignInWith');
diff --git a/fp.js b/fp.js
index d3b61a6d3..d8887e0fe 100644
--- a/fp.js
+++ b/fp.js
@@ -1 +1,2 @@
-module.exports = require('./fp/convert.js')();
+var _ = require('./lodash').noConflict().runInContext();
+module.exports = require('./fp/convert')(_);
diff --git a/fp/baseConvert.js b/fp/_baseConvert.js
similarity index 76%
rename from fp/baseConvert.js
rename to fp/_baseConvert.js
index f43ee6240..10a7d70bc 100644
--- a/fp/baseConvert.js
+++ b/fp/_baseConvert.js
@@ -1,5 +1,6 @@
-var mapping = require('./mapping.js'),
- mutateMap = mapping.mutateMap;
+var mapping = require('./_mapping'),
+ mutateMap = mapping.mutate,
+ placeholder = {};
/**
* The base implementation of `convert` which accepts a `util` object of methods
@@ -39,21 +40,16 @@ function baseConvert(util, name, func) {
keys = _.keys,
rearg = _.rearg;
- var baseAry = function(func, n) {
- return function() {
- var args = arguments,
- length = Math.min(args.length, n);
+ var baseArity = function(func, n) {
+ return n == 2
+ ? function(a, b) { return func.apply(undefined, arguments); }
+ : function(a) { return func.apply(undefined, arguments); };
+ };
- switch (length) {
- case 1: return func(args[0]);
- case 2: return func(args[0], args[1]);
- }
- args = Array(length);
- while (length--) {
- args[length] = arguments[length];
- }
- return func.apply(undefined, args);
- };
+ var baseAry = function(func, n) {
+ return n == 2
+ ? function(a, b) { return func(a, b); }
+ : function(a) { return func(a); };
};
var cloneArray = function(array) {
@@ -82,6 +78,13 @@ function baseConvert(util, name, func) {
});
};
+ var iterateeRearg = function(func, indexes) {
+ return overArg(func, function(func) {
+ var n = indexes.length;
+ return baseArity(rearg(baseAry(func, n), indexes), n);
+ });
+ };
+
var overArg = function(func, iteratee, retArg) {
return function() {
var length = arguments.length,
@@ -98,7 +101,10 @@ function baseConvert(util, name, func) {
var wrappers = {
'iteratee': function(iteratee) {
- return function(func, arity) {
+ return function() {
+ var func = arguments[0],
+ arity = arguments[1];
+
arity = arity > 2 ? (arity - 2) : 1;
func = iteratee(func);
var length = func.length;
@@ -158,14 +164,18 @@ function baseConvert(util, name, func) {
}
var result;
each(mapping.caps, function(cap) {
- each(mapping.aryMethodMap[cap], function(otherName) {
+ each(mapping.aryMethod[cap], function(otherName) {
if (name == otherName) {
+ var indexes = mapping.iterateeRearg[name],
+ n = !isLib && mapping.aryIteratee[name];
+
result = ary(func, cap);
- if (cap > 1 && !mapping.skipReargMap[name]) {
- result = rearg(result, mapping.methodReargMap[name] || mapping.aryReargMap[cap]);
+ if (cap > 1 && !mapping.skipRearg[name]) {
+ result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[cap]);
}
- var n = !isLib && mapping.aryIterateeMap[name];
- if (n) {
+ if (indexes) {
+ result = iterateeRearg(result, indexes);
+ } else if (n) {
result = iterateeAry(result, n);
}
if (cap > 1) {
@@ -176,7 +186,12 @@ function baseConvert(util, name, func) {
});
return !result;
});
- return result || func;
+
+ result || (result = func);
+ if (mapping.placeholder[name]) {
+ result.placeholder = placeholder;
+ }
+ return result;
};
if (!isLib) {
@@ -185,8 +200,8 @@ function baseConvert(util, name, func) {
// Iterate over methods for the current ary cap.
var pairs = [];
each(mapping.caps, function(cap) {
- each(mapping.aryMethodMap[cap], function(key) {
- var func = _[mapping.keyMap[key] || key];
+ each(mapping.aryMethod[cap], function(key) {
+ var func = _[mapping.key[key] || key];
if (func) {
pairs.push([key, wrap(key, func)]);
}
@@ -200,7 +215,7 @@ function baseConvert(util, name, func) {
// Wrap the lodash method and its aliases.
each(keys(_), function(key) {
- each(mapping.aliasMap[key] || [], function(alias) {
+ each(mapping.alias[key] || [], function(alias) {
_[alias] = _[key];
});
});
diff --git a/fp/_convertBrowser.js b/fp/_convertBrowser.js
new file mode 100644
index 000000000..b076778a4
--- /dev/null
+++ b/fp/_convertBrowser.js
@@ -0,0 +1,13 @@
+var baseConvert = require('./_baseConvert');
+
+/**
+ * Converts `lodash` to an immutable auto-curried iteratee-first data-last version.
+ *
+ * @param {Function} lodash The lodash function.
+ * @returns {Function} Returns the converted `lodash`.
+ */
+function browserConvert(lodash) {
+ return baseConvert(lodash, lodash);
+}
+
+module.exports = browserConvert;
diff --git a/fp/_mapping.js b/fp/_mapping.js
new file mode 100644
index 000000000..4f1e607ee
--- /dev/null
+++ b/fp/_mapping.js
@@ -0,0 +1,202 @@
+module.exports = {
+
+ /** Used to map method names to their aliases. */
+ 'alias': {
+ 'ary': ['nAry'],
+ 'assignIn': ['extend'],
+ 'assignInWith': ['extendWith'],
+ 'filter': ['whereEq'],
+ 'flatten': ['unnest'],
+ 'flow': ['pipe'],
+ 'flowRight': ['compose'],
+ 'forEach': ['each'],
+ 'forEachRight': ['eachRight'],
+ 'get': ['path', 'prop'],
+ 'getOr': ['pathOr', 'propOr'],
+ 'head': ['first'],
+ 'includes': ['contains'],
+ 'initial': ['init'],
+ 'isEqual': ['equals'],
+ 'mapValues': ['mapObj'],
+ 'matchesProperty': ['pathEq'],
+ 'omit': ['dissoc', 'omitAll'],
+ 'overArgs': ['useWith'],
+ 'overEvery': ['allPass'],
+ 'overSome': ['somePass'],
+ 'pick': ['pickAll'],
+ 'propertyOf': ['propOf'],
+ 'rest': ['unapply'],
+ 'some': ['all'],
+ 'spread': ['apply'],
+ 'zipObject': ['zipObj']
+ },
+
+ /** Used to map method names to their iteratee ary. */
+ 'aryIteratee': {
+ 'assignWith': 2,
+ 'assignInWith': 2,
+ 'cloneDeepWith': 1,
+ 'cloneWith': 1,
+ 'dropRightWhile': 1,
+ 'dropWhile': 1,
+ 'every': 1,
+ 'filter': 1,
+ 'find': 1,
+ 'findIndex': 1,
+ 'findKey': 1,
+ 'findLast': 1,
+ 'findLastIndex': 1,
+ 'findLastKey': 1,
+ 'flatMap': 1,
+ 'forEach': 1,
+ 'forEachRight': 1,
+ 'forIn': 1,
+ 'forInRight': 1,
+ 'forOwn': 1,
+ 'forOwnRight': 1,
+ 'isEqualWith': 2,
+ 'isMatchWith': 2,
+ 'map': 1,
+ 'mapKeys': 1,
+ 'mapValues': 1,
+ 'partition': 1,
+ 'reduce': 2,
+ 'reduceRight': 2,
+ 'reject': 1,
+ 'remove': 1,
+ 'some': 1,
+ 'takeRightWhile': 1,
+ 'takeWhile': 1,
+ 'times': 1,
+ 'transform': 2
+ },
+
+ /** Used to map ary to method names. */
+ 'aryMethod': {
+ 1:[
+ 'attempt', 'ceil', 'create', 'curry', 'curryRight', 'floor', 'fromPairs',
+ 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', 'over',
+ 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext',
+ 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words'
+ ],
+ 2:[
+ 'add', 'after', 'ary', 'assign', 'at', 'before', 'bind', 'bindKey',
+ 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN',
+ 'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference',
+ 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq',
+ 'every', 'extend', 'filter', 'find', 'find', 'findIndex', 'findKey',
+ 'findLast', 'findLastIndex', 'findLastKey', 'flatMap', 'forEach',
+ 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'get',
+ 'groupBy', 'gt', 'gte', 'has', 'hasIn', 'includes', 'indexOf', 'intersection',
+ 'invoke', 'invokeMap', 'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf',
+ 'lt', 'lte', 'map', 'mapKeys', 'mapValues', 'matchesProperty', 'maxBy',
+ 'merge', 'minBy', 'omit', 'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd',
+ 'padStart', 'parseInt', 'partition', 'pick', 'pickBy', 'pull', 'pullAll',
+ 'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove',
+ 'repeat', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex',
+ 'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy',
+ 'split', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile',
+ 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'truncate', 'union', 'uniqBy',
+ 'uniqWith', 'unset', 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject'
+ ],
+ 3:[
+ 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith',
+ 'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith',
+ 'isMatchWith', 'mergeWith', 'pullAllBy', 'reduce', 'reduceRight', 'replace',
+ 'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy',
+ 'unionWith', 'xorBy', 'xorWith', 'zipWith'
+ ],
+ 4:[
+ 'fill', 'setWith'
+ ]
+ },
+
+ /** Used to map ary to rearg configs. */
+ 'aryRearg': {
+ 2: [1, 0],
+ 3: [2, 1, 0],
+ 4: [3, 2, 0, 1]
+ },
+
+ /** Used to map method names to iteratee rearg configs. */
+ 'iterateeRearg': {
+ 'findKey': [1],
+ 'findLastKey': [1],
+ 'mapKeys': [1]
+ },
+
+ /** Used to map method names to rearg configs. */
+ 'methodRearg': {
+ 'clamp': [2, 0, 1],
+ 'reduce': [2, 0, 1],
+ 'reduceRight': [2, 0, 1],
+ 'set': [2, 0, 1],
+ 'setWith': [3, 1, 2, 0],
+ 'slice': [2, 0, 1],
+ 'transform': [2, 0, 1]
+ },
+
+ /** Used to iterate `mapping.aryMethod` keys. */
+ 'caps': [1, 2, 3, 4],
+
+ /** Used to map keys to other keys. */
+ 'key': {
+ 'curryN': 'curry',
+ 'curryRightN': 'curryRight',
+ 'getOr': 'get'
+ },
+
+ /** Used to identify methods which mutate arrays or objects. */
+ 'mutate': {
+ 'array': {
+ 'fill': true,
+ 'pull': true,
+ 'pullAll': true,
+ 'pullAllBy': true,
+ 'pullAt': true,
+ 'remove': true,
+ 'reverse': true
+ },
+ 'object': {
+ 'assign': true,
+ 'assignIn': true,
+ 'assignInWith': true,
+ 'assignWith': true,
+ 'defaults': true,
+ 'defaultsDeep': true,
+ 'merge': true,
+ 'mergeWith': true
+ },
+ 'set': {
+ 'set': true,
+ 'setWith': true
+ }
+ },
+
+ /** Used to track methods with placeholder support */
+ 'placeholder': {
+ 'bind': true,
+ 'bindKey': true,
+ 'curry': true,
+ 'curryRight': true,
+ 'partial': true,
+ 'partialRight': true
+ },
+
+ /** Used to track methods that skip `_.rearg`. */
+ 'skipRearg': {
+ 'assign': true,
+ 'assignIn': true,
+ 'concat': true,
+ 'defaults': true,
+ 'defaultsDeep': true,
+ 'difference': true,
+ 'matchesProperty': true,
+ 'merge': true,
+ 'random': true,
+ 'range': true,
+ 'rangeRight': true,
+ 'zip': true,
+ 'zipObject': true
+ }
+};
diff --git a/fp/util.js b/fp/_util.js
similarity index 100%
rename from fp/util.js
rename to fp/_util.js
diff --git a/fp/convert.browser.js b/fp/convert.browser.js
deleted file mode 100644
index 6855f34f8..000000000
--- a/fp/convert.browser.js
+++ /dev/null
@@ -1,13 +0,0 @@
-var baseConvert = require('./baseConvert.js');
-
-/**
- * Converts `lodash` to an auto-curried iteratee-first data-last version.
- *
- * @param {Function} lodash The lodash function.
- * @returns {Function} Returns the converted lodash function.
- */
-function browserConvert(lodash) {
- return baseConvert(lodash, lodash);
-}
-
-module.exports = browserConvert;
diff --git a/fp/convert.js b/fp/convert.js
index 49aca2b7f..85f3b7535 100644
--- a/fp/convert.js
+++ b/fp/convert.js
@@ -1,20 +1,15 @@
-var _ = require('../lodash'),
- baseConvert = require('./baseConvert.js'),
- util = require('./util.js');
+var baseConvert = require('./_baseConvert'),
+ util = require('./_util');
/**
- * Converts `func` of `name` to an auto-curried iteratee-first data-last version.
- * If `name` is an object, the methods on it will be converted and the object returned.
+ * Converts `func` of `name` to an immutable auto-curried iteratee-first data-last
+ * version. If `name` is an object its methods will be converted.
*
- * @param {string} [name] The name of the function to wrap.
+ * @param {string} name The name of the function to wrap.
* @param {Function} [func] The function to wrap.
* @returns {Function|Object} Returns the converted function or object.
*/
-function convert() {
- var args = arguments,
- name = args.length ? args[0] : _.noConflict().runInContext(),
- func = args[1];
-
+function convert(name, func) {
return baseConvert(util, name, func);
}
diff --git a/fp/convert.node.js b/fp/convert.node.js
deleted file mode 100644
index ef26d5cbf..000000000
--- a/fp/convert.node.js
+++ /dev/null
@@ -1,16 +0,0 @@
-var baseConvert = require('./baseConvert.js'),
- util = require('./util.js');
-
-/**
- * Converts `func` of `name` to an auto-curried iteratee-first data-last version.
- * If `name` is an object, the methods on it will be converted and the object returned.
- *
- * @param {string} name The name of the function to wrap.
- * @param {Function} func The function to wrap.
- * @returns {Function|Object} Returns the converted function or object.
- */
-function nodeConvert(name, func) {
- return baseConvert(util, name, func);
-}
-
-module.exports = nodeConvert;
diff --git a/fp/mapping.js b/fp/mapping.js
deleted file mode 100644
index 4c76e4289..000000000
--- a/fp/mapping.js
+++ /dev/null
@@ -1,164 +0,0 @@
-module.exports = {
-
- /** Used to map method names to their aliases. */
- 'aliasMap': {
- 'ary': ['nAry'],
- 'overEvery': ['allPass'],
- 'overSome': ['somePass'],
- 'filter': ['whereEq'],
- 'flatten': ['unnest'],
- 'flow': ['pipe'],
- 'flowRight': ['compose'],
- 'forEach': ['each'],
- 'forEachRight': ['eachRight'],
- 'get': ['path'],
- 'getOr': ['pathOr'],
- 'head': ['first'],
- 'includes': ['contains'],
- 'initial': ['init'],
- 'isEqual': ['equals'],
- 'mapValues': ['mapObj'],
- 'matchesProperty': ['pathEq'],
- 'overArgs': ['useWith'],
- 'omit': ['dissoc', 'omitAll'],
- 'pick': ['pickAll'],
- 'property': ['prop'],
- 'propertyOf': ['propOf'],
- 'rest': ['unapply'],
- 'some': ['all'],
- 'spread': ['apply'],
- 'zipObject': ['zipObj']
- },
-
- /** Used to map method names to their iteratee ary. */
- 'aryIterateeMap': {
- 'assignWith': 2,
- 'cloneDeepWith': 1,
- 'cloneWith': 1,
- 'dropRightWhile': 1,
- 'dropWhile': 1,
- 'every': 1,
- 'extendWith': 2,
- 'filter': 1,
- 'find': 1,
- 'findIndex': 1,
- 'findKey': 1,
- 'findLast': 1,
- 'findLastIndex': 1,
- 'findLastKey': 1,
- 'flatMap': 1,
- 'forEach': 1,
- 'forEachRight': 1,
- 'forIn': 1,
- 'forInRight': 1,
- 'forOwn': 1,
- 'forOwnRight': 1,
- 'isEqualWith': 2,
- 'isMatchWith': 2,
- 'map': 1,
- 'mapKeys': 1,
- 'mapValues': 1,
- 'partition': 1,
- 'reduce': 2,
- 'reduceRight': 2,
- 'reject': 1,
- 'remove': 1,
- 'some': 1,
- 'takeRightWhile': 1,
- 'takeWhile': 1,
- 'times': 1,
- 'transform': 2
- },
-
- /** Used to map ary to method names. */
- 'aryMethodMap': {
- 1: (
- 'attempt,ceil,create,curry,curryRight,floor,fromPairs,iteratee,invert,over,' +
- 'overEvery,overSome,memoize,method,methodOf,mixin,rest,reverse,round,' +
- 'runInContext,template,trim,trimLeft,trimRight,uniqueId,words').split(','),
- 2: (
- 'add,ary,assign,at,bind,bindKey,cloneDeepWith,cloneWith,concat,countBy,curryN,' +
- 'curryRightN,debounce,defaults,defaultsDeep,delay,difference,drop,dropRight,' +
- 'dropRightWhile,dropWhile,endsWith,eq,every,extend,filter,find,find,findIndex,' +
- 'findKey,findLast,findLastIndex,findLastKey,flatMap,forEach,forEachRight,' +
- 'forIn,forInRight,forOwn,forOwnRight,get,groupBy,includes,indexBy,indexOf,' +
- 'intersection,invoke,invokeMap,isMatch,lastIndexOf,map,mapKeys,mapValues,' +
- 'matchesProperty,maxBy,mean,minBy,merge,omit,orderBy,overArgs,pad,padLeft,' +
- 'padRight,parseInt,partition,pick,pull,pullAll,pullAt,random,range,rangeRight,' +
- 'rearg,reject,remove,repeat,result,sampleSize,some,sortBy,sortedIndexBy,' +
- 'sortedLastIndexBy,sortedUniqBy,startsWith,subtract,sumBy,take,takeRight,' +
- 'takeRightWhile,takeWhile,throttle,times,truncate,union,uniqBy,without,wrap,' +
- 'xor,zip,zipObject').split(','),
- 3: (
- 'assignWith,clamp,differenceBy,extendWith,getOr,inRange,intersectionBy,' +
- 'isEqualWith,isMatchWith,mergeWith,omitBy,pickBy,pullAllBy,reduce,' +
- 'reduceRight,set,slice,transform,unionBy,xorBy,zipWith').split(','),
- 4:
- ['fill', 'setWith']
- },
-
- /** Used to map ary to rearg configs by method ary. */
- 'aryReargMap': {
- 2: [1, 0],
- 3: [2, 1, 0],
- 4: [3, 2, 0, 1]
- },
-
- /** Used to map ary to rearg configs by method names. */
- 'methodReargMap': {
- 'clamp': [2, 0, 1],
- 'reduce': [2, 0, 1],
- 'reduceRight': [2, 0, 1],
- 'setWith': [3, 2, 1, 0],
- 'slice': [2, 0, 1],
- 'transform': [2, 0, 1]
- },
-
- /** Used to iterate `mapping.aryMethodMap` keys. */
- 'caps': [1, 2, 3, 4],
-
- /** Used to map keys to other keys. */
- 'keyMap': {
- 'curryN': 'curry',
- 'curryRightN': 'curryRight',
- 'getOr': 'get'
- },
-
- /** Used to identify methods which mutate arrays or objects. */
- 'mutateMap': {
- 'array': {
- 'fill': true,
- 'pull': true,
- 'pullAll': true,
- 'pullAllBy': true,
- 'pullAt': true,
- 'remove': true,
- 'reverse': true
- },
- 'object': {
- 'assign': true,
- 'assignWith': true,
- 'defaults': true,
- 'defaultsDeep': true,
- 'extend': true,
- 'extendWith': true,
- 'merge': true,
- 'mergeWith': true
- },
- 'set': {
- 'set': true,
- 'setWith': true
- }
- },
-
- /** Used to track methods that skip `_.rearg`. */
- 'skipReargMap': {
- 'difference': true,
- 'matchesProperty': true,
- 'random': true,
- 'range': true,
- 'rangeRight': true,
- 'zip': true,
- 'zipObject': true
- }
-};
diff --git a/fromPairs.js b/fromPairs.js
index aa5c2803d..c18c1e386 100644
--- a/fromPairs.js
+++ b/fromPairs.js
@@ -1,5 +1,3 @@
-var baseSet = require('./internal/baseSet');
-
/**
* The inverse of `_.toPairs`; this method returns an object composed
* from key-value `pairs`.
@@ -21,7 +19,7 @@ function fromPairs(pairs) {
while (++index < length) {
var pair = pairs[index];
- baseSet(result, pair[0], pair[1]);
+ result[pair[0]] = pair[1];
}
return result;
}
diff --git a/groupBy.js b/groupBy.js
index 7950a0666..b8325ec93 100644
--- a/groupBy.js
+++ b/groupBy.js
@@ -9,14 +9,14 @@ var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Creates an object composed of keys generated from the results of running
* each element of `collection` through `iteratee`. The corresponding value
- * of each key is an array of the elements responsible for generating the key.
+ * of each key is an array of elements responsible for generating the key.
* The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
diff --git a/internal/Symbol.js b/internal/Symbol.js
new file mode 100644
index 000000000..9f903d2a8
--- /dev/null
+++ b/internal/Symbol.js
@@ -0,0 +1,4 @@
+/** Built-in value references. */
+var Symbol = global.Symbol;
+
+module.exports = Symbol;
diff --git a/internal/_Symbol.js b/internal/_Symbol.js
deleted file mode 100644
index dc481f51e..000000000
--- a/internal/_Symbol.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/** Built-in value references. */
-var _Symbol = global.Symbol;
-
-module.exports = _Symbol;
diff --git a/internal/arrayReduce.js b/internal/arrayReduce.js
index db95dc49a..6a355bce8 100644
--- a/internal/arrayReduce.js
+++ b/internal/arrayReduce.js
@@ -6,14 +6,14 @@
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {boolean} [initFromArray] Specify using the first element of `array` as the initial value.
+ * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
* @returns {*} Returns the accumulated value.
*/
-function arrayReduce(array, iteratee, accumulator, initFromArray) {
+function arrayReduce(array, iteratee, accumulator, initAccum) {
var index = -1,
length = array.length;
- if (initFromArray && length) {
+ if (initAccum && length) {
accumulator = array[++index];
}
while (++index < length) {
diff --git a/internal/arrayReduceRight.js b/internal/arrayReduceRight.js
index 5301e4a73..b33a2d086 100644
--- a/internal/arrayReduceRight.js
+++ b/internal/arrayReduceRight.js
@@ -6,12 +6,12 @@
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {boolean} [initFromArray] Specify using the last element of `array` as the initial value.
+ * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value.
* @returns {*} Returns the accumulated value.
*/
-function arrayReduceRight(array, iteratee, accumulator, initFromArray) {
+function arrayReduceRight(array, iteratee, accumulator, initAccum) {
var length = array.length;
- if (initFromArray && length) {
+ if (initAccum && length) {
accumulator = array[--length];
}
while (length--) {
diff --git a/internal/baseFind.js b/internal/baseFind.js
index f728c0f6f..535f7f353 100644
--- a/internal/baseFind.js
+++ b/internal/baseFind.js
@@ -1,7 +1,7 @@
/**
* The base implementation of methods like `_.find` and `_.findKey`, without
* support for iteratee shorthands, which iterates over `collection` using
- * the provided `eachFunc`.
+ * `eachFunc`.
*
* @private
* @param {Array|Object} collection The collection to search.
diff --git a/internal/baseInvoke.js b/internal/baseInvoke.js
index 2df5c09ad..e47ebbfa2 100644
--- a/internal/baseInvoke.js
+++ b/internal/baseInvoke.js
@@ -8,7 +8,6 @@ var apply = require('./apply'),
* The base implementation of `_.invoke` without support for individual
* method arguments.
*
- *
* @private
* @param {Object} object The object to query.
* @param {Array|string} path The path of the method to invoke.
diff --git a/internal/baseIsMatch.js b/internal/baseIsMatch.js
index f763df602..1f7a6045d 100644
--- a/internal/baseIsMatch.js
+++ b/internal/baseIsMatch.js
@@ -47,7 +47,10 @@ function baseIsMatch(object, source, matchData, customizer) {
var stack = new Stack,
result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
- if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) : result)) {
+ if (!(result === undefined
+ ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
+ : result
+ )) {
return false;
}
}
diff --git a/internal/baseMerge.js b/internal/baseMerge.js
index c0fcc060e..48d28314d 100644
--- a/internal/baseMerge.js
+++ b/internal/baseMerge.js
@@ -13,10 +13,11 @@ var Stack = require('./Stack'),
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
+ * @param {number} srcIndex The index of `source`.
* @param {Function} [customizer] The function to customize merged values.
* @param {Object} [stack] Tracks traversed source values and their merged counterparts.
*/
-function baseMerge(object, source, customizer, stack) {
+function baseMerge(object, source, srcIndex, customizer, stack) {
if (object === source) {
return;
}
@@ -28,7 +29,7 @@ function baseMerge(object, source, customizer, stack) {
}
if (isObject(srcValue)) {
stack || (stack = new Stack);
- baseMergeDeep(object, source, key, baseMerge, customizer, stack);
+ baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
}
else {
var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined;
diff --git a/internal/baseMergeDeep.js b/internal/baseMergeDeep.js
index b6c131f8f..c7f3c40c4 100644
--- a/internal/baseMergeDeep.js
+++ b/internal/baseMergeDeep.js
@@ -19,11 +19,12 @@ var assignMergeValue = require('./assignMergeValue'),
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @param {string} key The key of the value to merge.
+ * @param {number} srcIndex The index of `source`.
* @param {Function} mergeFunc The function to merge values.
* @param {Function} [customizer] The function to customize assigned values.
* @param {Object} [stack] Tracks traversed source values and their merged counterparts.
*/
-function baseMergeDeep(object, source, key, mergeFunc, customizer, stack) {
+function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
var objValue = object[key],
srcValue = source[key],
stacked = stack.get(srcValue) || stack.get(objValue);
@@ -38,24 +39,36 @@ function baseMergeDeep(object, source, key, mergeFunc, customizer, stack) {
if (isCommon) {
newValue = srcValue;
if (isArray(srcValue) || isTypedArray(srcValue)) {
- newValue = isArray(objValue)
- ? objValue
- : ((isArrayLikeObject(objValue)) ? copyArray(objValue) : baseClone(srcValue));
+ if (isArray(objValue)) {
+ newValue = srcIndex ? copyArray(objValue) : objValue;
+ }
+ else if (isArrayLikeObject(objValue)) {
+ newValue = copyArray(objValue);
+ }
+ else {
+ newValue = baseClone(srcValue);
+ }
}
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
- newValue = isArguments(objValue)
- ? toPlainObject(objValue)
- : (isObject(objValue) ? objValue : baseClone(srcValue));
+ if (isArguments(objValue)) {
+ newValue = toPlainObject(objValue);
+ }
+ else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
+ newValue = baseClone(srcValue);
+ }
+ else {
+ newValue = srcIndex ? baseClone(objValue) : objValue;
+ }
}
else {
- isCommon = isFunction(srcValue);
+ isCommon = false;
}
}
stack.set(srcValue, newValue);
if (isCommon) {
// Recursively merge objects and arrays (susceptible to call stack limits).
- mergeFunc(newValue, srcValue, customizer, stack);
+ mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
}
assignMergeValue(object, key, newValue);
}
diff --git a/internal/basePickBy.js b/internal/basePickBy.js
index 48e17757d..2d7dd2041 100644
--- a/internal/basePickBy.js
+++ b/internal/basePickBy.js
@@ -11,7 +11,7 @@ var baseForIn = require('./baseForIn');
function basePickBy(object, predicate) {
var result = {};
baseForIn(object, function(value, key) {
- if (predicate(value)) {
+ if (predicate(value, key)) {
result[key] = value;
}
});
diff --git a/internal/baseReduce.js b/internal/baseReduce.js
index 9ab844221..6ec544251 100644
--- a/internal/baseReduce.js
+++ b/internal/baseReduce.js
@@ -1,20 +1,19 @@
/**
* The base implementation of `_.reduce` and `_.reduceRight`, without support
- * for iteratee shorthands, which iterates over `collection` using the provided
- * `eachFunc`.
+ * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
*
* @private
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} accumulator The initial value.
- * @param {boolean} initFromCollection Specify using the first or last element of `collection` as the initial value.
+ * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value.
* @param {Function} eachFunc The function to iterate over `collection`.
* @returns {*} Returns the accumulated value.
*/
-function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) {
+function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
eachFunc(collection, function(value, index, collection) {
- accumulator = initFromCollection
- ? (initFromCollection = false, value)
+ accumulator = initAccum
+ ? (initAccum = false, value)
: iteratee(accumulator, value, index, collection);
});
return accumulator;
diff --git a/internal/cloneSymbol.js b/internal/cloneSymbol.js
index d5480ebcd..1310b3a51 100644
--- a/internal/cloneSymbol.js
+++ b/internal/cloneSymbol.js
@@ -1,8 +1,8 @@
-var _Symbol = require('./_Symbol');
+var Symbol = require('./Symbol');
/** Used to convert symbols to primitives and strings. */
-var symbolProto = _Symbol ? _Symbol.prototype : undefined,
- symbolValueOf = _Symbol ? symbolProto.valueOf : undefined;
+var symbolProto = Symbol ? Symbol.prototype : undefined,
+ symbolValueOf = Symbol ? symbolProto.valueOf : undefined;
/**
* Creates a clone of the `symbol` object.
@@ -12,7 +12,7 @@ var symbolProto = _Symbol ? _Symbol.prototype : undefined,
* @returns {Object} Returns the cloned symbol object.
*/
function cloneSymbol(symbol) {
- return _Symbol ? Object(symbolValueOf.call(symbol)) : {};
+ return Symbol ? Object(symbolValueOf.call(symbol)) : {};
}
module.exports = cloneSymbol;
diff --git a/internal/createAssigner.js b/internal/createAssigner.js
index c8dfd19f9..7dbbc0c64 100644
--- a/internal/createAssigner.js
+++ b/internal/createAssigner.js
@@ -24,7 +24,7 @@ function createAssigner(assigner) {
while (++index < length) {
var source = sources[index];
if (source) {
- assigner(object, source, customizer);
+ assigner(object, source, index, customizer);
}
}
return object;
diff --git a/internal/createCaseFirst.js b/internal/createCaseFirst.js
index 10b6c6ad0..2c29e0137 100644
--- a/internal/createCaseFirst.js
+++ b/internal/createCaseFirst.js
@@ -3,14 +3,15 @@ var stringToArray = require('./stringToArray'),
/** Used to compose unicode character classes. */
var rsAstralRange = '\\ud800-\\udfff',
- rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboSymbolsRange = '\\u20d0-\\u20f0',
rsVarRange = '\\ufe0e\\ufe0f';
/** Used to compose unicode capture groups. */
var rsZWJ = '\\u200d';
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
-var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
+var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
/**
* Creates a function like `_.lowerFirst`.
diff --git a/internal/createPadding.js b/internal/createPadding.js
index a1983f949..0e5a02526 100644
--- a/internal/createPadding.js
+++ b/internal/createPadding.js
@@ -5,14 +5,15 @@ var repeat = require('../repeat'),
/** Used to compose unicode character classes. */
var rsAstralRange = '\\ud800-\\udfff',
- rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboSymbolsRange = '\\u20d0-\\u20f0',
rsVarRange = '\\ufe0e\\ufe0f';
/** Used to compose unicode capture groups. */
var rsZWJ = '\\u200d';
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
-var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
+var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeCeil = Math.ceil;
diff --git a/internal/equalByTag.js b/internal/equalByTag.js
index 9a77d47c1..ba00fa3b3 100644
--- a/internal/equalByTag.js
+++ b/internal/equalByTag.js
@@ -1,5 +1,5 @@
-var Uint8Array = require('./Uint8Array'),
- _Symbol = require('./_Symbol'),
+var Symbol = require('./Symbol'),
+ Uint8Array = require('./Uint8Array'),
mapToArray = require('./mapToArray'),
setToArray = require('./setToArray');
@@ -21,8 +21,8 @@ var boolTag = '[object Boolean]',
var arrayBufferTag = '[object ArrayBuffer]';
/** Used to convert symbols to primitives and strings. */
-var symbolProto = _Symbol ? _Symbol.prototype : undefined,
- symbolValueOf = _Symbol ? symbolProto.valueOf : undefined;
+var symbolProto = Symbol ? Symbol.prototype : undefined,
+ symbolValueOf = Symbol ? symbolProto.valueOf : undefined;
/**
* A specialized version of `baseIsEqualDeep` for comparing objects of
@@ -80,7 +80,7 @@ function equalByTag(object, other, tag, equalFunc, customizer, bitmask) {
equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
case symbolTag:
- return !!_Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
+ return !!Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
}
return false;
}
diff --git a/internal/equalObjects.js b/internal/equalObjects.js
index 86966b1be..ad95a755e 100644
--- a/internal/equalObjects.js
+++ b/internal/equalObjects.js
@@ -2,8 +2,7 @@ var baseHas = require('./baseHas'),
keys = require('../keys');
/** Used to compose bitmasks for comparison styles. */
-var UNORDERED_COMPARE_FLAG = 1,
- PARTIAL_COMPARE_FLAG = 2;
+var PARTIAL_COMPARE_FLAG = 2;
/**
* A specialized version of `baseIsEqualDeep` for objects with support for
@@ -20,7 +19,6 @@ var UNORDERED_COMPARE_FLAG = 1,
*/
function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
- isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
@@ -32,8 +30,7 @@ function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
var index = objLength;
while (index--) {
var key = objProps[index];
- if (!(isPartial ? key in other : baseHas(other, key)) ||
- !(isUnordered || key == othProps[index])) {
+ if (!(isPartial ? key in other : baseHas(other, key))) {
return false;
}
}
diff --git a/internal/getFuncName.js b/internal/getFuncName.js
index ed92867d6..4a555ad13 100644
--- a/internal/getFuncName.js
+++ b/internal/getFuncName.js
@@ -1,5 +1,11 @@
var realNames = require('./realNames');
+/** Used for built-in method references. */
+var objectProto = global.Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
/**
* Gets the name of `func`.
*
@@ -10,7 +16,7 @@ var realNames = require('./realNames');
function getFuncName(func) {
var result = (func.name + ''),
array = realNames[result],
- length = array ? array.length : 0;
+ length = hasOwnProperty.call(realNames, result) ? array.length : 0;
while (length--) {
var data = array[length],
diff --git a/internal/mergeDefaults.js b/internal/mergeDefaults.js
index d17bd1bac..97ab718ec 100644
--- a/internal/mergeDefaults.js
+++ b/internal/mergeDefaults.js
@@ -1,5 +1,4 @@
-var baseClone = require('./baseClone'),
- baseMerge = require('./baseMerge'),
+var baseMerge = require('./baseMerge'),
isObject = require('../isObject');
/**
@@ -17,9 +16,9 @@ var baseClone = require('./baseClone'),
function mergeDefaults(objValue, srcValue, key, object, source, stack) {
if (isObject(objValue) && isObject(srcValue)) {
stack.set(srcValue, objValue);
- baseMerge(objValue, srcValue, mergeDefaults, stack);
+ baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
}
- return objValue === undefined ? baseClone(srcValue) : objValue;
+ return objValue;
}
module.exports = mergeDefaults;
diff --git a/internal/stringSize.js b/internal/stringSize.js
index a97dbcb7f..7aa9f4125 100644
--- a/internal/stringSize.js
+++ b/internal/stringSize.js
@@ -1,12 +1,14 @@
/** Used to compose unicode character classes. */
var rsAstralRange = '\\ud800-\\udfff',
- rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboSymbolsRange = '\\u20d0-\\u20f0',
rsVarRange = '\\ufe0e\\ufe0f';
/** Used to compose unicode capture groups. */
var rsAstral = '[' + rsAstralRange + ']',
- rsCombo = '[' + rsComboRange + ']',
- rsModifier = '(?:\\ud83c[\\udffb-\\udfff])',
+ rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
+ rsFitz = '\\ud83c[\\udffb-\\udfff]',
+ rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
rsNonAstral = '[^' + rsAstralRange + ']',
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
@@ -20,14 +22,15 @@ var reOptMod = rsModifier + '?',
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
-var reComplexSymbol = RegExp(rsSymbol + rsSeq, 'g');
+var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
-var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
+var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
/**
* Gets the number of symbols in `string`.
*
+ * @private
* @param {string} string The string to inspect.
* @returns {number} Returns the string size.
*/
diff --git a/internal/stringToArray.js b/internal/stringToArray.js
index 9176f35e0..90986f09b 100644
--- a/internal/stringToArray.js
+++ b/internal/stringToArray.js
@@ -1,12 +1,14 @@
/** Used to compose unicode character classes. */
var rsAstralRange = '\\ud800-\\udfff',
- rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboSymbolsRange = '\\u20d0-\\u20f0',
rsVarRange = '\\ufe0e\\ufe0f';
/** Used to compose unicode capture groups. */
var rsAstral = '[' + rsAstralRange + ']',
- rsCombo = '[' + rsComboRange + ']',
- rsModifier = '(?:\\ud83c[\\udffb-\\udfff])',
+ rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
+ rsFitz = '\\ud83c[\\udffb-\\udfff]',
+ rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
rsNonAstral = '[^' + rsAstralRange + ']',
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
@@ -20,7 +22,7 @@ var reOptMod = rsModifier + '?',
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
-var reComplexSymbol = RegExp(rsSymbol + rsSeq, 'g');
+var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
/**
* Converts `string` to an array.
diff --git a/intersection.js b/intersection.js
index 55bf7a0e0..6a33fcf41 100644
--- a/intersection.js
+++ b/intersection.js
@@ -14,6 +14,7 @@ var arrayMap = require('./internal/arrayMap'),
* @param {...Array} [arrays] The arrays to inspect.
* @returns {Array} Returns the new array of shared values.
* @example
+ *
* _.intersection([2, 1], [4, 2], [1, 2]);
* // => [2]
*/
diff --git a/isEqualWith.js b/isEqualWith.js
index 3f21b88e0..3262db9f6 100644
--- a/isEqualWith.js
+++ b/isEqualWith.js
@@ -3,7 +3,7 @@ var baseIsEqual = require('./internal/baseIsEqual');
/**
* This method is like `_.isEqual` except that it accepts `customizer` which is
* invoked to compare values. If `customizer` returns `undefined` comparisons are
- * handled by the method instead. The `customizer` is invoked with up to seven arguments:
+ * handled by the method instead. The `customizer` is invoked with up to six arguments:
* (objValue, othValue [, index|key, object, other, stack]).
*
* @static
diff --git a/isMatchWith.js b/isMatchWith.js
index d3deea50a..7b1345ae7 100644
--- a/isMatchWith.js
+++ b/isMatchWith.js
@@ -4,7 +4,7 @@ var baseIsMatch = require('./internal/baseIsMatch'),
/**
* This method is like `_.isMatch` except that it accepts `customizer` which
* is invoked to compare values. If `customizer` returns `undefined` comparisons
- * are handled by the method instead. The `customizer` is invoked with three
+ * are handled by the method instead. The `customizer` is invoked with five
* arguments: (objValue, srcValue, index|key, object, source).
*
* @static
diff --git a/keyBy.js b/keyBy.js
index e71bc97db..8a4bac5b3 100644
--- a/keyBy.js
+++ b/keyBy.js
@@ -10,7 +10,7 @@ var createAggregator = require('./internal/createAggregator');
* @memberOf _
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
@@ -19,13 +19,13 @@ var createAggregator = require('./internal/createAggregator');
* { 'dir': 'right', 'code': 100 }
* ];
*
- * _.keyBy(keyData, 'dir');
- * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
- *
* _.keyBy(keyData, function(o) {
* return String.fromCharCode(o.code);
* });
* // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+ *
+ * _.keyBy(keyData, 'dir');
+ * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
*/
var keyBy = createAggregator(function(result, value, key) {
result[key] = value;
diff --git a/lodash.js b/lodash.js
index e20df3884..95aef7960 100644
--- a/lodash.js
+++ b/lodash.js
@@ -1,6 +1,6 @@
/**
* @license
- * lodash 4.0.0 (Custom Build)
+ * lodash 4.0.1 (Custom Build)
* Build: `lodash -d -o ./lodash.js`
* Copyright 2012-2016 The Dojo Foundation
* Based on Underscore.js 1.8.3
@@ -13,7 +13,7 @@
var undefined;
/** Used as the semantic version number. */
- var VERSION = '4.0.0';
+ var VERSION = '4.0.1';
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
@@ -163,7 +163,8 @@
/** Used to compose unicode character classes. */
var rsAstralRange = '\\ud800-\\udfff',
- rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboSymbolsRange = '\\u20d0-\\u20f0',
rsDingbatRange = '\\u2700-\\u27bf',
rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
@@ -177,12 +178,13 @@
/** Used to compose unicode capture groups. */
var rsAstral = '[' + rsAstralRange + ']',
rsBreak = '[' + rsBreakRange + ']',
- rsCombo = '[' + rsComboRange + ']',
+ rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
rsDigits = '\\d+',
rsDingbat = '[' + rsDingbatRange + ']',
rsLower = '[' + rsLowerRange + ']',
rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
- rsModifier = '(?:\\ud83c[\\udffb-\\udfff])',
+ rsFitz = '\\ud83c[\\udffb-\\udfff]',
+ rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
rsNonAstral = '[^' + rsAstralRange + ']',
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
@@ -199,14 +201,17 @@
rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
- /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */
+ /**
+ * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
+ * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
+ */
var reComboMark = RegExp(rsCombo, 'g');
/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
- var reComplexSymbol = RegExp(rsSymbol + rsSeq, 'g');
+ var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
- var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
+ var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
/** Used to match non-compound words composed of alphanumeric characters. */
var reBasicWord = /[a-zA-Z0-9]+/g;
@@ -216,7 +221,8 @@
rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
rsUpper + '?' + rsLowerMisc + '+',
- rsDigits + '(?:' + rsLowerMisc + '+)?',
+ rsUpper + '+',
+ rsDigits,
rsEmoji
].join('|'), 'g');
@@ -597,14 +603,14 @@
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {boolean} [initFromArray] Specify using the first element of `array` as the initial value.
+ * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
* @returns {*} Returns the accumulated value.
*/
- function arrayReduce(array, iteratee, accumulator, initFromArray) {
+ function arrayReduce(array, iteratee, accumulator, initAccum) {
var index = -1,
length = array.length;
- if (initFromArray && length) {
+ if (initAccum && length) {
accumulator = array[++index];
}
while (++index < length) {
@@ -621,12 +627,12 @@
* @param {Array} array The array to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} [accumulator] The initial value.
- * @param {boolean} [initFromArray] Specify using the last element of `array` as the initial value.
+ * @param {boolean} [initAccum] Specify using the last element of `array` as the initial value.
* @returns {*} Returns the accumulated value.
*/
- function arrayReduceRight(array, iteratee, accumulator, initFromArray) {
+ function arrayReduceRight(array, iteratee, accumulator, initAccum) {
var length = array.length;
- if (initFromArray && length) {
+ if (initAccum && length) {
accumulator = array[--length];
}
while (length--) {
@@ -688,7 +694,7 @@
/**
* The base implementation of methods like `_.find` and `_.findKey`, without
* support for iteratee shorthands, which iterates over `collection` using
- * the provided `eachFunc`.
+ * `eachFunc`.
*
* @private
* @param {Array|Object} collection The collection to search.
@@ -756,21 +762,20 @@
/**
* The base implementation of `_.reduce` and `_.reduceRight`, without support
- * for iteratee shorthands, which iterates over `collection` using the provided
- * `eachFunc`.
+ * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
*
* @private
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} iteratee The function invoked per iteration.
* @param {*} accumulator The initial value.
- * @param {boolean} initFromCollection Specify using the first or last element of `collection` as the initial value.
+ * @param {boolean} initAccum Specify using the first or last element of `collection` as the initial value.
* @param {Function} eachFunc The function to iterate over `collection`.
* @returns {*} Returns the accumulated value.
*/
- function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) {
+ function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
eachFunc(collection, function(value, index, collection) {
- accumulator = initFromCollection
- ? (initFromCollection = false, value)
+ accumulator = initAccum
+ ? (initAccum = false, value)
: iteratee(accumulator, value, index, collection);
});
return accumulator;
@@ -1164,6 +1169,7 @@
/**
* Gets the number of symbols in `string`.
*
+ * @private
* @param {string} string The string to inspect.
* @returns {number} Returns the string size.
*/
@@ -1279,14 +1285,14 @@
);
/** Built-in value references. */
- var _Symbol = context.Symbol,
- Reflect = context.Reflect,
+ var Reflect = context.Reflect,
+ Symbol = context.Symbol,
Uint8Array = context.Uint8Array,
clearTimeout = context.clearTimeout,
enumerate = Reflect ? Reflect.enumerate : undefined,
getPrototypeOf = Object.getPrototypeOf,
getOwnPropertySymbols = Object.getOwnPropertySymbols,
- iteratorSymbol = typeof (iteratorSymbol = _Symbol && _Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
+ iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
propertyIsEnumerable = objectProto.propertyIsEnumerable,
setTimeout = context.setTimeout,
splice = arrayProto.splice;
@@ -1317,9 +1323,9 @@
setCtorString = Set ? funcToString.call(Set) : '';
/** Used to convert symbols to primitives and strings. */
- var symbolProto = _Symbol ? _Symbol.prototype : undefined,
- symbolValueOf = _Symbol ? symbolProto.valueOf : undefined,
- symbolToString = _Symbol ? symbolProto.toString : undefined;
+ var symbolProto = Symbol ? Symbol.prototype : undefined,
+ symbolValueOf = Symbol ? symbolProto.valueOf : undefined,
+ symbolToString = Symbol ? symbolProto.toString : undefined;
/** Used to lookup unminified function names. */
var realNames = {};
@@ -1367,13 +1373,12 @@
* The chainable wrapper methods are:
* `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`,
* `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`,
- * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
+ * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
* `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
- * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
+ * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
* `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
- * `flowRight`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
- * `forOwnRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
- * `intersection`, `intersectionBy`, `intersectionWith`, invert`, `invokeMap`,
+ * `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
+ * `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invokeMap`,
* `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`,
* `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`,
* `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`,
@@ -1392,22 +1397,23 @@
* `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
* `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
* `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
- * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `get`, `gt`, `gte`,
- * `has`, `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`,
- * `invoke`, `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`,
- * `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`,
- * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`,
- * `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`,
- * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`,
- * `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, `last`,
- * `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`,
- * `mean`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, `padEnd`,
- * `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`,
- * `result`, `round`, `runInContext`, `sample`, `shift`, `size`, `snakeCase`,
- * `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`,
- * `startCase`, `startsWith`, `subtract`, `sum`, sumBy`, `template`, `times`,
- * `toLower`, `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, toString`,
- * `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
+ * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`,
+ * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
+ * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
+ * `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`,
+ * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`,
+ * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`, `isMatchWith`,
+ * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`,
+ * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isString`, `isUndefined`,
+ * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`,
+ * `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`,
+ * `noConflict`, `noop`, `now`, `pad`, `padEnd`, `padStart`, `parseInt`,
+ * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`,
+ * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
+ * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`,
+ * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toLower`,
+ * `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`,
+ * `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
* `upperCase`, `upperFirst`, `value`, and `words`
*
* @name _
@@ -2667,7 +2673,6 @@
* The base implementation of `_.invoke` without support for individual
* method arguments.
*
- *
* @private
* @param {Object} object The object to query.
* @param {Array|string} path The path of the method to invoke.
@@ -2810,7 +2815,10 @@
var stack = new Stack,
result = customizer ? customizer(objValue, srcValue, key, object, source, stack) : undefined;
- if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) : result)) {
+ if (!(result === undefined
+ ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
+ : result
+ )) {
return false;
}
}
@@ -2946,10 +2954,11 @@
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
+ * @param {number} srcIndex The index of `source`.
* @param {Function} [customizer] The function to customize merged values.
* @param {Object} [stack] Tracks traversed source values and their merged counterparts.
*/
- function baseMerge(object, source, customizer, stack) {
+ function baseMerge(object, source, srcIndex, customizer, stack) {
if (object === source) {
return;
}
@@ -2961,7 +2970,7 @@
}
if (isObject(srcValue)) {
stack || (stack = new Stack);
- baseMergeDeep(object, source, key, baseMerge, customizer, stack);
+ baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
}
else {
var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined;
@@ -2982,11 +2991,12 @@
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @param {string} key The key of the value to merge.
+ * @param {number} srcIndex The index of `source`.
* @param {Function} mergeFunc The function to merge values.
* @param {Function} [customizer] The function to customize assigned values.
* @param {Object} [stack] Tracks traversed source values and their merged counterparts.
*/
- function baseMergeDeep(object, source, key, mergeFunc, customizer, stack) {
+ function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
var objValue = object[key],
srcValue = source[key],
stacked = stack.get(srcValue) || stack.get(objValue);
@@ -3001,24 +3011,36 @@
if (isCommon) {
newValue = srcValue;
if (isArray(srcValue) || isTypedArray(srcValue)) {
- newValue = isArray(objValue)
- ? objValue
- : ((isArrayLikeObject(objValue)) ? copyArray(objValue) : baseClone(srcValue));
+ if (isArray(objValue)) {
+ newValue = srcIndex ? copyArray(objValue) : objValue;
+ }
+ else if (isArrayLikeObject(objValue)) {
+ newValue = copyArray(objValue);
+ }
+ else {
+ newValue = baseClone(srcValue);
+ }
}
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
- newValue = isArguments(objValue)
- ? toPlainObject(objValue)
- : (isObject(objValue) ? objValue : baseClone(srcValue));
+ if (isArguments(objValue)) {
+ newValue = toPlainObject(objValue);
+ }
+ else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
+ newValue = baseClone(srcValue);
+ }
+ else {
+ newValue = srcIndex ? baseClone(objValue) : objValue;
+ }
}
else {
- isCommon = isFunction(srcValue);
+ isCommon = false;
}
}
stack.set(srcValue, newValue);
if (isCommon) {
// Recursively merge objects and arrays (susceptible to call stack limits).
- mergeFunc(newValue, srcValue, customizer, stack);
+ mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
}
assignMergeValue(object, key, newValue);
}
@@ -3082,7 +3104,7 @@
function basePickBy(object, predicate) {
var result = {};
baseForIn(object, function(value, key) {
- if (predicate(value)) {
+ if (predicate(value, key)) {
result[key] = value;
}
});
@@ -3667,7 +3689,7 @@
* @returns {Object} Returns the cloned symbol object.
*/
function cloneSymbol(symbol) {
- return _Symbol ? Object(symbolValueOf.call(symbol)) : {};
+ return Symbol ? Object(symbolValueOf.call(symbol)) : {};
}
/**
@@ -3870,7 +3892,7 @@
while (++index < length) {
var source = sources[index];
if (source) {
- assigner(object, source, customizer);
+ assigner(object, source, index, customizer);
}
}
return object;
@@ -4555,7 +4577,7 @@
equalFunc(convert(object), convert(other), customizer, bitmask | UNORDERED_COMPARE_FLAG);
case symbolTag:
- return !!_Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
+ return !!Symbol && (symbolValueOf.call(object) == symbolValueOf.call(other));
}
return false;
}
@@ -4575,7 +4597,6 @@
*/
function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
- isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
objProps = keys(object),
objLength = objProps.length,
othProps = keys(other),
@@ -4587,8 +4608,7 @@
var index = objLength;
while (index--) {
var key = objProps[index];
- if (!(isPartial ? key in other : baseHas(other, key)) ||
- !(isUnordered || key == othProps[index])) {
+ if (!(isPartial ? key in other : baseHas(other, key))) {
return false;
}
}
@@ -4658,7 +4678,7 @@
function getFuncName(func) {
var result = (func.name + ''),
array = realNames[result],
- length = array ? array.length : 0;
+ length = hasOwnProperty.call(realNames, result) ? array.length : 0;
while (length--) {
var data = array[length],
@@ -5099,9 +5119,9 @@
function mergeDefaults(objValue, srcValue, key, object, source, stack) {
if (isObject(objValue) && isObject(srcValue)) {
stack.set(srcValue, objValue);
- baseMerge(objValue, srcValue, mergeDefaults, stack);
+ baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
}
- return objValue === undefined ? baseClone(srcValue) : objValue;
+ return objValue;
}
/**
@@ -5315,8 +5335,11 @@
* // => [1]
*/
var concat = rest(function(array, values) {
+ if (!isArray(array)) {
+ array = array == null ? [] : [Object(array)];
+ }
values = baseFlatten(values);
- return arrayConcat(isArray(array) ? array : [Object(array)], values);
+ return arrayConcat(array, values);
});
/**
@@ -5748,7 +5771,7 @@
while (++index < length) {
var pair = pairs[index];
- baseSet(result, pair[0], pair[1]);
+ result[pair[0]] = pair[1];
}
return result;
}
@@ -5837,6 +5860,7 @@
* @param {...Array} [arrays] The arrays to inspect.
* @returns {Array} Returns the new array of shared values.
* @example
+ *
* _.intersection([2, 1], [4, 2], [1, 2]);
* // => [2]
*/
@@ -6029,7 +6053,7 @@
*
* var array = [1, 2, 3, 1, 2, 3];
*
- * _.pull(array, [2, 3]);
+ * _.pullAll(array, [2, 3]);
* console.log(array);
* // => [1, 1]
*/
@@ -6153,6 +6177,7 @@
* **Note:** This method mutates `array` and is based on
* [`Array#reverse`](https://mdn.io/Array/reverse).
*
+ * @static
* @memberOf _
* @category Array
* @returns {Array} Returns `array`.
@@ -7111,7 +7136,7 @@
/**
* This method is the wrapper version of `_.flatMap`.
*
- * @static
+ * @name flatMap
* @memberOf _
* @category Seq
* @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
@@ -7262,7 +7287,7 @@
*
* @name value
* @memberOf _
- * @alias run, toJSON, valueOf
+ * @alias toJSON, valueOf
* @category Seq
* @returns {*} Returns the resolved unwrapped value.
* @example
@@ -7286,7 +7311,7 @@
* @memberOf _
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
@@ -7510,14 +7535,14 @@
/**
* Creates an object composed of keys generated from the results of running
* each element of `collection` through `iteratee`. The corresponding value
- * of each key is an array of the elements responsible for generating the key.
+ * of each key is an array of elements responsible for generating the key.
* The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
@@ -7622,7 +7647,7 @@
* @memberOf _
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
- * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
+ * @param {Function|Object|string} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
@@ -7631,13 +7656,13 @@
* { 'dir': 'right', 'code': 100 }
* ];
*
- * _.keyBy(keyData, 'dir');
- * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
- *
* _.keyBy(keyData, function(o) {
* return String.fromCharCode(o.code);
* });
* // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
+ *
+ * _.keyBy(keyData, 'dir');
+ * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
*/
var keyBy = createAggregator(function(result, value, key) {
result[key] = value;
@@ -7669,11 +7694,11 @@
* return n * n;
* }
*
- * _.map([1, 2], square);
- * // => [3, 6]
+ * _.map([4, 8], square);
+ * // => [16, 64]
*
- * _.map({ 'a': 1, 'b': 2 }, square);
- * // => [3, 6] (iteration order is not guaranteed)
+ * _.map({ 'a': 4, 'b': 8 }, square);
+ * // => [16, 64] (iteration order is not guaranteed)
*
* var users = [
* { 'user': 'barney' },
@@ -7732,9 +7757,9 @@
/**
* Creates an array of elements split into two groups, the first of which
- * contains elements `predicate` returns truthy for, while the second of which
- * contains elements `predicate` returns falsey for. The predicate is invoked
- * with three arguments: (value, index|key, collection).
+ * contains elements `predicate` returns truthy for, the second of which
+ * contains elements `predicate` returns falsey for. The predicate is
+ * invoked with one argument: (value).
*
* @static
* @memberOf _
@@ -7806,9 +7831,9 @@
*/
function reduce(collection, iteratee, accumulator) {
var func = isArray(collection) ? arrayReduce : baseReduce,
- initFromCollection = arguments.length < 3;
+ initAccum = arguments.length < 3;
- return func(collection, getIteratee(iteratee, 4), accumulator, initFromCollection, baseEach);
+ return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
}
/**
@@ -7833,9 +7858,9 @@
*/
function reduceRight(collection, iteratee, accumulator) {
var func = isArray(collection) ? arrayReduceRight : baseReduce,
- initFromCollection = arguments.length < 3;
+ initAccum = arguments.length < 3;
- return func(collection, getIteratee(iteratee, 4), accumulator, initFromCollection, baseEachRight);
+ return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
}
/**
@@ -7899,7 +7924,8 @@
}
/**
- * Gets `n` random elements from `collection`.
+ * Gets `n` random elements at unique keys from `collection` up to the
+ * size of `collection`.
*
* @static
* @memberOf _
@@ -7909,8 +7935,11 @@
* @returns {Array} Returns the random elements.
* @example
*
- * _.sampleSize([1, 2, 3, 4], 2);
+ * _.sampleSize([1, 2, 3], 2);
* // => [3, 1]
+ *
+ * _.sampleSize([1, 2, 3], 4);
+ * // => [2, 3, 1]
*/
function sampleSize(collection, n) {
var index = -1,
@@ -9074,7 +9103,7 @@
* This method is like `_.clone` except that it accepts `customizer` which
* is invoked to produce the cloned value. If `customizer` returns `undefined`
* cloning is handled by the method instead. The `customizer` is invoked with
- * up to five arguments; (value [, index|key, object, stack]).
+ * up to four arguments; (value [, index|key, object, stack]).
*
* @static
* @memberOf _
@@ -9090,7 +9119,7 @@
* }
* }
*
- * var el = _.clone(document.body, customizer);
+ * var el = _.cloneWith(document.body, customizer);
*
* console.log(el === document.body);
* // => false
@@ -9140,7 +9169,7 @@
* }
* }
*
- * var el = _.cloneDeep(document.body, customizer);
+ * var el = _.cloneDeepWith(document.body, customizer);
*
* console.log(el === document.body);
* // => false
@@ -9468,7 +9497,7 @@
/**
* This method is like `_.isEqual` except that it accepts `customizer` which is
* invoked to compare values. If `customizer` returns `undefined` comparisons are
- * handled by the method instead. The `customizer` is invoked with up to seven arguments:
+ * handled by the method instead. The `customizer` is invoked with up to six arguments:
* (objValue, othValue [, index|key, object, other, stack]).
*
* @static
@@ -9718,7 +9747,7 @@
/**
* This method is like `_.isMatch` except that it accepts `customizer` which
* is invoked to compare values. If `customizer` returns `undefined` comparisons
- * are handled by the method instead. The `customizer` is invoked with three
+ * are handled by the method instead. The `customizer` is invoked with five
* arguments: (objValue, srcValue, index|key, object, source).
*
* @static
@@ -10189,7 +10218,7 @@
* @memberOf _
* @category Lang
* @param {*} value The value to convert.
- * @return {number} Returns the converted integer.
+ * @returns {number} Returns the converted integer.
* @example
*
* _.toLength(3);
@@ -10328,7 +10357,7 @@
return '';
}
if (isSymbol(value)) {
- return _Symbol ? symbolToString.call(value) : '';
+ return Symbol ? symbolToString.call(value) : '';
}
var result = (value + '');
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
@@ -10430,7 +10459,7 @@
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
* // => { 'a': 1, 'b': 2 }
*/
- var assignInWith = createAssigner(function(object, source, customizer) {
+ var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
copyObjectWith(source, keysIn(source), object, customizer);
});
@@ -10460,7 +10489,7 @@
* defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
* // => { 'a': 1, 'b': 2 }
*/
- var assignWith = createAssigner(function(object, source, customizer) {
+ var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
copyObjectWith(source, keys(source), object, customizer);
});
@@ -11140,8 +11169,8 @@
* _.merge(users, ages);
* // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
*/
- var merge = createAssigner(function(object, source) {
- baseMerge(object, source);
+ var merge = createAssigner(function(object, source, srcIndex) {
+ baseMerge(object, source, srcIndex);
});
/**
@@ -11179,8 +11208,8 @@
* _.mergeWith(object, other, customizer);
* // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
*/
- var mergeWith = createAssigner(function(object, source, customizer) {
- baseMerge(object, source, customizer);
+ var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
+ baseMerge(object, source, srcIndex, customizer);
});
/**
@@ -11228,9 +11257,9 @@
* // => { 'b': '2' }
*/
function omitBy(object, predicate) {
- predicate = getIteratee(predicate);
- return basePickBy(object, function(value) {
- return !predicate(value);
+ predicate = getIteratee(predicate, 2);
+ return basePickBy(object, function(value, key) {
+ return !predicate(value, key);
});
}
@@ -11273,7 +11302,7 @@
* // => { 'a': 1, 'c': 3 }
*/
function pickBy(object, predicate) {
- return object == null ? {} : basePickBy(object, getIteratee(predicate));
+ return object == null ? {} : basePickBy(object, getIteratee(predicate, 2));
}
/**
@@ -12040,7 +12069,7 @@
* `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
* in which case a `radix` of `16` is used.
*
- * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E)
+ * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2)
* of `parseInt`.
*
* @static
@@ -12832,7 +12861,7 @@
* [_.matches({ 'a': 1 }), _.constant('matches A')],
* [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
* [_.constant(true), _.constant('no match')]
- * ])
+ * ]);
*
* func({ 'a': 1, 'b': 2 });
* // => 'matches A'
@@ -13203,7 +13232,9 @@
* var lodash = _.noConflict();
*/
function noConflict() {
- root._ = oldDash;
+ if (root._ === this) {
+ root._ = oldDash;
+ }
return this;
}
@@ -13368,8 +13399,7 @@
* Creates an array of numbers (positive and/or negative) progressing from
* `start` up to, but not including, `end`. A step of `-1` is used if a negative
* `start` is specified without an `end` or `step`. If `end` is not specified
- * it's set to `start` with `start` then set to `0`. If `end` is less than
- * `start` a zero-length range is created unless a negative `step` is specified.
+ * it's set to `start` with `start` then set to `0`.
*
* **Note:** JavaScript follows the IEEE-754 standard for resolving
* floating-point values which can produce unexpected results.
@@ -13637,7 +13667,7 @@
*
* var objects = [{ 'n': 1 }, { 'n': 2 }];
*
- * _.maxBy(objects, function(o) { return o.a; });
+ * _.maxBy(objects, function(o) { return o.n; });
* // => { 'n': 2 }
*
* // using the `_.property` iteratee shorthand
@@ -13705,7 +13735,7 @@
*
* var objects = [{ 'n': 1 }, { 'n': 2 }];
*
- * _.minBy(objects, function(o) { return o.a; });
+ * _.minBy(objects, function(o) { return o.n; });
* // => { 'n': 1 }
*
* // using the `_.property` iteratee shorthand
@@ -13989,8 +14019,6 @@
lodash.zipWith = zipWith;
// Add aliases.
- lodash.each = forEach;
- lodash.eachRight = forEachRight;
lodash.extend = assignIn;
lodash.extendWith = assignInWith;
@@ -14133,6 +14161,8 @@
lodash.upperFirst = upperFirst;
// Add aliases.
+ lodash.each = forEach;
+ lodash.eachRight = forEachRight;
lodash.first = head;
mixin(lodash, (function() {
diff --git a/map.js b/map.js
index 0f8ce833b..31da57788 100644
--- a/map.js
+++ b/map.js
@@ -29,11 +29,11 @@ var arrayMap = require('./internal/arrayMap'),
* return n * n;
* }
*
- * _.map([1, 2], square);
- * // => [3, 6]
+ * _.map([4, 8], square);
+ * // => [16, 64]
*
- * _.map({ 'a': 1, 'b': 2 }, square);
- * // => [3, 6] (iteration order is not guaranteed)
+ * _.map({ 'a': 4, 'b': 8 }, square);
+ * // => [16, 64] (iteration order is not guaranteed)
*
* var users = [
* { 'user': 'barney' },
diff --git a/maxBy.js b/maxBy.js
index 5a7200bd9..b5170ef30 100644
--- a/maxBy.js
+++ b/maxBy.js
@@ -17,7 +17,7 @@ var baseExtremum = require('./internal/baseExtremum'),
*
* var objects = [{ 'n': 1 }, { 'n': 2 }];
*
- * _.maxBy(objects, function(o) { return o.a; });
+ * _.maxBy(objects, function(o) { return o.n; });
* // => { 'n': 2 }
*
* // using the `_.property` iteratee shorthand
diff --git a/merge.js b/merge.js
index dd90d6939..d22d9daeb 100644
--- a/merge.js
+++ b/merge.js
@@ -30,8 +30,8 @@ var baseMerge = require('./internal/baseMerge'),
* _.merge(users, ages);
* // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
*/
-var merge = createAssigner(function(object, source) {
- baseMerge(object, source);
+var merge = createAssigner(function(object, source, srcIndex) {
+ baseMerge(object, source, srcIndex);
});
module.exports = merge;
diff --git a/mergeWith.js b/mergeWith.js
index dde4198c2..2555741c6 100644
--- a/mergeWith.js
+++ b/mergeWith.js
@@ -36,8 +36,8 @@ var baseMerge = require('./internal/baseMerge'),
* _.mergeWith(object, other, customizer);
* // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
*/
-var mergeWith = createAssigner(function(object, source, customizer) {
- baseMerge(object, source, customizer);
+var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
+ baseMerge(object, source, srcIndex, customizer);
});
module.exports = mergeWith;
diff --git a/minBy.js b/minBy.js
index 187fd763c..cb90acec5 100644
--- a/minBy.js
+++ b/minBy.js
@@ -17,7 +17,7 @@ var baseExtremum = require('./internal/baseExtremum'),
*
* var objects = [{ 'n': 1 }, { 'n': 2 }];
*
- * _.minBy(objects, function(o) { return o.a; });
+ * _.minBy(objects, function(o) { return o.n; });
* // => { 'n': 1 }
*
* // using the `_.property` iteratee shorthand
diff --git a/object.js b/object.js
index df85280c9..6bd7cf071 100644
--- a/object.js
+++ b/object.js
@@ -6,6 +6,8 @@ module.exports = {
'create': require('./create'),
'defaults': require('./defaults'),
'defaultsDeep': require('./defaultsDeep'),
+ 'extend': require('./extend'),
+ 'extendWith': require('./extendWith'),
'findKey': require('./findKey'),
'findLastKey': require('./findLastKey'),
'forIn': require('./forIn'),
diff --git a/omitBy.js b/omitBy.js
index 1a51e6fe4..1230d0149 100644
--- a/omitBy.js
+++ b/omitBy.js
@@ -20,9 +20,9 @@ var baseIteratee = require('./internal/baseIteratee'),
* // => { 'b': '2' }
*/
function omitBy(object, predicate) {
- predicate = baseIteratee(predicate);
- return basePickBy(object, function(value) {
- return !predicate(value);
+ predicate = baseIteratee(predicate, 2);
+ return basePickBy(object, function(value, key) {
+ return !predicate(value, key);
});
}
diff --git a/package.json b/package.json
index 36b3981bb..24f2c988a 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,11 @@
{
"name": "lodash",
- "version": "4.0.0",
+ "version": "4.0.1",
"description": "Lodash modular utilities.",
"homepage": "https://lodash.com/",
"icon": "https://lodash.com/icon.svg",
"license": "MIT",
- "main": "index.js",
+ "main": "lodash.js",
"keywords": "modules, stdlib, util",
"author": "John-David Dalton (http://allyoucanleet.com/)",
"contributors": [
diff --git a/parseInt.js b/parseInt.js
index cf45faa2d..789aa0131 100644
--- a/parseInt.js
+++ b/parseInt.js
@@ -14,7 +14,7 @@ var nativeParseInt = global.parseInt;
* `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal,
* in which case a `radix` of `16` is used.
*
- * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E)
+ * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#x15.1.2.2)
* of `parseInt`.
*
* @static
diff --git a/partition.js b/partition.js
index c7c8f60f9..f33f13b2c 100644
--- a/partition.js
+++ b/partition.js
@@ -2,9 +2,9 @@ var createAggregator = require('./internal/createAggregator');
/**
* Creates an array of elements split into two groups, the first of which
- * contains elements `predicate` returns truthy for, while the second of which
- * contains elements `predicate` returns falsey for. The predicate is invoked
- * with three arguments: (value, index|key, collection).
+ * contains elements `predicate` returns truthy for, the second of which
+ * contains elements `predicate` returns falsey for. The predicate is
+ * invoked with one argument: (value).
*
* @static
* @memberOf _
diff --git a/pickBy.js b/pickBy.js
index 1e2651a29..5289d8757 100644
--- a/pickBy.js
+++ b/pickBy.js
@@ -19,7 +19,7 @@ var baseIteratee = require('./internal/baseIteratee'),
* // => { 'a': 1, 'c': 3 }
*/
function pickBy(object, predicate) {
- return object == null ? {} : basePickBy(object, baseIteratee(predicate));
+ return object == null ? {} : basePickBy(object, baseIteratee(predicate, 2));
}
module.exports = pickBy;
diff --git a/pullAll.js b/pullAll.js
index 55a6f180a..cf4020170 100644
--- a/pullAll.js
+++ b/pullAll.js
@@ -15,7 +15,7 @@ var basePullAll = require('./internal/basePullAll');
*
* var array = [1, 2, 3, 1, 2, 3];
*
- * _.pull(array, [2, 3]);
+ * _.pullAll(array, [2, 3]);
* console.log(array);
* // => [1, 1]
*/
diff --git a/range.js b/range.js
index 7b6ed9214..f6528304e 100644
--- a/range.js
+++ b/range.js
@@ -4,8 +4,7 @@ var createRange = require('./internal/createRange');
* Creates an array of numbers (positive and/or negative) progressing from
* `start` up to, but not including, `end`. A step of `-1` is used if a negative
* `start` is specified without an `end` or `step`. If `end` is not specified
- * it's set to `start` with `start` then set to `0`. If `end` is less than
- * `start` a zero-length range is created unless a negative `step` is specified.
+ * it's set to `start` with `start` then set to `0`.
*
* **Note:** JavaScript follows the IEEE-754 standard for resolving
* floating-point values which can produce unexpected results.
diff --git a/reduce.js b/reduce.js
index b8e49235f..0ae8064ff 100644
--- a/reduce.js
+++ b/reduce.js
@@ -41,9 +41,9 @@ var arrayReduce = require('./internal/arrayReduce'),
*/
function reduce(collection, iteratee, accumulator) {
var func = isArray(collection) ? arrayReduce : baseReduce,
- initFromCollection = arguments.length < 3;
+ initAccum = arguments.length < 3;
- return func(collection, baseIteratee(iteratee, 4), accumulator, initFromCollection, baseEach);
+ return func(collection, baseIteratee(iteratee, 4), accumulator, initAccum, baseEach);
}
module.exports = reduce;
diff --git a/reduceRight.js b/reduceRight.js
index 6038a281d..2864c5fda 100644
--- a/reduceRight.js
+++ b/reduceRight.js
@@ -26,9 +26,9 @@ var arrayReduceRight = require('./internal/arrayReduceRight'),
*/
function reduceRight(collection, iteratee, accumulator) {
var func = isArray(collection) ? arrayReduceRight : baseReduce,
- initFromCollection = arguments.length < 3;
+ initAccum = arguments.length < 3;
- return func(collection, baseIteratee(iteratee, 4), accumulator, initFromCollection, baseEachRight);
+ return func(collection, baseIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
}
module.exports = reduceRight;
diff --git a/reverse.js b/reverse.js
index 004cc82ac..7e8b5e03f 100644
--- a/reverse.js
+++ b/reverse.js
@@ -11,6 +11,7 @@ var nativeReverse = arrayProto.reverse;
* **Note:** This method mutates `array` and is based on
* [`Array#reverse`](https://mdn.io/Array/reverse).
*
+ * @static
* @memberOf _
* @category Array
* @returns {Array} Returns `array`.
diff --git a/sampleSize.js b/sampleSize.js
index eb75cc4e1..947a28dc1 100644
--- a/sampleSize.js
+++ b/sampleSize.js
@@ -4,7 +4,8 @@ var baseClamp = require('./internal/baseClamp'),
toInteger = require('./toInteger');
/**
- * Gets `n` random elements from `collection`.
+ * Gets `n` random elements at unique keys from `collection` up to the
+ * size of `collection`.
*
* @static
* @memberOf _
@@ -14,8 +15,11 @@ var baseClamp = require('./internal/baseClamp'),
* @returns {Array} Returns the random elements.
* @example
*
- * _.sampleSize([1, 2, 3, 4], 2);
+ * _.sampleSize([1, 2, 3], 2);
* // => [3, 1]
+ *
+ * _.sampleSize([1, 2, 3], 4);
+ * // => [2, 3, 1]
*/
function sampleSize(collection, n) {
var index = -1,
diff --git a/toArray.js b/toArray.js
index f35372fd5..582a0f629 100644
--- a/toArray.js
+++ b/toArray.js
@@ -1,4 +1,4 @@
-var _Symbol = require('./internal/_Symbol'),
+var Symbol = require('./internal/Symbol'),
copyArray = require('./internal/copyArray'),
getTag = require('./internal/getTag'),
isArrayLike = require('./isArrayLike'),
@@ -14,7 +14,7 @@ var mapTag = '[object Map]',
setTag = '[object Set]';
/** Built-in value references. */
-var iteratorSymbol = typeof (iteratorSymbol = _Symbol && _Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined;
+var iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined;
/**
* Converts `value` to an array.
diff --git a/toLength.js b/toLength.js
index 1e130f156..d309e7ca5 100644
--- a/toLength.js
+++ b/toLength.js
@@ -14,7 +14,7 @@ var MAX_ARRAY_LENGTH = 4294967295;
* @memberOf _
* @category Lang
* @param {*} value The value to convert.
- * @return {number} Returns the converted integer.
+ * @returns {number} Returns the converted integer.
* @example
*
* _.toLength(3);
diff --git a/toString.js b/toString.js
index b62551983..a9beaf9d7 100644
--- a/toString.js
+++ b/toString.js
@@ -1,12 +1,12 @@
-var _Symbol = require('./internal/_Symbol'),
+var Symbol = require('./internal/Symbol'),
isSymbol = require('./isSymbol');
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;
/** Used to convert symbols to primitives and strings. */
-var symbolProto = _Symbol ? _Symbol.prototype : undefined,
- symbolToString = _Symbol ? symbolProto.toString : undefined;
+var symbolProto = Symbol ? Symbol.prototype : undefined,
+ symbolToString = Symbol ? symbolProto.toString : undefined;
/**
* Converts `value` to a string if it's not one. An empty string is returned
@@ -37,7 +37,7 @@ function toString(value) {
return '';
}
if (isSymbol(value)) {
- return _Symbol ? symbolToString.call(value) : '';
+ return Symbol ? symbolToString.call(value) : '';
}
var result = (value + '');
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
diff --git a/truncate.js b/truncate.js
index d19925532..889101bc5 100644
--- a/truncate.js
+++ b/truncate.js
@@ -14,14 +14,15 @@ var reFlags = /\w*$/;
/** Used to compose unicode character classes. */
var rsAstralRange = '\\ud800-\\udfff',
- rsComboRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboSymbolsRange = '\\u20d0-\\u20f0',
rsVarRange = '\\ufe0e\\ufe0f';
/** Used to compose unicode capture groups. */
var rsZWJ = '\\u200d';
/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
-var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']');
+var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
/**
* Truncates `string` if it's longer than the given maximum string length.
diff --git a/words.js b/words.js
index 05d9785e2..20ea44987 100644
--- a/words.js
+++ b/words.js
@@ -2,6 +2,8 @@ var toString = require('./toString');
/** Used to compose unicode character classes. */
var rsAstralRange = '\\ud800-\\udfff',
+ rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboSymbolsRange = '\\u20d0-\\u20f0',
rsDingbatRange = '\\u2700-\\u27bf',
rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
@@ -14,11 +16,13 @@ var rsAstralRange = '\\ud800-\\udfff',
/** Used to compose unicode capture groups. */
var rsBreak = '[' + rsBreakRange + ']',
+ rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
rsDigits = '\\d+',
rsDingbat = '[' + rsDingbatRange + ']',
rsLower = '[' + rsLowerRange + ']',
rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
- rsModifier = '(?:\\ud83c[\\udffb-\\udfff])',
+ rsFitz = '\\ud83c[\\udffb-\\udfff]',
+ rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
rsNonAstral = '[^' + rsAstralRange + ']',
rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
@@ -42,7 +46,8 @@ var reComplexWord = RegExp([
rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
rsUpper + '?' + rsLowerMisc + '+',
- rsDigits + '(?:' + rsLowerMisc + '+)?',
+ rsUpper + '+',
+ rsDigits,
rsEmoji
].join('|'), 'g');
diff --git a/wrapperFlatMap.js b/wrapperFlatMap.js
index 2f67e5ae8..4c2f85b08 100644
--- a/wrapperFlatMap.js
+++ b/wrapperFlatMap.js
@@ -1,7 +1,7 @@
/**
* This method is the wrapper version of `_.flatMap`.
*
- * @static
+ * @name flatMap
* @memberOf _
* @category Seq
* @param {Function|Object|string} [iteratee=_.identity] The function invoked per iteration.
diff --git a/wrapperLodash.js b/wrapperLodash.js
index 5106ab1d9..77cb92e43 100644
--- a/wrapperLodash.js
+++ b/wrapperLodash.js
@@ -52,13 +52,12 @@ var hasOwnProperty = objectProto.hasOwnProperty;
* The chainable wrapper methods are:
* `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`,
* `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`,
- * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
+ * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`,
* `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`,
- * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
+ * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`,
* `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`,
- * `flowRight`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
- * `forOwnRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
- * `intersection`, `intersectionBy`, `intersectionWith`, invert`, `invokeMap`,
+ * `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`,
+ * `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invokeMap`,
* `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`,
* `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, `method`,
* `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, `orderBy`,
@@ -77,22 +76,23 @@ var hasOwnProperty = objectProto.hasOwnProperty;
* `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
* `cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `endsWith`, `eq`,
* `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`,
- * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `get`, `gt`, `gte`,
- * `has`, `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`,
- * `invoke`, `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`,
- * `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`,
- * `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`,
- * `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`,
- * `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, `isSafeInteger`,
- * `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, `last`,
- * `lastIndexOf`, `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`,
- * `mean`, `min`, `minBy`, `noConflict`, `noop`, `now`, `pad`, `padEnd`,
- * `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `repeat`,
- * `result`, `round`, `runInContext`, `sample`, `shift`, `size`, `snakeCase`,
- * `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`,
- * `startCase`, `startsWith`, `subtract`, `sum`, sumBy`, `template`, `times`,
- * `toLower`, `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, toString`,
- * `toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
+ * `findLast`, `findLastIndex`, `findLastKey`, `floor`, `forEach`, `forEachRight`,
+ * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
+ * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
+ * `isArguments`, `isArray`, `isArrayLike`, `isArrayLikeObject`, `isBoolean`,
+ * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isEqualWith`, `isError`,
+ * `isFinite`, `isFunction`, `isInteger`, `isLength`, `isMatch`, `isMatchWith`,
+ * `isNaN`, `isNative`, `isNil`, `isNull`, `isNumber`, `isObject`, `isObjectLike`,
+ * `isPlainObject`, `isRegExp`, `isSafeInteger`, `isString`, `isUndefined`,
+ * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `lowerCase`,
+ * `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `min`, `minBy`,
+ * `noConflict`, `noop`, `now`, `pad`, `padEnd`, `padStart`, `parseInt`,
+ * `pop`, `random`, `reduce`, `reduceRight`, `repeat`, `result`, `round`,
+ * `runInContext`, `sample`, `shift`, `size`, `snakeCase`, `some`, `sortedIndex`,
+ * `sortedIndexBy`, `sortedLastIndex`, `sortedLastIndexBy`, `startCase`,
+ * `startsWith`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toLower`,
+ * `toInteger`, `toLength`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`,
+ * `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`,
* `upperCase`, `upperFirst`, `value`, and `words`
*
* @name _
diff --git a/wrapperValue.js b/wrapperValue.js
index 363f4476a..2f7e908e1 100644
--- a/wrapperValue.js
+++ b/wrapperValue.js
@@ -5,7 +5,7 @@ var baseWrapperValue = require('./internal/baseWrapperValue');
*
* @name value
* @memberOf _
- * @alias run, toJSON, valueOf
+ * @alias toJSON, valueOf
* @category Seq
* @returns {*} Returns the resolved unwrapped value.
* @example