index.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990
  1. /**
  2. * lodash (Custom Build) <https://lodash.com/>
  3. * Build: `lodash modularize exports="npm" -o ./`
  4. * Copyright jQuery Foundation and other contributors <https://jquery.org/>
  5. * Released under MIT license <https://lodash.com/license>
  6. * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
  7. * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  8. */
  9. /** Used as the `TypeError` message for "Functions" methods. */
  10. var FUNC_ERROR_TEXT = 'Expected a function';
  11. /** Used to stand-in for `undefined` hash values. */
  12. var HASH_UNDEFINED = '__lodash_hash_undefined__';
  13. /** Used as references for various `Number` constants. */
  14. var INFINITY = 1 / 0,
  15. MAX_SAFE_INTEGER = 9007199254740991;
  16. /** `Object#toString` result references. */
  17. var funcTag = '[object Function]',
  18. genTag = '[object GeneratorFunction]',
  19. symbolTag = '[object Symbol]';
  20. /** Used to match property names within property paths. */
  21. var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
  22. reIsPlainProp = /^\w*$/,
  23. reLeadingDot = /^\./,
  24. rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
  25. /**
  26. * Used to match `RegExp`
  27. * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
  28. */
  29. var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
  30. /** Used to match backslashes in property paths. */
  31. var reEscapeChar = /\\(\\)?/g;
  32. /** Used to detect host constructors (Safari). */
  33. var reIsHostCtor = /^\[object .+?Constructor\]$/;
  34. /** Used to detect unsigned integer values. */
  35. var reIsUint = /^(?:0|[1-9]\d*)$/;
  36. /** Detect free variable `global` from Node.js. */
  37. var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
  38. /** Detect free variable `self`. */
  39. var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  40. /** Used as a reference to the global object. */
  41. var root = freeGlobal || freeSelf || Function('return this')();
  42. /**
  43. * Gets the value at `key` of `object`.
  44. *
  45. * @private
  46. * @param {Object} [object] The object to query.
  47. * @param {string} key The key of the property to get.
  48. * @returns {*} Returns the property value.
  49. */
  50. function getValue(object, key) {
  51. return object == null ? undefined : object[key];
  52. }
  53. /**
  54. * Checks if `value` is a host object in IE < 9.
  55. *
  56. * @private
  57. * @param {*} value The value to check.
  58. * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
  59. */
  60. function isHostObject(value) {
  61. // Many host objects are `Object` objects that can coerce to strings
  62. // despite having improperly defined `toString` methods.
  63. var result = false;
  64. if (value != null && typeof value.toString != 'function') {
  65. try {
  66. result = !!(value + '');
  67. } catch (e) {}
  68. }
  69. return result;
  70. }
  71. /** Used for built-in method references. */
  72. var arrayProto = Array.prototype,
  73. funcProto = Function.prototype,
  74. objectProto = Object.prototype;
  75. /** Used to detect overreaching core-js shims. */
  76. var coreJsData = root['__core-js_shared__'];
  77. /** Used to detect methods masquerading as native. */
  78. var maskSrcKey = (function() {
  79. var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
  80. return uid ? ('Symbol(src)_1.' + uid) : '';
  81. }());
  82. /** Used to resolve the decompiled source of functions. */
  83. var funcToString = funcProto.toString;
  84. /** Used to check objects for own properties. */
  85. var hasOwnProperty = objectProto.hasOwnProperty;
  86. /**
  87. * Used to resolve the
  88. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  89. * of values.
  90. */
  91. var objectToString = objectProto.toString;
  92. /** Used to detect if a method is native. */
  93. var reIsNative = RegExp('^' +
  94. funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
  95. .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  96. );
  97. /** Built-in value references. */
  98. var Symbol = root.Symbol,
  99. splice = arrayProto.splice;
  100. /* Built-in method references that are verified to be native. */
  101. var Map = getNative(root, 'Map'),
  102. nativeCreate = getNative(Object, 'create');
  103. /** Used to convert symbols to primitives and strings. */
  104. var symbolProto = Symbol ? Symbol.prototype : undefined,
  105. symbolToString = symbolProto ? symbolProto.toString : undefined;
  106. /**
  107. * Creates a hash object.
  108. *
  109. * @private
  110. * @constructor
  111. * @param {Array} [entries] The key-value pairs to cache.
  112. */
  113. function Hash(entries) {
  114. var index = -1,
  115. length = entries ? entries.length : 0;
  116. this.clear();
  117. while (++index < length) {
  118. var entry = entries[index];
  119. this.set(entry[0], entry[1]);
  120. }
  121. }
  122. /**
  123. * Removes all key-value entries from the hash.
  124. *
  125. * @private
  126. * @name clear
  127. * @memberOf Hash
  128. */
  129. function hashClear() {
  130. this.__data__ = nativeCreate ? nativeCreate(null) : {};
  131. }
  132. /**
  133. * Removes `key` and its value from the hash.
  134. *
  135. * @private
  136. * @name delete
  137. * @memberOf Hash
  138. * @param {Object} hash The hash to modify.
  139. * @param {string} key The key of the value to remove.
  140. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  141. */
  142. function hashDelete(key) {
  143. return this.has(key) && delete this.__data__[key];
  144. }
  145. /**
  146. * Gets the hash value for `key`.
  147. *
  148. * @private
  149. * @name get
  150. * @memberOf Hash
  151. * @param {string} key The key of the value to get.
  152. * @returns {*} Returns the entry value.
  153. */
  154. function hashGet(key) {
  155. var data = this.__data__;
  156. if (nativeCreate) {
  157. var result = data[key];
  158. return result === HASH_UNDEFINED ? undefined : result;
  159. }
  160. return hasOwnProperty.call(data, key) ? data[key] : undefined;
  161. }
  162. /**
  163. * Checks if a hash value for `key` exists.
  164. *
  165. * @private
  166. * @name has
  167. * @memberOf Hash
  168. * @param {string} key The key of the entry to check.
  169. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  170. */
  171. function hashHas(key) {
  172. var data = this.__data__;
  173. return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
  174. }
  175. /**
  176. * Sets the hash `key` to `value`.
  177. *
  178. * @private
  179. * @name set
  180. * @memberOf Hash
  181. * @param {string} key The key of the value to set.
  182. * @param {*} value The value to set.
  183. * @returns {Object} Returns the hash instance.
  184. */
  185. function hashSet(key, value) {
  186. var data = this.__data__;
  187. data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
  188. return this;
  189. }
  190. // Add methods to `Hash`.
  191. Hash.prototype.clear = hashClear;
  192. Hash.prototype['delete'] = hashDelete;
  193. Hash.prototype.get = hashGet;
  194. Hash.prototype.has = hashHas;
  195. Hash.prototype.set = hashSet;
  196. /**
  197. * Creates an list cache object.
  198. *
  199. * @private
  200. * @constructor
  201. * @param {Array} [entries] The key-value pairs to cache.
  202. */
  203. function ListCache(entries) {
  204. var index = -1,
  205. length = entries ? entries.length : 0;
  206. this.clear();
  207. while (++index < length) {
  208. var entry = entries[index];
  209. this.set(entry[0], entry[1]);
  210. }
  211. }
  212. /**
  213. * Removes all key-value entries from the list cache.
  214. *
  215. * @private
  216. * @name clear
  217. * @memberOf ListCache
  218. */
  219. function listCacheClear() {
  220. this.__data__ = [];
  221. }
  222. /**
  223. * Removes `key` and its value from the list cache.
  224. *
  225. * @private
  226. * @name delete
  227. * @memberOf ListCache
  228. * @param {string} key The key of the value to remove.
  229. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  230. */
  231. function listCacheDelete(key) {
  232. var data = this.__data__,
  233. index = assocIndexOf(data, key);
  234. if (index < 0) {
  235. return false;
  236. }
  237. var lastIndex = data.length - 1;
  238. if (index == lastIndex) {
  239. data.pop();
  240. } else {
  241. splice.call(data, index, 1);
  242. }
  243. return true;
  244. }
  245. /**
  246. * Gets the list cache value for `key`.
  247. *
  248. * @private
  249. * @name get
  250. * @memberOf ListCache
  251. * @param {string} key The key of the value to get.
  252. * @returns {*} Returns the entry value.
  253. */
  254. function listCacheGet(key) {
  255. var data = this.__data__,
  256. index = assocIndexOf(data, key);
  257. return index < 0 ? undefined : data[index][1];
  258. }
  259. /**
  260. * Checks if a list cache value for `key` exists.
  261. *
  262. * @private
  263. * @name has
  264. * @memberOf ListCache
  265. * @param {string} key The key of the entry to check.
  266. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  267. */
  268. function listCacheHas(key) {
  269. return assocIndexOf(this.__data__, key) > -1;
  270. }
  271. /**
  272. * Sets the list cache `key` to `value`.
  273. *
  274. * @private
  275. * @name set
  276. * @memberOf ListCache
  277. * @param {string} key The key of the value to set.
  278. * @param {*} value The value to set.
  279. * @returns {Object} Returns the list cache instance.
  280. */
  281. function listCacheSet(key, value) {
  282. var data = this.__data__,
  283. index = assocIndexOf(data, key);
  284. if (index < 0) {
  285. data.push([key, value]);
  286. } else {
  287. data[index][1] = value;
  288. }
  289. return this;
  290. }
  291. // Add methods to `ListCache`.
  292. ListCache.prototype.clear = listCacheClear;
  293. ListCache.prototype['delete'] = listCacheDelete;
  294. ListCache.prototype.get = listCacheGet;
  295. ListCache.prototype.has = listCacheHas;
  296. ListCache.prototype.set = listCacheSet;
  297. /**
  298. * Creates a map cache object to store key-value pairs.
  299. *
  300. * @private
  301. * @constructor
  302. * @param {Array} [entries] The key-value pairs to cache.
  303. */
  304. function MapCache(entries) {
  305. var index = -1,
  306. length = entries ? entries.length : 0;
  307. this.clear();
  308. while (++index < length) {
  309. var entry = entries[index];
  310. this.set(entry[0], entry[1]);
  311. }
  312. }
  313. /**
  314. * Removes all key-value entries from the map.
  315. *
  316. * @private
  317. * @name clear
  318. * @memberOf MapCache
  319. */
  320. function mapCacheClear() {
  321. this.__data__ = {
  322. 'hash': new Hash,
  323. 'map': new (Map || ListCache),
  324. 'string': new Hash
  325. };
  326. }
  327. /**
  328. * Removes `key` and its value from the map.
  329. *
  330. * @private
  331. * @name delete
  332. * @memberOf MapCache
  333. * @param {string} key The key of the value to remove.
  334. * @returns {boolean} Returns `true` if the entry was removed, else `false`.
  335. */
  336. function mapCacheDelete(key) {
  337. return getMapData(this, key)['delete'](key);
  338. }
  339. /**
  340. * Gets the map value for `key`.
  341. *
  342. * @private
  343. * @name get
  344. * @memberOf MapCache
  345. * @param {string} key The key of the value to get.
  346. * @returns {*} Returns the entry value.
  347. */
  348. function mapCacheGet(key) {
  349. return getMapData(this, key).get(key);
  350. }
  351. /**
  352. * Checks if a map value for `key` exists.
  353. *
  354. * @private
  355. * @name has
  356. * @memberOf MapCache
  357. * @param {string} key The key of the entry to check.
  358. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
  359. */
  360. function mapCacheHas(key) {
  361. return getMapData(this, key).has(key);
  362. }
  363. /**
  364. * Sets the map `key` to `value`.
  365. *
  366. * @private
  367. * @name set
  368. * @memberOf MapCache
  369. * @param {string} key The key of the value to set.
  370. * @param {*} value The value to set.
  371. * @returns {Object} Returns the map cache instance.
  372. */
  373. function mapCacheSet(key, value) {
  374. getMapData(this, key).set(key, value);
  375. return this;
  376. }
  377. // Add methods to `MapCache`.
  378. MapCache.prototype.clear = mapCacheClear;
  379. MapCache.prototype['delete'] = mapCacheDelete;
  380. MapCache.prototype.get = mapCacheGet;
  381. MapCache.prototype.has = mapCacheHas;
  382. MapCache.prototype.set = mapCacheSet;
  383. /**
  384. * Assigns `value` to `key` of `object` if the existing value is not equivalent
  385. * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  386. * for equality comparisons.
  387. *
  388. * @private
  389. * @param {Object} object The object to modify.
  390. * @param {string} key The key of the property to assign.
  391. * @param {*} value The value to assign.
  392. */
  393. function assignValue(object, key, value) {
  394. var objValue = object[key];
  395. if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
  396. (value === undefined && !(key in object))) {
  397. object[key] = value;
  398. }
  399. }
  400. /**
  401. * Gets the index at which the `key` is found in `array` of key-value pairs.
  402. *
  403. * @private
  404. * @param {Array} array The array to inspect.
  405. * @param {*} key The key to search for.
  406. * @returns {number} Returns the index of the matched value, else `-1`.
  407. */
  408. function assocIndexOf(array, key) {
  409. var length = array.length;
  410. while (length--) {
  411. if (eq(array[length][0], key)) {
  412. return length;
  413. }
  414. }
  415. return -1;
  416. }
  417. /**
  418. * The base implementation of `_.isNative` without bad shim checks.
  419. *
  420. * @private
  421. * @param {*} value The value to check.
  422. * @returns {boolean} Returns `true` if `value` is a native function,
  423. * else `false`.
  424. */
  425. function baseIsNative(value) {
  426. if (!isObject(value) || isMasked(value)) {
  427. return false;
  428. }
  429. var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
  430. return pattern.test(toSource(value));
  431. }
  432. /**
  433. * The base implementation of `_.set`.
  434. *
  435. * @private
  436. * @param {Object} object The object to modify.
  437. * @param {Array|string} path The path of the property to set.
  438. * @param {*} value The value to set.
  439. * @param {Function} [customizer] The function to customize path creation.
  440. * @returns {Object} Returns `object`.
  441. */
  442. function baseSet(object, path, value, customizer) {
  443. if (!isObject(object)) {
  444. return object;
  445. }
  446. path = isKey(path, object) ? [path] : castPath(path);
  447. var index = -1,
  448. length = path.length,
  449. lastIndex = length - 1,
  450. nested = object;
  451. while (nested != null && ++index < length) {
  452. var key = toKey(path[index]),
  453. newValue = value;
  454. if (index != lastIndex) {
  455. var objValue = nested[key];
  456. newValue = customizer ? customizer(objValue, key, nested) : undefined;
  457. if (newValue === undefined) {
  458. newValue = isObject(objValue)
  459. ? objValue
  460. : (isIndex(path[index + 1]) ? [] : {});
  461. }
  462. }
  463. assignValue(nested, key, newValue);
  464. nested = nested[key];
  465. }
  466. return object;
  467. }
  468. /**
  469. * The base implementation of `_.toString` which doesn't convert nullish
  470. * values to empty strings.
  471. *
  472. * @private
  473. * @param {*} value The value to process.
  474. * @returns {string} Returns the string.
  475. */
  476. function baseToString(value) {
  477. // Exit early for strings to avoid a performance hit in some environments.
  478. if (typeof value == 'string') {
  479. return value;
  480. }
  481. if (isSymbol(value)) {
  482. return symbolToString ? symbolToString.call(value) : '';
  483. }
  484. var result = (value + '');
  485. return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
  486. }
  487. /**
  488. * Casts `value` to a path array if it's not one.
  489. *
  490. * @private
  491. * @param {*} value The value to inspect.
  492. * @returns {Array} Returns the cast property path array.
  493. */
  494. function castPath(value) {
  495. return isArray(value) ? value : stringToPath(value);
  496. }
  497. /**
  498. * Gets the data for `map`.
  499. *
  500. * @private
  501. * @param {Object} map The map to query.
  502. * @param {string} key The reference key.
  503. * @returns {*} Returns the map data.
  504. */
  505. function getMapData(map, key) {
  506. var data = map.__data__;
  507. return isKeyable(key)
  508. ? data[typeof key == 'string' ? 'string' : 'hash']
  509. : data.map;
  510. }
  511. /**
  512. * Gets the native function at `key` of `object`.
  513. *
  514. * @private
  515. * @param {Object} object The object to query.
  516. * @param {string} key The key of the method to get.
  517. * @returns {*} Returns the function if it's native, else `undefined`.
  518. */
  519. function getNative(object, key) {
  520. var value = getValue(object, key);
  521. return baseIsNative(value) ? value : undefined;
  522. }
  523. /**
  524. * Checks if `value` is a valid array-like index.
  525. *
  526. * @private
  527. * @param {*} value The value to check.
  528. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
  529. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
  530. */
  531. function isIndex(value, length) {
  532. length = length == null ? MAX_SAFE_INTEGER : length;
  533. return !!length &&
  534. (typeof value == 'number' || reIsUint.test(value)) &&
  535. (value > -1 && value % 1 == 0 && value < length);
  536. }
  537. /**
  538. * Checks if `value` is a property name and not a property path.
  539. *
  540. * @private
  541. * @param {*} value The value to check.
  542. * @param {Object} [object] The object to query keys on.
  543. * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
  544. */
  545. function isKey(value, object) {
  546. if (isArray(value)) {
  547. return false;
  548. }
  549. var type = typeof value;
  550. if (type == 'number' || type == 'symbol' || type == 'boolean' ||
  551. value == null || isSymbol(value)) {
  552. return true;
  553. }
  554. return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
  555. (object != null && value in Object(object));
  556. }
  557. /**
  558. * Checks if `value` is suitable for use as unique object key.
  559. *
  560. * @private
  561. * @param {*} value The value to check.
  562. * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
  563. */
  564. function isKeyable(value) {
  565. var type = typeof value;
  566. return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
  567. ? (value !== '__proto__')
  568. : (value === null);
  569. }
  570. /**
  571. * Checks if `func` has its source masked.
  572. *
  573. * @private
  574. * @param {Function} func The function to check.
  575. * @returns {boolean} Returns `true` if `func` is masked, else `false`.
  576. */
  577. function isMasked(func) {
  578. return !!maskSrcKey && (maskSrcKey in func);
  579. }
  580. /**
  581. * Converts `string` to a property path array.
  582. *
  583. * @private
  584. * @param {string} string The string to convert.
  585. * @returns {Array} Returns the property path array.
  586. */
  587. var stringToPath = memoize(function(string) {
  588. string = toString(string);
  589. var result = [];
  590. if (reLeadingDot.test(string)) {
  591. result.push('');
  592. }
  593. string.replace(rePropName, function(match, number, quote, string) {
  594. result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
  595. });
  596. return result;
  597. });
  598. /**
  599. * Converts `value` to a string key if it's not a string or symbol.
  600. *
  601. * @private
  602. * @param {*} value The value to inspect.
  603. * @returns {string|symbol} Returns the key.
  604. */
  605. function toKey(value) {
  606. if (typeof value == 'string' || isSymbol(value)) {
  607. return value;
  608. }
  609. var result = (value + '');
  610. return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
  611. }
  612. /**
  613. * Converts `func` to its source code.
  614. *
  615. * @private
  616. * @param {Function} func The function to process.
  617. * @returns {string} Returns the source code.
  618. */
  619. function toSource(func) {
  620. if (func != null) {
  621. try {
  622. return funcToString.call(func);
  623. } catch (e) {}
  624. try {
  625. return (func + '');
  626. } catch (e) {}
  627. }
  628. return '';
  629. }
  630. /**
  631. * Creates a function that memoizes the result of `func`. If `resolver` is
  632. * provided, it determines the cache key for storing the result based on the
  633. * arguments provided to the memoized function. By default, the first argument
  634. * provided to the memoized function is used as the map cache key. The `func`
  635. * is invoked with the `this` binding of the memoized function.
  636. *
  637. * **Note:** The cache is exposed as the `cache` property on the memoized
  638. * function. Its creation may be customized by replacing the `_.memoize.Cache`
  639. * constructor with one whose instances implement the
  640. * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
  641. * method interface of `delete`, `get`, `has`, and `set`.
  642. *
  643. * @static
  644. * @memberOf _
  645. * @since 0.1.0
  646. * @category Function
  647. * @param {Function} func The function to have its output memoized.
  648. * @param {Function} [resolver] The function to resolve the cache key.
  649. * @returns {Function} Returns the new memoized function.
  650. * @example
  651. *
  652. * var object = { 'a': 1, 'b': 2 };
  653. * var other = { 'c': 3, 'd': 4 };
  654. *
  655. * var values = _.memoize(_.values);
  656. * values(object);
  657. * // => [1, 2]
  658. *
  659. * values(other);
  660. * // => [3, 4]
  661. *
  662. * object.a = 2;
  663. * values(object);
  664. * // => [1, 2]
  665. *
  666. * // Modify the result cache.
  667. * values.cache.set(object, ['a', 'b']);
  668. * values(object);
  669. * // => ['a', 'b']
  670. *
  671. * // Replace `_.memoize.Cache`.
  672. * _.memoize.Cache = WeakMap;
  673. */
  674. function memoize(func, resolver) {
  675. if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
  676. throw new TypeError(FUNC_ERROR_TEXT);
  677. }
  678. var memoized = function() {
  679. var args = arguments,
  680. key = resolver ? resolver.apply(this, args) : args[0],
  681. cache = memoized.cache;
  682. if (cache.has(key)) {
  683. return cache.get(key);
  684. }
  685. var result = func.apply(this, args);
  686. memoized.cache = cache.set(key, result);
  687. return result;
  688. };
  689. memoized.cache = new (memoize.Cache || MapCache);
  690. return memoized;
  691. }
  692. // Assign cache to `_.memoize`.
  693. memoize.Cache = MapCache;
  694. /**
  695. * Performs a
  696. * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
  697. * comparison between two values to determine if they are equivalent.
  698. *
  699. * @static
  700. * @memberOf _
  701. * @since 4.0.0
  702. * @category Lang
  703. * @param {*} value The value to compare.
  704. * @param {*} other The other value to compare.
  705. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  706. * @example
  707. *
  708. * var object = { 'a': 1 };
  709. * var other = { 'a': 1 };
  710. *
  711. * _.eq(object, object);
  712. * // => true
  713. *
  714. * _.eq(object, other);
  715. * // => false
  716. *
  717. * _.eq('a', 'a');
  718. * // => true
  719. *
  720. * _.eq('a', Object('a'));
  721. * // => false
  722. *
  723. * _.eq(NaN, NaN);
  724. * // => true
  725. */
  726. function eq(value, other) {
  727. return value === other || (value !== value && other !== other);
  728. }
  729. /**
  730. * Checks if `value` is classified as an `Array` object.
  731. *
  732. * @static
  733. * @memberOf _
  734. * @since 0.1.0
  735. * @category Lang
  736. * @param {*} value The value to check.
  737. * @returns {boolean} Returns `true` if `value` is an array, else `false`.
  738. * @example
  739. *
  740. * _.isArray([1, 2, 3]);
  741. * // => true
  742. *
  743. * _.isArray(document.body.children);
  744. * // => false
  745. *
  746. * _.isArray('abc');
  747. * // => false
  748. *
  749. * _.isArray(_.noop);
  750. * // => false
  751. */
  752. var isArray = Array.isArray;
  753. /**
  754. * Checks if `value` is classified as a `Function` object.
  755. *
  756. * @static
  757. * @memberOf _
  758. * @since 0.1.0
  759. * @category Lang
  760. * @param {*} value The value to check.
  761. * @returns {boolean} Returns `true` if `value` is a function, else `false`.
  762. * @example
  763. *
  764. * _.isFunction(_);
  765. * // => true
  766. *
  767. * _.isFunction(/abc/);
  768. * // => false
  769. */
  770. function isFunction(value) {
  771. // The use of `Object#toString` avoids issues with the `typeof` operator
  772. // in Safari 8-9 which returns 'object' for typed array and other constructors.
  773. var tag = isObject(value) ? objectToString.call(value) : '';
  774. return tag == funcTag || tag == genTag;
  775. }
  776. /**
  777. * Checks if `value` is the
  778. * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
  779. * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  780. *
  781. * @static
  782. * @memberOf _
  783. * @since 0.1.0
  784. * @category Lang
  785. * @param {*} value The value to check.
  786. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  787. * @example
  788. *
  789. * _.isObject({});
  790. * // => true
  791. *
  792. * _.isObject([1, 2, 3]);
  793. * // => true
  794. *
  795. * _.isObject(_.noop);
  796. * // => true
  797. *
  798. * _.isObject(null);
  799. * // => false
  800. */
  801. function isObject(value) {
  802. var type = typeof value;
  803. return !!value && (type == 'object' || type == 'function');
  804. }
  805. /**
  806. * Checks if `value` is object-like. A value is object-like if it's not `null`
  807. * and has a `typeof` result of "object".
  808. *
  809. * @static
  810. * @memberOf _
  811. * @since 4.0.0
  812. * @category Lang
  813. * @param {*} value The value to check.
  814. * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
  815. * @example
  816. *
  817. * _.isObjectLike({});
  818. * // => true
  819. *
  820. * _.isObjectLike([1, 2, 3]);
  821. * // => true
  822. *
  823. * _.isObjectLike(_.noop);
  824. * // => false
  825. *
  826. * _.isObjectLike(null);
  827. * // => false
  828. */
  829. function isObjectLike(value) {
  830. return !!value && typeof value == 'object';
  831. }
  832. /**
  833. * Checks if `value` is classified as a `Symbol` primitive or object.
  834. *
  835. * @static
  836. * @memberOf _
  837. * @since 4.0.0
  838. * @category Lang
  839. * @param {*} value The value to check.
  840. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
  841. * @example
  842. *
  843. * _.isSymbol(Symbol.iterator);
  844. * // => true
  845. *
  846. * _.isSymbol('abc');
  847. * // => false
  848. */
  849. function isSymbol(value) {
  850. return typeof value == 'symbol' ||
  851. (isObjectLike(value) && objectToString.call(value) == symbolTag);
  852. }
  853. /**
  854. * Converts `value` to a string. An empty string is returned for `null`
  855. * and `undefined` values. The sign of `-0` is preserved.
  856. *
  857. * @static
  858. * @memberOf _
  859. * @since 4.0.0
  860. * @category Lang
  861. * @param {*} value The value to process.
  862. * @returns {string} Returns the string.
  863. * @example
  864. *
  865. * _.toString(null);
  866. * // => ''
  867. *
  868. * _.toString(-0);
  869. * // => '-0'
  870. *
  871. * _.toString([1, 2, 3]);
  872. * // => '1,2,3'
  873. */
  874. function toString(value) {
  875. return value == null ? '' : baseToString(value);
  876. }
  877. /**
  878. * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
  879. * it's created. Arrays are created for missing index properties while objects
  880. * are created for all other missing properties. Use `_.setWith` to customize
  881. * `path` creation.
  882. *
  883. * **Note:** This method mutates `object`.
  884. *
  885. * @static
  886. * @memberOf _
  887. * @since 3.7.0
  888. * @category Object
  889. * @param {Object} object The object to modify.
  890. * @param {Array|string} path The path of the property to set.
  891. * @param {*} value The value to set.
  892. * @returns {Object} Returns `object`.
  893. * @example
  894. *
  895. * var object = { 'a': [{ 'b': { 'c': 3 } }] };
  896. *
  897. * _.set(object, 'a[0].b.c', 4);
  898. * console.log(object.a[0].b.c);
  899. * // => 4
  900. *
  901. * _.set(object, ['x', '0', 'y', 'z'], 5);
  902. * console.log(object.x[0].y.z);
  903. * // => 5
  904. */
  905. function set(object, path, value) {
  906. return object == null ? object : baseSet(object, path, value);
  907. }
  908. module.exports = set;