|
@@ -1,1650 +0,0 @@
|
|
|
-/**
|
|
|
|
|
- * @license
|
|
|
|
|
- * lodash 3.10.1 (Custom Build) <https://lodash.com/>
|
|
|
|
|
- * Build: `lodash modern exports="amd" include="clone,extend,isPlainObject,isObject,isArray,last,isEqual" --development --output src/lib/lodash/lodash-ckeditor.js`
|
|
|
|
|
- * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
|
|
|
|
|
- * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|
|
|
|
- * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
|
|
|
- * Available under MIT license <https://lodash.com/license>
|
|
|
|
|
- */
|
|
|
|
|
-;(function() {
|
|
|
|
|
-
|
|
|
|
|
- /** Used as a safe reference for `undefined` in pre-ES5 environments. */
|
|
|
|
|
- var undefined;
|
|
|
|
|
-
|
|
|
|
|
- /** Used as the semantic version number. */
|
|
|
|
|
- var VERSION = '3.10.1';
|
|
|
|
|
-
|
|
|
|
|
- /** Used as the `TypeError` message for "Functions" methods. */
|
|
|
|
|
- var FUNC_ERROR_TEXT = 'Expected a function';
|
|
|
|
|
-
|
|
|
|
|
- /** `Object#toString` result references. */
|
|
|
|
|
- var argsTag = '[object Arguments]',
|
|
|
|
|
- arrayTag = '[object Array]',
|
|
|
|
|
- boolTag = '[object Boolean]',
|
|
|
|
|
- dateTag = '[object Date]',
|
|
|
|
|
- errorTag = '[object Error]',
|
|
|
|
|
- funcTag = '[object Function]',
|
|
|
|
|
- mapTag = '[object Map]',
|
|
|
|
|
- numberTag = '[object Number]',
|
|
|
|
|
- objectTag = '[object Object]',
|
|
|
|
|
- regexpTag = '[object RegExp]',
|
|
|
|
|
- setTag = '[object Set]',
|
|
|
|
|
- stringTag = '[object String]',
|
|
|
|
|
- weakMapTag = '[object WeakMap]';
|
|
|
|
|
-
|
|
|
|
|
- var arrayBufferTag = '[object ArrayBuffer]',
|
|
|
|
|
- float32Tag = '[object Float32Array]',
|
|
|
|
|
- float64Tag = '[object Float64Array]',
|
|
|
|
|
- int8Tag = '[object Int8Array]',
|
|
|
|
|
- int16Tag = '[object Int16Array]',
|
|
|
|
|
- int32Tag = '[object Int32Array]',
|
|
|
|
|
- uint8Tag = '[object Uint8Array]',
|
|
|
|
|
- uint8ClampedTag = '[object Uint8ClampedArray]',
|
|
|
|
|
- uint16Tag = '[object Uint16Array]',
|
|
|
|
|
- uint32Tag = '[object Uint32Array]';
|
|
|
|
|
-
|
|
|
|
|
- /** Used to match `RegExp` flags from their coerced string values. */
|
|
|
|
|
- var reFlags = /\w*$/;
|
|
|
|
|
-
|
|
|
|
|
- /** Used to detect host constructors (Safari > 5). */
|
|
|
|
|
- var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
|
|
|
-
|
|
|
|
|
- /** Used to detect unsigned integer values. */
|
|
|
|
|
- var reIsUint = /^\d+$/;
|
|
|
|
|
-
|
|
|
|
|
- /** Used to identify `toStringTag` values of typed arrays. */
|
|
|
|
|
- var typedArrayTags = {};
|
|
|
|
|
- typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
|
|
|
|
|
- typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
|
|
|
|
|
- typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
|
|
|
|
|
- typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
|
|
|
|
|
- typedArrayTags[uint32Tag] = true;
|
|
|
|
|
- typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
|
|
|
|
|
- typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
|
|
|
|
|
- typedArrayTags[dateTag] = typedArrayTags[errorTag] =
|
|
|
|
|
- typedArrayTags[funcTag] = typedArrayTags[mapTag] =
|
|
|
|
|
- typedArrayTags[numberTag] = typedArrayTags[objectTag] =
|
|
|
|
|
- typedArrayTags[regexpTag] = typedArrayTags[setTag] =
|
|
|
|
|
- typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
|
|
|
|
|
-
|
|
|
|
|
- /** Used to identify `toStringTag` values supported by `_.clone`. */
|
|
|
|
|
- var cloneableTags = {};
|
|
|
|
|
- cloneableTags[argsTag] = cloneableTags[arrayTag] =
|
|
|
|
|
- cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
|
|
|
|
|
- cloneableTags[dateTag] = cloneableTags[float32Tag] =
|
|
|
|
|
- cloneableTags[float64Tag] = cloneableTags[int8Tag] =
|
|
|
|
|
- cloneableTags[int16Tag] = cloneableTags[int32Tag] =
|
|
|
|
|
- cloneableTags[numberTag] = cloneableTags[objectTag] =
|
|
|
|
|
- cloneableTags[regexpTag] = cloneableTags[stringTag] =
|
|
|
|
|
- cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
|
|
|
|
|
- cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
|
|
|
|
|
- cloneableTags[errorTag] = cloneableTags[funcTag] =
|
|
|
|
|
- cloneableTags[mapTag] = cloneableTags[setTag] =
|
|
|
|
|
- cloneableTags[weakMapTag] = false;
|
|
|
|
|
-
|
|
|
|
|
- /** 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;
|
|
|
|
|
-
|
|
|
|
|
- /** Detect free variable `module`. */
|
|
|
|
|
- var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
|
|
|
|
|
-
|
|
|
|
|
- /** Detect free variable `global` from Node.js. */
|
|
|
|
|
- var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global;
|
|
|
|
|
-
|
|
|
|
|
- /** Detect free variable `self`. */
|
|
|
|
|
- var freeSelf = objectTypes[typeof self] && self && self.Object && self;
|
|
|
|
|
-
|
|
|
|
|
- /** Detect free variable `window`. */
|
|
|
|
|
- var freeWindow = objectTypes[typeof window] && window && window.Object && window;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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 !== (this && this.window)) && freeWindow) || freeSelf || this;
|
|
|
|
|
-
|
|
|
|
|
- /*--------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Checks if `value` is object-like.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {*} value The value to check.
|
|
|
|
|
- * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
|
|
|
- */
|
|
|
|
|
- function isObjectLike(value) {
|
|
|
|
|
- return !!value && typeof value == 'object';
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*--------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- /** Used for native method references. */
|
|
|
|
|
- var objectProto = Object.prototype;
|
|
|
|
|
-
|
|
|
|
|
- /** Used to resolve the decompiled source of functions. */
|
|
|
|
|
- var fnToString = Function.prototype.toString;
|
|
|
|
|
-
|
|
|
|
|
- /** Used to check objects for own properties. */
|
|
|
|
|
- var hasOwnProperty = objectProto.hasOwnProperty;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
|
|
|
|
- * of values.
|
|
|
|
|
- */
|
|
|
|
|
- var objToString = objectProto.toString;
|
|
|
|
|
-
|
|
|
|
|
- /** Used to detect if a method is native. */
|
|
|
|
|
- var reIsNative = RegExp('^' +
|
|
|
|
|
- fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
|
|
|
|
|
- .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- /** Native method references. */
|
|
|
|
|
- var ArrayBuffer = root.ArrayBuffer,
|
|
|
|
|
- propertyIsEnumerable = objectProto.propertyIsEnumerable,
|
|
|
|
|
- Uint8Array = root.Uint8Array;
|
|
|
|
|
-
|
|
|
|
|
- /* Native method references for those with the same name as other `lodash` methods. */
|
|
|
|
|
- var nativeIsArray = getNative(Array, 'isArray'),
|
|
|
|
|
- nativeKeys = getNative(Object, 'keys'),
|
|
|
|
|
- nativeMax = Math.max;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
|
|
|
|
|
- * of an array-like value.
|
|
|
|
|
- */
|
|
|
|
|
- var MAX_SAFE_INTEGER = 9007199254740991;
|
|
|
|
|
-
|
|
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Creates a `lodash` object which wraps `value` to enable implicit 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 returning the unwrapped
|
|
|
|
|
- * value. Explicit chaining may be enabled using `_.chain`. The execution of
|
|
|
|
|
- * chained methods is lazy, that is, execution is deferred until `_#value`
|
|
|
|
|
- * is implicitly or explicitly called.
|
|
|
|
|
- *
|
|
|
|
|
- * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
|
|
|
|
|
- * fusion is an optimization strategy which merge iteratee calls; this can help
|
|
|
|
|
- * to avoid the creation of intermediate data structures and greatly reduce the
|
|
|
|
|
- * number of iteratee executions.
|
|
|
|
|
- *
|
|
|
|
|
- * 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`, `reverse`, `shift`, `slice`, `sort`,
|
|
|
|
|
- * `splice`, and `unshift`
|
|
|
|
|
- *
|
|
|
|
|
- * The wrapper `String` methods are:
|
|
|
|
|
- * `replace` and `split`
|
|
|
|
|
- *
|
|
|
|
|
- * The wrapper methods that support shortcut fusion are:
|
|
|
|
|
- * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,
|
|
|
|
|
- * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,
|
|
|
|
|
- * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,
|
|
|
|
|
- * and `where`
|
|
|
|
|
- *
|
|
|
|
|
- * The chainable wrapper methods are:
|
|
|
|
|
- * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,
|
|
|
|
|
- * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,
|
|
|
|
|
- * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,
|
|
|
|
|
- * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,
|
|
|
|
|
- * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,
|
|
|
|
|
- * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
|
|
|
|
|
- * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
|
|
|
|
|
- * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,
|
|
|
|
|
- * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,
|
|
|
|
|
- * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
|
|
|
|
|
- * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,
|
|
|
|
|
- * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,
|
|
|
|
|
- * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,
|
|
|
|
|
- * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,
|
|
|
|
|
- * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,
|
|
|
|
|
- * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,
|
|
|
|
|
- * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
|
|
|
|
|
- *
|
|
|
|
|
- * The wrapper methods that are **not** chainable by default are:
|
|
|
|
|
- * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,
|
|
|
|
|
- * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,
|
|
|
|
|
- * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,
|
|
|
|
|
- * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,
|
|
|
|
|
- * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
|
|
|
|
|
- * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,
|
|
|
|
|
- * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,
|
|
|
|
|
- * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,
|
|
|
|
|
- * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,
|
|
|
|
|
- * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,
|
|
|
|
|
- * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,
|
|
|
|
|
- * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,
|
|
|
|
|
- * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
|
|
|
|
|
- * `unescape`, `uniqueId`, `value`, and `words`
|
|
|
|
|
- *
|
|
|
|
|
- * The wrapper method `sample` will return a wrapped value when `n` is provided,
|
|
|
|
|
- * otherwise an unwrapped value is returned.
|
|
|
|
|
- *
|
|
|
|
|
- * @name _
|
|
|
|
|
- * @constructor
|
|
|
|
|
- * @category Chain
|
|
|
|
|
- * @param {*} value The value to wrap in a `lodash` instance.
|
|
|
|
|
- * @returns {Object} Returns the new `lodash` wrapper instance.
|
|
|
|
|
- * @example
|
|
|
|
|
- *
|
|
|
|
|
- * var wrapped = _([1, 2, 3]);
|
|
|
|
|
- *
|
|
|
|
|
- * // returns an unwrapped value
|
|
|
|
|
- * wrapped.reduce(function(total, n) {
|
|
|
|
|
- * return total + n;
|
|
|
|
|
- * });
|
|
|
|
|
- * // => 6
|
|
|
|
|
- *
|
|
|
|
|
- * // returns a wrapped value
|
|
|
|
|
- * var squares = wrapped.map(function(n) {
|
|
|
|
|
- * return n * n;
|
|
|
|
|
- * });
|
|
|
|
|
- *
|
|
|
|
|
- * _.isArray(squares);
|
|
|
|
|
- * // => false
|
|
|
|
|
- *
|
|
|
|
|
- * _.isArray(squares.value());
|
|
|
|
|
- * // => true
|
|
|
|
|
- */
|
|
|
|
|
- function lodash() {
|
|
|
|
|
- // No operation performed.
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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 arrayCopy(source, array) {
|
|
|
|
|
- var index = -1,
|
|
|
|
|
- length = source.length;
|
|
|
|
|
-
|
|
|
|
|
- array || (array = Array(length));
|
|
|
|
|
- while (++index < length) {
|
|
|
|
|
- array[index] = source[index];
|
|
|
|
|
- }
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * A specialized version of `_.forEach` for arrays without support for callback
|
|
|
|
|
- * shorthands and `this` binding.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Array} array The array to iterate over.
|
|
|
|
|
- * @param {Function} iteratee The function invoked per iteration.
|
|
|
|
|
- * @returns {Array} Returns `array`.
|
|
|
|
|
- */
|
|
|
|
|
- function arrayEach(array, iteratee) {
|
|
|
|
|
- var index = -1,
|
|
|
|
|
- length = array.length;
|
|
|
|
|
-
|
|
|
|
|
- while (++index < length) {
|
|
|
|
|
- if (iteratee(array[index], index, array) === false) {
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return array;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * A specialized version of `_.some` for arrays without support for callback
|
|
|
|
|
- * shorthands and `this` binding.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Array} array The array to iterate over.
|
|
|
|
|
- * @param {Function} predicate The function invoked per iteration.
|
|
|
|
|
- * @returns {boolean} Returns `true` if any element passes the predicate check,
|
|
|
|
|
- * else `false`.
|
|
|
|
|
- */
|
|
|
|
|
- function arraySome(array, predicate) {
|
|
|
|
|
- var index = -1,
|
|
|
|
|
- length = array.length;
|
|
|
|
|
-
|
|
|
|
|
- while (++index < length) {
|
|
|
|
|
- if (predicate(array[index], index, array)) {
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * A specialized version of `_.assign` for customizing assigned values without
|
|
|
|
|
- * support for argument juggling, multiple sources, and `this` binding `customizer`
|
|
|
|
|
- * functions.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Object} object The destination object.
|
|
|
|
|
- * @param {Object} source The source object.
|
|
|
|
|
- * @param {Function} customizer The function to customize assigned values.
|
|
|
|
|
- * @returns {Object} Returns `object`.
|
|
|
|
|
- */
|
|
|
|
|
- function assignWith(object, source, customizer) {
|
|
|
|
|
- var index = -1,
|
|
|
|
|
- props = keys(source),
|
|
|
|
|
- length = props.length;
|
|
|
|
|
-
|
|
|
|
|
- while (++index < length) {
|
|
|
|
|
- var key = props[index],
|
|
|
|
|
- value = object[key],
|
|
|
|
|
- result = customizer(value, source[key], key, object, source);
|
|
|
|
|
-
|
|
|
|
|
- if ((result === result ? (result !== value) : (value === value)) ||
|
|
|
|
|
- (value === undefined && !(key in object))) {
|
|
|
|
|
- object[key] = result;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return object;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * The base implementation of `_.assign` without support for argument juggling,
|
|
|
|
|
- * multiple sources, and `customizer` functions.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Object} object The destination object.
|
|
|
|
|
- * @param {Object} source The source object.
|
|
|
|
|
- * @returns {Object} Returns `object`.
|
|
|
|
|
- */
|
|
|
|
|
- function baseAssign(object, source) {
|
|
|
|
|
- return source == null
|
|
|
|
|
- ? object
|
|
|
|
|
- : baseCopy(source, keys(source), object);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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`.
|
|
|
|
|
- */
|
|
|
|
|
- function baseCopy(source, props, object) {
|
|
|
|
|
- object || (object = {});
|
|
|
|
|
-
|
|
|
|
|
- var index = -1,
|
|
|
|
|
- length = props.length;
|
|
|
|
|
-
|
|
|
|
|
- while (++index < length) {
|
|
|
|
|
- var key = props[index];
|
|
|
|
|
- object[key] = source[key];
|
|
|
|
|
- }
|
|
|
|
|
- return object;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * The base implementation of `_.clone` without support for argument juggling
|
|
|
|
|
- * and `this` binding `customizer` functions.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {*} value The value to clone.
|
|
|
|
|
- * @param {boolean} [isDeep] Specify a deep clone.
|
|
|
|
|
- * @param {Function} [customizer] The function to customize cloning values.
|
|
|
|
|
- * @param {string} [key] The key of `value`.
|
|
|
|
|
- * @param {Object} [object] The object `value` belongs to.
|
|
|
|
|
- * @param {Array} [stackA=[]] Tracks traversed source objects.
|
|
|
|
|
- * @param {Array} [stackB=[]] Associates clones with source counterparts.
|
|
|
|
|
- * @returns {*} Returns the cloned value.
|
|
|
|
|
- */
|
|
|
|
|
- function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
|
|
|
|
|
- var result;
|
|
|
|
|
- if (customizer) {
|
|
|
|
|
- result = object ? customizer(value, key, object) : customizer(value);
|
|
|
|
|
- }
|
|
|
|
|
- if (result !== undefined) {
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
- if (!isObject(value)) {
|
|
|
|
|
- return value;
|
|
|
|
|
- }
|
|
|
|
|
- var isArr = isArray(value);
|
|
|
|
|
- if (isArr) {
|
|
|
|
|
- result = initCloneArray(value);
|
|
|
|
|
- if (!isDeep) {
|
|
|
|
|
- return arrayCopy(value, result);
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- var tag = objToString.call(value),
|
|
|
|
|
- isFunc = tag == funcTag;
|
|
|
|
|
-
|
|
|
|
|
- if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
|
|
|
|
|
- result = initCloneObject(isFunc ? {} : value);
|
|
|
|
|
- if (!isDeep) {
|
|
|
|
|
- return baseAssign(result, value);
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- return cloneableTags[tag]
|
|
|
|
|
- ? initCloneByTag(value, tag, isDeep)
|
|
|
|
|
- : (object ? value : {});
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- // Check for circular references and return its corresponding clone.
|
|
|
|
|
- stackA || (stackA = []);
|
|
|
|
|
- stackB || (stackB = []);
|
|
|
|
|
-
|
|
|
|
|
- var length = stackA.length;
|
|
|
|
|
- while (length--) {
|
|
|
|
|
- if (stackA[length] == value) {
|
|
|
|
|
- return stackB[length];
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- // Add the source value to the stack of traversed objects and associate it with its clone.
|
|
|
|
|
- stackA.push(value);
|
|
|
|
|
- stackB.push(result);
|
|
|
|
|
-
|
|
|
|
|
- // Recursively populate clone (susceptible to call stack limits).
|
|
|
|
|
- (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
|
|
|
|
|
- result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
|
|
|
|
|
- });
|
|
|
|
|
- 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 `_.forIn` without support for callback
|
|
|
|
|
- * shorthands and `this` binding.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Object} object The object to iterate over.
|
|
|
|
|
- * @param {Function} iteratee The function invoked per iteration.
|
|
|
|
|
- * @returns {Object} Returns `object`.
|
|
|
|
|
- */
|
|
|
|
|
- function baseForIn(object, iteratee) {
|
|
|
|
|
- return baseFor(object, iteratee, keysIn);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * The base implementation of `_.forOwn` without support for callback
|
|
|
|
|
- * shorthands and `this` binding.
|
|
|
|
|
- *
|
|
|
|
|
- * @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 baseFor(object, iteratee, keys);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * The base implementation of `_.isEqual` without support for `this` binding
|
|
|
|
|
- * `customizer` functions.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {*} value The value to compare.
|
|
|
|
|
- * @param {*} other The other value to compare.
|
|
|
|
|
- * @param {Function} [customizer] The function to customize comparing values.
|
|
|
|
|
- * @param {boolean} [isLoose] Specify performing partial comparisons.
|
|
|
|
|
- * @param {Array} [stackA] Tracks traversed `value` objects.
|
|
|
|
|
- * @param {Array} [stackB] Tracks traversed `other` objects.
|
|
|
|
|
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
|
|
|
- */
|
|
|
|
|
- function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
|
|
|
|
|
- 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, isLoose, stackA, stackB);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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 comparing objects.
|
|
|
|
|
- * @param {boolean} [isLoose] Specify performing partial comparisons.
|
|
|
|
|
- * @param {Array} [stackA=[]] Tracks traversed `value` objects.
|
|
|
|
|
- * @param {Array} [stackB=[]] Tracks traversed `other` objects.
|
|
|
|
|
- * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|
|
|
|
- */
|
|
|
|
|
- function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
|
|
|
|
|
- var objIsArr = isArray(object),
|
|
|
|
|
- othIsArr = isArray(other),
|
|
|
|
|
- objTag = arrayTag,
|
|
|
|
|
- othTag = arrayTag;
|
|
|
|
|
-
|
|
|
|
|
- if (!objIsArr) {
|
|
|
|
|
- objTag = objToString.call(object);
|
|
|
|
|
- if (objTag == argsTag) {
|
|
|
|
|
- objTag = objectTag;
|
|
|
|
|
- } else if (objTag != objectTag) {
|
|
|
|
|
- objIsArr = isTypedArray(object);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (!othIsArr) {
|
|
|
|
|
- othTag = objToString.call(other);
|
|
|
|
|
- if (othTag == argsTag) {
|
|
|
|
|
- othTag = objectTag;
|
|
|
|
|
- } else if (othTag != objectTag) {
|
|
|
|
|
- othIsArr = isTypedArray(other);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- var objIsObj = objTag == objectTag,
|
|
|
|
|
- othIsObj = othTag == objectTag,
|
|
|
|
|
- isSameTag = objTag == othTag;
|
|
|
|
|
-
|
|
|
|
|
- if (isSameTag && !(objIsArr || objIsObj)) {
|
|
|
|
|
- return equalByTag(object, other, objTag);
|
|
|
|
|
- }
|
|
|
|
|
- if (!isLoose) {
|
|
|
|
|
- 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, isLoose, stackA, stackB);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- if (!isSameTag) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- // Assume cyclic values are equal.
|
|
|
|
|
- // For more information on detecting circular references see https://es5.github.io/#JO.
|
|
|
|
|
- stackA || (stackA = []);
|
|
|
|
|
- stackB || (stackB = []);
|
|
|
|
|
-
|
|
|
|
|
- var length = stackA.length;
|
|
|
|
|
- while (length--) {
|
|
|
|
|
- if (stackA[length] == object) {
|
|
|
|
|
- return stackB[length] == other;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- // Add `object` and `other` to the stack of traversed objects.
|
|
|
|
|
- stackA.push(object);
|
|
|
|
|
- stackB.push(other);
|
|
|
|
|
-
|
|
|
|
|
- var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
|
|
|
|
|
-
|
|
|
|
|
- stackA.pop();
|
|
|
|
|
- stackB.pop();
|
|
|
|
|
-
|
|
|
|
|
- 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];
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * A specialized version of `baseCallback` which only supports `this` binding
|
|
|
|
|
- * and specifying the number of arguments to provide to `func`.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Function} func The function to bind.
|
|
|
|
|
- * @param {*} thisArg The `this` binding of `func`.
|
|
|
|
|
- * @param {number} [argCount] The number of arguments to provide to `func`.
|
|
|
|
|
- * @returns {Function} Returns the callback.
|
|
|
|
|
- */
|
|
|
|
|
- function bindCallback(func, thisArg, argCount) {
|
|
|
|
|
- if (typeof func != 'function') {
|
|
|
|
|
- return identity;
|
|
|
|
|
- }
|
|
|
|
|
- if (thisArg === undefined) {
|
|
|
|
|
- return func;
|
|
|
|
|
- }
|
|
|
|
|
- switch (argCount) {
|
|
|
|
|
- case 1: return function(value) {
|
|
|
|
|
- return func.call(thisArg, value);
|
|
|
|
|
- };
|
|
|
|
|
- case 3: return function(value, index, collection) {
|
|
|
|
|
- return func.call(thisArg, value, index, collection);
|
|
|
|
|
- };
|
|
|
|
|
- case 4: return function(accumulator, value, index, collection) {
|
|
|
|
|
- return func.call(thisArg, accumulator, value, index, collection);
|
|
|
|
|
- };
|
|
|
|
|
- case 5: return function(value, other, key, object, source) {
|
|
|
|
|
- return func.call(thisArg, value, other, key, object, source);
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
- return function() {
|
|
|
|
|
- return func.apply(thisArg, arguments);
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Creates a clone of the given array buffer.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {ArrayBuffer} buffer The array buffer to clone.
|
|
|
|
|
- * @returns {ArrayBuffer} Returns the cloned array buffer.
|
|
|
|
|
- */
|
|
|
|
|
- function bufferClone(buffer) {
|
|
|
|
|
- var result = new ArrayBuffer(buffer.byteLength),
|
|
|
|
|
- view = new Uint8Array(result);
|
|
|
|
|
-
|
|
|
|
|
- view.set(new Uint8Array(buffer));
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Creates a `_.assign`, `_.defaults`, or `_.merge` function.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Function} assigner The function to assign values.
|
|
|
|
|
- * @returns {Function} Returns the new assigner function.
|
|
|
|
|
- */
|
|
|
|
|
- function createAssigner(assigner) {
|
|
|
|
|
- return restParam(function(object, sources) {
|
|
|
|
|
- var index = -1,
|
|
|
|
|
- length = object == null ? 0 : sources.length,
|
|
|
|
|
- customizer = length > 2 ? sources[length - 2] : undefined,
|
|
|
|
|
- guard = length > 2 ? sources[2] : undefined,
|
|
|
|
|
- thisArg = length > 1 ? sources[length - 1] : undefined;
|
|
|
|
|
-
|
|
|
|
|
- if (typeof customizer == 'function') {
|
|
|
|
|
- customizer = bindCallback(customizer, thisArg, 5);
|
|
|
|
|
- length -= 2;
|
|
|
|
|
- } else {
|
|
|
|
|
- customizer = typeof thisArg == 'function' ? thisArg : undefined;
|
|
|
|
|
- length -= (customizer ? 1 : 0);
|
|
|
|
|
- }
|
|
|
|
|
- if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
|
|
|
|
- customizer = length < 3 ? undefined : customizer;
|
|
|
|
|
- length = 1;
|
|
|
|
|
- }
|
|
|
|
|
- while (++index < length) {
|
|
|
|
|
- var source = sources[index];
|
|
|
|
|
- if (source) {
|
|
|
|
|
- assigner(object, source, customizer);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return object;
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Creates a base function for `_.forIn` or `_.forInRight`.
|
|
|
|
|
- *
|
|
|
|
|
- * @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 iterable = toObject(object),
|
|
|
|
|
- props = keysFunc(object),
|
|
|
|
|
- length = props.length,
|
|
|
|
|
- index = fromRight ? length : -1;
|
|
|
|
|
-
|
|
|
|
|
- while ((fromRight ? index-- : ++index < length)) {
|
|
|
|
|
- var key = props[index];
|
|
|
|
|
- if (iteratee(iterable[key], key, iterable) === false) {
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return object;
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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 comparing arrays.
|
|
|
|
|
- * @param {boolean} [isLoose] Specify performing partial comparisons.
|
|
|
|
|
- * @param {Array} [stackA] Tracks traversed `value` objects.
|
|
|
|
|
- * @param {Array} [stackB] Tracks traversed `other` objects.
|
|
|
|
|
- * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
|
|
|
|
|
- */
|
|
|
|
|
- function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
|
|
|
|
|
- var index = -1,
|
|
|
|
|
- arrLength = array.length,
|
|
|
|
|
- othLength = other.length;
|
|
|
|
|
-
|
|
|
|
|
- if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- // Ignore non-index properties.
|
|
|
|
|
- while (++index < arrLength) {
|
|
|
|
|
- var arrValue = array[index],
|
|
|
|
|
- othValue = other[index],
|
|
|
|
|
- result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;
|
|
|
|
|
-
|
|
|
|
|
- if (result !== undefined) {
|
|
|
|
|
- if (result) {
|
|
|
|
|
- continue;
|
|
|
|
|
- }
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- // Recursively compare arrays (susceptible to call stack limits).
|
|
|
|
|
- if (isLoose) {
|
|
|
|
|
- if (!arraySome(other, function(othValue) {
|
|
|
|
|
- return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
|
|
|
|
|
- })) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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.
|
|
|
|
|
- * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|
|
|
|
- */
|
|
|
|
|
- function equalByTag(object, other, tag) {
|
|
|
|
|
- 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 comparing values.
|
|
|
|
|
- * @param {boolean} [isLoose] Specify performing partial comparisons.
|
|
|
|
|
- * @param {Array} [stackA] Tracks traversed `value` objects.
|
|
|
|
|
- * @param {Array} [stackB] Tracks traversed `other` objects.
|
|
|
|
|
- * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
|
|
|
|
- */
|
|
|
|
|
- function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
|
|
|
|
|
- var objProps = keys(object),
|
|
|
|
|
- objLength = objProps.length,
|
|
|
|
|
- othProps = keys(other),
|
|
|
|
|
- othLength = othProps.length;
|
|
|
|
|
-
|
|
|
|
|
- if (objLength != othLength && !isLoose) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- var index = objLength;
|
|
|
|
|
- while (index--) {
|
|
|
|
|
- var key = objProps[index];
|
|
|
|
|
- if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- var skipCtor = isLoose;
|
|
|
|
|
- while (++index < objLength) {
|
|
|
|
|
- key = objProps[index];
|
|
|
|
|
- var objValue = object[key],
|
|
|
|
|
- othValue = other[key],
|
|
|
|
|
- result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;
|
|
|
|
|
-
|
|
|
|
|
- // Recursively compare objects (susceptible to call stack limits).
|
|
|
|
|
- if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- skipCtor || (skipCtor = key == 'constructor');
|
|
|
|
|
- }
|
|
|
|
|
- if (!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)) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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');
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Gets the native function at `key` of `object`.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Object} object The object to query.
|
|
|
|
|
- * @param {string} key The key of the method to get.
|
|
|
|
|
- * @returns {*} Returns the function if it's native, else `undefined`.
|
|
|
|
|
- */
|
|
|
|
|
- function getNative(object, key) {
|
|
|
|
|
- var value = object == null ? undefined : object[key];
|
|
|
|
|
- return isNative(value) ? value : undefined;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Initializes an array clone.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Array} array The array to clone.
|
|
|
|
|
- * @returns {Array} Returns the initialized clone.
|
|
|
|
|
- */
|
|
|
|
|
- function initCloneArray(array) {
|
|
|
|
|
- var length = array.length,
|
|
|
|
|
- result = new array.constructor(length);
|
|
|
|
|
-
|
|
|
|
|
- // Add array properties assigned by `RegExp#exec`.
|
|
|
|
|
- if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
|
|
|
|
|
- result.index = array.index;
|
|
|
|
|
- result.input = array.input;
|
|
|
|
|
- }
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Initializes an object clone.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Object} object The object to clone.
|
|
|
|
|
- * @returns {Object} Returns the initialized clone.
|
|
|
|
|
- */
|
|
|
|
|
- function initCloneObject(object) {
|
|
|
|
|
- var Ctor = object.constructor;
|
|
|
|
|
- if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
|
|
|
|
|
- Ctor = Object;
|
|
|
|
|
- }
|
|
|
|
|
- return new Ctor;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Initializes an object clone based on its `toStringTag`.
|
|
|
|
|
- *
|
|
|
|
|
- * **Note:** This function only supports cloning values with tags of
|
|
|
|
|
- * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Object} object The object to clone.
|
|
|
|
|
- * @param {string} tag The `toStringTag` of the object to clone.
|
|
|
|
|
- * @param {boolean} [isDeep] Specify a deep clone.
|
|
|
|
|
- * @returns {Object} Returns the initialized clone.
|
|
|
|
|
- */
|
|
|
|
|
- function initCloneByTag(object, tag, isDeep) {
|
|
|
|
|
- var Ctor = object.constructor;
|
|
|
|
|
- switch (tag) {
|
|
|
|
|
- case arrayBufferTag:
|
|
|
|
|
- return bufferClone(object);
|
|
|
|
|
-
|
|
|
|
|
- case boolTag:
|
|
|
|
|
- case dateTag:
|
|
|
|
|
- return new Ctor(+object);
|
|
|
|
|
-
|
|
|
|
|
- case float32Tag: case float64Tag:
|
|
|
|
|
- case int8Tag: case int16Tag: case int32Tag:
|
|
|
|
|
- case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
|
|
|
|
|
- var buffer = object.buffer;
|
|
|
|
|
- return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
|
|
|
|
|
-
|
|
|
|
|
- case numberTag:
|
|
|
|
|
- case stringTag:
|
|
|
|
|
- return new Ctor(object);
|
|
|
|
|
-
|
|
|
|
|
- case regexpTag:
|
|
|
|
|
- var result = new Ctor(object.source, reFlags.exec(object));
|
|
|
|
|
- result.lastIndex = object.lastIndex;
|
|
|
|
|
- }
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Checks if `value` is array-like.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {*} value The value to check.
|
|
|
|
|
- * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|
|
|
|
- */
|
|
|
|
|
- function isArrayLike(value) {
|
|
|
|
|
- return value != null && isLength(getLength(value));
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Checks if the provided arguments are from an iteratee call.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {*} value The potential iteratee value argument.
|
|
|
|
|
- * @param {*} index The potential iteratee index or key argument.
|
|
|
|
|
- * @param {*} object The potential iteratee object argument.
|
|
|
|
|
- * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
|
|
|
|
|
- */
|
|
|
|
|
- function isIterateeCall(value, index, object) {
|
|
|
|
|
- if (!isObject(object)) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- var type = typeof index;
|
|
|
|
|
- if (type == 'number'
|
|
|
|
|
- ? (isArrayLike(object) && isIndex(index, object.length))
|
|
|
|
|
- : (type == 'string' && index in object)) {
|
|
|
|
|
- var other = object[index];
|
|
|
|
|
- return value === value ? (value === other) : (other !== other);
|
|
|
|
|
- }
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Checks if `value` is a valid array-like length.
|
|
|
|
|
- *
|
|
|
|
|
- * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {*} value The value to check.
|
|
|
|
|
- * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|
|
|
|
- */
|
|
|
|
|
- function isLength(value) {
|
|
|
|
|
- return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * A fallback implementation of `Object.keys` which creates an array of the
|
|
|
|
|
- * own enumerable property names of `object`.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {Object} object The object to query.
|
|
|
|
|
- * @returns {Array} Returns the array of property names.
|
|
|
|
|
- */
|
|
|
|
|
- function shimKeys(object) {
|
|
|
|
|
- var props = keysIn(object),
|
|
|
|
|
- propsLength = props.length,
|
|
|
|
|
- length = propsLength && object.length;
|
|
|
|
|
-
|
|
|
|
|
- var allowIndexes = !!length && isLength(length) &&
|
|
|
|
|
- (isArray(object) || isArguments(object));
|
|
|
|
|
-
|
|
|
|
|
- var index = -1,
|
|
|
|
|
- result = [];
|
|
|
|
|
-
|
|
|
|
|
- while (++index < propsLength) {
|
|
|
|
|
- var key = props[index];
|
|
|
|
|
- if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
|
|
|
|
|
- result.push(key);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Converts `value` to an object if it's not one.
|
|
|
|
|
- *
|
|
|
|
|
- * @private
|
|
|
|
|
- * @param {*} value The value to process.
|
|
|
|
|
- * @returns {Object} Returns the object.
|
|
|
|
|
- */
|
|
|
|
|
- function toObject(value) {
|
|
|
|
|
- return isObject(value) ? value : Object(value);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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 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://developer.mozilla.org/Web/JavaScript/Reference/Functions/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 = _.restParam(function(what, names) {
|
|
|
|
|
- * return what + ' ' + _.initial(names).join(', ') +
|
|
|
|
|
- * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
|
|
|
|
|
- * });
|
|
|
|
|
- *
|
|
|
|
|
- * say('hello', 'fred', 'barney', 'pebbles');
|
|
|
|
|
- * // => 'hello fred, barney, & pebbles'
|
|
|
|
|
- */
|
|
|
|
|
- function restParam(func, start) {
|
|
|
|
|
- if (typeof func != 'function') {
|
|
|
|
|
- throw new TypeError(FUNC_ERROR_TEXT);
|
|
|
|
|
- }
|
|
|
|
|
- start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
|
|
|
|
|
- return function() {
|
|
|
|
|
- var args = arguments,
|
|
|
|
|
- index = -1,
|
|
|
|
|
- length = nativeMax(args.length - start, 0),
|
|
|
|
|
- rest = Array(length);
|
|
|
|
|
-
|
|
|
|
|
- while (++index < length) {
|
|
|
|
|
- rest[index] = args[start + index];
|
|
|
|
|
- }
|
|
|
|
|
- switch (start) {
|
|
|
|
|
- case 0: return func.call(this, rest);
|
|
|
|
|
- case 1: return func.call(this, args[0], rest);
|
|
|
|
|
- case 2: return func.call(this, args[0], args[1], rest);
|
|
|
|
|
- }
|
|
|
|
|
- var otherArgs = Array(start + 1);
|
|
|
|
|
- index = -1;
|
|
|
|
|
- while (++index < start) {
|
|
|
|
|
- otherArgs[index] = args[index];
|
|
|
|
|
- }
|
|
|
|
|
- otherArgs[start] = rest;
|
|
|
|
|
- return func.apply(this, otherArgs);
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned,
|
|
|
|
|
- * otherwise they are assigned by reference. If `customizer` is provided it's
|
|
|
|
|
- * invoked to produce the cloned values. If `customizer` returns `undefined`
|
|
|
|
|
- * cloning is handled by the method instead. The `customizer` is bound to
|
|
|
|
|
- * `thisArg` and invoked with up to three argument; (value [, index|key, object]).
|
|
|
|
|
- *
|
|
|
|
|
- * **Note:** This method is loosely based on the
|
|
|
|
|
- * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
|
|
|
|
|
- * The enumerable properties of `arguments` objects and objects created by
|
|
|
|
|
- * constructors other than `Object` are cloned to plain `Object` objects. An
|
|
|
|
|
- * empty object is returned for uncloneable values such as functions, DOM nodes,
|
|
|
|
|
- * Maps, Sets, and WeakMaps.
|
|
|
|
|
- *
|
|
|
|
|
- * @static
|
|
|
|
|
- * @memberOf _
|
|
|
|
|
- * @category Lang
|
|
|
|
|
- * @param {*} value The value to clone.
|
|
|
|
|
- * @param {boolean} [isDeep] Specify a deep clone.
|
|
|
|
|
- * @param {Function} [customizer] The function to customize cloning values.
|
|
|
|
|
- * @param {*} [thisArg] The `this` binding of `customizer`.
|
|
|
|
|
- * @returns {*} Returns the cloned value.
|
|
|
|
|
- * @example
|
|
|
|
|
- *
|
|
|
|
|
- * var users = [
|
|
|
|
|
- * { 'user': 'barney' },
|
|
|
|
|
- * { 'user': 'fred' }
|
|
|
|
|
- * ];
|
|
|
|
|
- *
|
|
|
|
|
- * var shallow = _.clone(users);
|
|
|
|
|
- * shallow[0] === users[0];
|
|
|
|
|
- * // => true
|
|
|
|
|
- *
|
|
|
|
|
- * var deep = _.clone(users, true);
|
|
|
|
|
- * deep[0] === users[0];
|
|
|
|
|
- * // => false
|
|
|
|
|
- *
|
|
|
|
|
- * // using a customizer callback
|
|
|
|
|
- * var el = _.clone(document.body, function(value) {
|
|
|
|
|
- * if (_.isElement(value)) {
|
|
|
|
|
- * return value.cloneNode(false);
|
|
|
|
|
- * }
|
|
|
|
|
- * });
|
|
|
|
|
- *
|
|
|
|
|
- * el === document.body
|
|
|
|
|
- * // => false
|
|
|
|
|
- * el.nodeName
|
|
|
|
|
- * // => BODY
|
|
|
|
|
- * el.childNodes.length;
|
|
|
|
|
- * // => 0
|
|
|
|
|
- */
|
|
|
|
|
- function clone(value, isDeep, customizer, thisArg) {
|
|
|
|
|
- if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) {
|
|
|
|
|
- isDeep = false;
|
|
|
|
|
- }
|
|
|
|
|
- else if (typeof isDeep == 'function') {
|
|
|
|
|
- thisArg = customizer;
|
|
|
|
|
- customizer = isDeep;
|
|
|
|
|
- isDeep = false;
|
|
|
|
|
- }
|
|
|
|
|
- return typeof customizer == 'function'
|
|
|
|
|
- ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 3))
|
|
|
|
|
- : baseClone(value, isDeep);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Checks if `value` is classified as 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) {
|
|
|
|
|
- return isObjectLike(value) && isArrayLike(value) &&
|
|
|
|
|
- hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Checks if `value` is classified as an `Array` object.
|
|
|
|
|
- *
|
|
|
|
|
- * @static
|
|
|
|
|
- * @memberOf _
|
|
|
|
|
- * @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(function() { return arguments; }());
|
|
|
|
|
- * // => false
|
|
|
|
|
- */
|
|
|
|
|
- var isArray = nativeIsArray || function(value) {
|
|
|
|
|
- return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Performs a deep comparison between two values to determine if they are
|
|
|
|
|
- * equivalent. If `customizer` is provided it's invoked to compare values.
|
|
|
|
|
- * If `customizer` returns `undefined` comparisons are handled by the method
|
|
|
|
|
- * instead. The `customizer` is bound to `thisArg` and invoked with up to
|
|
|
|
|
- * three arguments: (value, other [, index|key]).
|
|
|
|
|
- *
|
|
|
|
|
- * **Note:** This method supports comparing arrays, booleans, `Date` objects,
|
|
|
|
|
- * numbers, `Object` objects, regexes, and strings. Objects are compared by
|
|
|
|
|
- * their own, not inherited, enumerable properties. Functions and DOM nodes
|
|
|
|
|
- * are **not** supported. Provide a customizer function to extend support
|
|
|
|
|
- * for comparing other values.
|
|
|
|
|
- *
|
|
|
|
|
- * @static
|
|
|
|
|
- * @memberOf _
|
|
|
|
|
- * @alias eq
|
|
|
|
|
- * @category Lang
|
|
|
|
|
- * @param {*} value The value to compare.
|
|
|
|
|
- * @param {*} other The other value to compare.
|
|
|
|
|
- * @param {Function} [customizer] The function to customize value comparisons.
|
|
|
|
|
- * @param {*} [thisArg] The `this` binding of `customizer`.
|
|
|
|
|
- * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
|
|
|
- * @example
|
|
|
|
|
- *
|
|
|
|
|
- * var object = { 'user': 'fred' };
|
|
|
|
|
- * var other = { 'user': 'fred' };
|
|
|
|
|
- *
|
|
|
|
|
- * object == other;
|
|
|
|
|
- * // => false
|
|
|
|
|
- *
|
|
|
|
|
- * _.isEqual(object, other);
|
|
|
|
|
- * // => true
|
|
|
|
|
- *
|
|
|
|
|
- * // using a customizer callback
|
|
|
|
|
- * var array = ['hello', 'goodbye'];
|
|
|
|
|
- * var other = ['hi', 'goodbye'];
|
|
|
|
|
- *
|
|
|
|
|
- * _.isEqual(array, other, function(value, other) {
|
|
|
|
|
- * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) {
|
|
|
|
|
- * return true;
|
|
|
|
|
- * }
|
|
|
|
|
- * });
|
|
|
|
|
- * // => true
|
|
|
|
|
- */
|
|
|
|
|
- function isEqual(value, other, customizer, thisArg) {
|
|
|
|
|
- customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined;
|
|
|
|
|
- var result = customizer ? customizer(value, other) : undefined;
|
|
|
|
|
- return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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 older versions of Chrome and Safari which return 'function' for regexes
|
|
|
|
|
- // and Safari 8 which returns 'object' for typed array constructors.
|
|
|
|
|
- return isObject(value) && objToString.call(value) == funcTag;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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(1);
|
|
|
|
|
- * // => 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 a native function.
|
|
|
|
|
- *
|
|
|
|
|
- * @static
|
|
|
|
|
- * @memberOf _
|
|
|
|
|
- * @category Lang
|
|
|
|
|
- * @param {*} value The value to check.
|
|
|
|
|
- * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
|
|
|
|
|
- * @example
|
|
|
|
|
- *
|
|
|
|
|
- * _.isNative(Array.prototype.push);
|
|
|
|
|
- * // => true
|
|
|
|
|
- *
|
|
|
|
|
- * _.isNative(_);
|
|
|
|
|
- * // => false
|
|
|
|
|
- */
|
|
|
|
|
- function isNative(value) {
|
|
|
|
|
- if (value == null) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- if (isFunction(value)) {
|
|
|
|
|
- return reIsNative.test(fnToString.call(value));
|
|
|
|
|
- }
|
|
|
|
|
- return isObjectLike(value) && reIsHostCtor.test(value);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Checks if `value` is a plain object, that is, an object created by the
|
|
|
|
|
- * `Object` constructor or one with a `[[Prototype]]` of `null`.
|
|
|
|
|
- *
|
|
|
|
|
- * **Note:** This method assumes objects created by the `Object` constructor
|
|
|
|
|
- * have no inherited enumerable properties.
|
|
|
|
|
- *
|
|
|
|
|
- * @static
|
|
|
|
|
- * @memberOf _
|
|
|
|
|
- * @category Lang
|
|
|
|
|
- * @param {*} value The value to check.
|
|
|
|
|
- * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
|
|
|
|
|
- * @example
|
|
|
|
|
- *
|
|
|
|
|
- * function Foo() {
|
|
|
|
|
- * this.a = 1;
|
|
|
|
|
- * }
|
|
|
|
|
- *
|
|
|
|
|
- * _.isPlainObject(new Foo);
|
|
|
|
|
- * // => false
|
|
|
|
|
- *
|
|
|
|
|
- * _.isPlainObject([1, 2, 3]);
|
|
|
|
|
- * // => false
|
|
|
|
|
- *
|
|
|
|
|
- * _.isPlainObject({ 'x': 0, 'y': 0 });
|
|
|
|
|
- * // => true
|
|
|
|
|
- *
|
|
|
|
|
- * _.isPlainObject(Object.create(null));
|
|
|
|
|
- * // => true
|
|
|
|
|
- */
|
|
|
|
|
- function isPlainObject(value) {
|
|
|
|
|
- var Ctor;
|
|
|
|
|
-
|
|
|
|
|
- // Exit early for non `Object` objects.
|
|
|
|
|
- if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) ||
|
|
|
|
|
- (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
- // IE < 9 iterates inherited properties before own properties. If the first
|
|
|
|
|
- // iterated property is an object's own property then there are no inherited
|
|
|
|
|
- // enumerable properties.
|
|
|
|
|
- var result;
|
|
|
|
|
- // In most environments an object's own properties are iterated before
|
|
|
|
|
- // its inherited properties. If the last iterated property is an object's
|
|
|
|
|
- // own property then there are no inherited enumerable properties.
|
|
|
|
|
- baseForIn(value, function(subValue, key) {
|
|
|
|
|
- result = key;
|
|
|
|
|
- });
|
|
|
|
|
- return result === undefined || hasOwnProperty.call(value, result);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Checks if `value` is classified as a typed array.
|
|
|
|
|
- *
|
|
|
|
|
- * @static
|
|
|
|
|
- * @memberOf _
|
|
|
|
|
- * @category Lang
|
|
|
|
|
- * @param {*} value The value to check.
|
|
|
|
|
- * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
|
|
|
|
- * @example
|
|
|
|
|
- *
|
|
|
|
|
- * _.isTypedArray(new Uint8Array);
|
|
|
|
|
- * // => true
|
|
|
|
|
- *
|
|
|
|
|
- * _.isTypedArray([]);
|
|
|
|
|
- * // => false
|
|
|
|
|
- */
|
|
|
|
|
- function isTypedArray(value) {
|
|
|
|
|
- return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * Assigns own enumerable properties of source object(s) to the destination
|
|
|
|
|
- * object. Subsequent sources overwrite property assignments of previous sources.
|
|
|
|
|
- * If `customizer` is provided it's invoked to produce the assigned values.
|
|
|
|
|
- * The `customizer` is bound to `thisArg` and invoked with five arguments:
|
|
|
|
|
- * (objectValue, sourceValue, key, object, source).
|
|
|
|
|
- *
|
|
|
|
|
- * **Note:** This method mutates `object` and is based on
|
|
|
|
|
- * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).
|
|
|
|
|
- *
|
|
|
|
|
- * @static
|
|
|
|
|
- * @memberOf _
|
|
|
|
|
- * @alias extend
|
|
|
|
|
- * @category Object
|
|
|
|
|
- * @param {Object} object The destination object.
|
|
|
|
|
- * @param {...Object} [sources] The source objects.
|
|
|
|
|
- * @param {Function} [customizer] The function to customize assigned values.
|
|
|
|
|
- * @param {*} [thisArg] The `this` binding of `customizer`.
|
|
|
|
|
- * @returns {Object} Returns `object`.
|
|
|
|
|
- * @example
|
|
|
|
|
- *
|
|
|
|
|
- * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' });
|
|
|
|
|
- * // => { 'user': 'fred', 'age': 40 }
|
|
|
|
|
- *
|
|
|
|
|
- * // using a customizer callback
|
|
|
|
|
- * var defaults = _.partialRight(_.assign, function(value, other) {
|
|
|
|
|
- * return _.isUndefined(value) ? other : value;
|
|
|
|
|
- * });
|
|
|
|
|
- *
|
|
|
|
|
- * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
|
|
|
|
|
- * // => { 'user': 'barney', 'age': 36 }
|
|
|
|
|
- */
|
|
|
|
|
- var assign = createAssigner(function(object, source, customizer) {
|
|
|
|
|
- return customizer
|
|
|
|
|
- ? assignWith(object, source, customizer)
|
|
|
|
|
- : baseAssign(object, source);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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']
|
|
|
|
|
- */
|
|
|
|
|
- var keys = !nativeKeys ? shimKeys : function(object) {
|
|
|
|
|
- var Ctor = object == null ? undefined : object.constructor;
|
|
|
|
|
- if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
|
|
|
|
|
- (typeof object != 'function' && isArrayLike(object))) {
|
|
|
|
|
- return shimKeys(object);
|
|
|
|
|
- }
|
|
|
|
|
- return isObject(object) ? nativeKeys(object) : [];
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 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) {
|
|
|
|
|
- if (object == null) {
|
|
|
|
|
- return [];
|
|
|
|
|
- }
|
|
|
|
|
- if (!isObject(object)) {
|
|
|
|
|
- object = Object(object);
|
|
|
|
|
- }
|
|
|
|
|
- var length = object.length;
|
|
|
|
|
- length = (length && isLength(length) &&
|
|
|
|
|
- (isArray(object) || isArguments(object)) && length) || 0;
|
|
|
|
|
-
|
|
|
|
|
- var Ctor = object.constructor,
|
|
|
|
|
- index = -1,
|
|
|
|
|
- isProto = typeof Ctor == 'function' && Ctor.prototype === object,
|
|
|
|
|
- result = Array(length),
|
|
|
|
|
- skipIndexes = length > 0;
|
|
|
|
|
-
|
|
|
|
|
- while (++index < length) {
|
|
|
|
|
- result[index] = (index + '');
|
|
|
|
|
- }
|
|
|
|
|
- for (var key in object) {
|
|
|
|
|
- if (!(skipIndexes && isIndex(key, length)) &&
|
|
|
|
|
- !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
|
|
|
|
|
- result.push(key);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * This method returns the first argument provided to it.
|
|
|
|
|
- *
|
|
|
|
|
- * @static
|
|
|
|
|
- * @memberOf _
|
|
|
|
|
- * @category Utility
|
|
|
|
|
- * @param {*} value Any value.
|
|
|
|
|
- * @returns {*} Returns `value`.
|
|
|
|
|
- * @example
|
|
|
|
|
- *
|
|
|
|
|
- * var object = { 'user': 'fred' };
|
|
|
|
|
- *
|
|
|
|
|
- * _.identity(object) === object;
|
|
|
|
|
- * // => true
|
|
|
|
|
- */
|
|
|
|
|
- function identity(value) {
|
|
|
|
|
- return value;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- // Add functions that return wrapped values when chaining.
|
|
|
|
|
- lodash.assign = assign;
|
|
|
|
|
- lodash.keys = keys;
|
|
|
|
|
- lodash.keysIn = keysIn;
|
|
|
|
|
- lodash.restParam = restParam;
|
|
|
|
|
-
|
|
|
|
|
- // Add aliases.
|
|
|
|
|
- lodash.extend = assign;
|
|
|
|
|
-
|
|
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- // Add functions that return unwrapped values when chaining.
|
|
|
|
|
- lodash.clone = clone;
|
|
|
|
|
- lodash.identity = identity;
|
|
|
|
|
- lodash.isArguments = isArguments;
|
|
|
|
|
- lodash.isArray = isArray;
|
|
|
|
|
- lodash.isEqual = isEqual;
|
|
|
|
|
- lodash.isFunction = isFunction;
|
|
|
|
|
- lodash.isNative = isNative;
|
|
|
|
|
- lodash.isObject = isObject;
|
|
|
|
|
- lodash.isPlainObject = isPlainObject;
|
|
|
|
|
- lodash.isTypedArray = isTypedArray;
|
|
|
|
|
- lodash.last = last;
|
|
|
|
|
-
|
|
|
|
|
- // Add aliases.
|
|
|
|
|
- lodash.eq = isEqual;
|
|
|
|
|
-
|
|
|
|
|
- /*------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * The semantic version number.
|
|
|
|
|
- *
|
|
|
|
|
- * @static
|
|
|
|
|
- * @memberOf _
|
|
|
|
|
- * @type string
|
|
|
|
|
- */
|
|
|
|
|
- lodash.VERSION = VERSION;
|
|
|
|
|
-
|
|
|
|
|
- /*--------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
- // 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;
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-}.call(this));
|
|
|