PageRenderTime 86ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/files/lodash/2.4.2/lodash.compat.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 1509 lines | 806 code | 144 blank | 559 comment | 294 complexity | 0b0029a5af28ef25fe8b46afe5979981 MD5 | raw file
  1. /**
  2. * @license
  3. * Lo-Dash 2.4.2 (Custom Build) <https://lodash.com/>
  4. * Build: `lodash -o ./dist/lodash.compat.js`
  5. * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
  6. * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
  7. * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  8. * Available under MIT license <https://lodash.com/license>
  9. */
  10. ;(function() {
  11. /** Used as a safe reference for `undefined` in pre ES5 environments */
  12. var undefined;
  13. /** Used to pool arrays and objects used internally */
  14. var arrayPool = [],
  15. objectPool = [];
  16. /** Used to generate unique IDs */
  17. var idCounter = 0;
  18. /** Used internally to indicate various things */
  19. var indicatorObject = {};
  20. /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
  21. var keyPrefix = +new Date + '';
  22. /** Used as the size when optimizations are enabled for large arrays */
  23. var largeArraySize = 75;
  24. /** Used as the max size of the `arrayPool` and `objectPool` */
  25. var maxPoolSize = 40;
  26. /** Used to detect and test whitespace */
  27. var whitespace = (
  28. // whitespace
  29. ' \t\x0B\f\xA0\ufeff' +
  30. // line terminators
  31. '\n\r\u2028\u2029' +
  32. // unicode category "Zs" space separators
  33. '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
  34. );
  35. /** Used to match empty string literals in compiled template source */
  36. var reEmptyStringLeading = /\b__p \+= '';/g,
  37. reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
  38. reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
  39. /**
  40. * Used to match ES6 template delimiters
  41. * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
  42. */
  43. var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
  44. /** Used to match regexp flags from their coerced string values */
  45. var reFlags = /\w*$/;
  46. /** Used to detected named functions */
  47. var reFuncName = /^\s*function[ \n\r\t]+\w/;
  48. /** Used to match "interpolate" template delimiters */
  49. var reInterpolate = /<%=([\s\S]+?)%>/g;
  50. /** Used to match leading whitespace and zeros to be removed */
  51. var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
  52. /** Used to ensure capturing order of template delimiters */
  53. var reNoMatch = /($^)/;
  54. /** Used to detect functions containing a `this` reference */
  55. var reThis = /\bthis\b/;
  56. /** Used to match unescaped characters in compiled string literals */
  57. var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
  58. /** Used to assign default `context` object properties */
  59. var contextProps = [
  60. 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object',
  61. 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
  62. 'parseInt', 'setTimeout'
  63. ];
  64. /** Used to fix the JScript [[DontEnum]] bug */
  65. var shadowedProps = [
  66. 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
  67. 'toLocaleString', 'toString', 'valueOf'
  68. ];
  69. /** Used to make template sourceURLs easier to identify */
  70. var templateCounter = 0;
  71. /** `Object#toString` result shortcuts */
  72. var argsClass = '[object Arguments]',
  73. arrayClass = '[object Array]',
  74. boolClass = '[object Boolean]',
  75. dateClass = '[object Date]',
  76. errorClass = '[object Error]',
  77. funcClass = '[object Function]',
  78. numberClass = '[object Number]',
  79. objectClass = '[object Object]',
  80. regexpClass = '[object RegExp]',
  81. stringClass = '[object String]';
  82. /** Used to identify object classifications that `_.clone` supports */
  83. var cloneableClasses = {};
  84. cloneableClasses[funcClass] = false;
  85. cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
  86. cloneableClasses[boolClass] = cloneableClasses[dateClass] =
  87. cloneableClasses[numberClass] = cloneableClasses[objectClass] =
  88. cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
  89. /** Used as an internal `_.debounce` options object */
  90. var debounceOptions = {
  91. 'leading': false,
  92. 'maxWait': 0,
  93. 'trailing': false
  94. };
  95. /** Used as the property descriptor for `__bindData__` */
  96. var descriptor = {
  97. 'configurable': false,
  98. 'enumerable': false,
  99. 'value': null,
  100. 'writable': false
  101. };
  102. /** Used as the data object for `iteratorTemplate` */
  103. var iteratorData = {
  104. 'args': '',
  105. 'array': null,
  106. 'bottom': '',
  107. 'firstArg': '',
  108. 'init': '',
  109. 'keys': null,
  110. 'loop': '',
  111. 'shadowedProps': null,
  112. 'support': null,
  113. 'top': '',
  114. 'useHas': false
  115. };
  116. /** Used to determine if values are of the language type Object */
  117. var objectTypes = {
  118. 'boolean': false,
  119. 'function': true,
  120. 'object': true,
  121. 'number': false,
  122. 'string': false,
  123. 'undefined': false
  124. };
  125. /** Used to escape characters for inclusion in compiled string literals */
  126. var stringEscapes = {
  127. '\\': '\\',
  128. "'": "'",
  129. '\n': 'n',
  130. '\r': 'r',
  131. '\t': 't',
  132. '\u2028': 'u2028',
  133. '\u2029': 'u2029'
  134. };
  135. /** Used as a reference to the global object */
  136. var root = (objectTypes[typeof window] && window) || this;
  137. /** Detect free variable `exports` */
  138. var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
  139. /** Detect free variable `module` */
  140. var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
  141. /** Detect the popular CommonJS extension `module.exports` */
  142. var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
  143. /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
  144. var freeGlobal = objectTypes[typeof global] && global;
  145. if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
  146. root = freeGlobal;
  147. }
  148. /*--------------------------------------------------------------------------*/
  149. /**
  150. * The base implementation of `_.indexOf` without support for binary searches
  151. * or `fromIndex` constraints.
  152. *
  153. * @private
  154. * @param {Array} array The array to search.
  155. * @param {*} value The value to search for.
  156. * @param {number} [fromIndex=0] The index to search from.
  157. * @returns {number} Returns the index of the matched value or `-1`.
  158. */
  159. function baseIndexOf(array, value, fromIndex) {
  160. var index = (fromIndex || 0) - 1,
  161. length = array ? array.length : 0;
  162. while (++index < length) {
  163. if (array[index] === value) {
  164. return index;
  165. }
  166. }
  167. return -1;
  168. }
  169. /**
  170. * An implementation of `_.contains` for cache objects that mimics the return
  171. * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
  172. *
  173. * @private
  174. * @param {Object} cache The cache object to inspect.
  175. * @param {*} value The value to search for.
  176. * @returns {number} Returns `0` if `value` is found, else `-1`.
  177. */
  178. function cacheIndexOf(cache, value) {
  179. var type = typeof value;
  180. cache = cache.cache;
  181. if (type == 'boolean' || value == null) {
  182. return cache[value] ? 0 : -1;
  183. }
  184. if (type != 'number' && type != 'string') {
  185. type = 'object';
  186. }
  187. var key = type == 'number' ? value : keyPrefix + value;
  188. cache = (cache = cache[type]) && cache[key];
  189. return type == 'object'
  190. ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
  191. : (cache ? 0 : -1);
  192. }
  193. /**
  194. * Adds a given value to the corresponding cache object.
  195. *
  196. * @private
  197. * @param {*} value The value to add to the cache.
  198. */
  199. function cachePush(value) {
  200. var cache = this.cache,
  201. type = typeof value;
  202. if (type == 'boolean' || value == null) {
  203. cache[value] = true;
  204. } else {
  205. if (type != 'number' && type != 'string') {
  206. type = 'object';
  207. }
  208. var key = type == 'number' ? value : keyPrefix + value,
  209. typeCache = cache[type] || (cache[type] = {});
  210. if (type == 'object') {
  211. (typeCache[key] || (typeCache[key] = [])).push(value);
  212. } else {
  213. typeCache[key] = true;
  214. }
  215. }
  216. }
  217. /**
  218. * Used by `_.max` and `_.min` as the default callback when a given
  219. * collection is a string value.
  220. *
  221. * @private
  222. * @param {string} value The character to inspect.
  223. * @returns {number} Returns the code unit of given character.
  224. */
  225. function charAtCallback(value) {
  226. return value.charCodeAt(0);
  227. }
  228. /**
  229. * Used by `sortBy` to compare transformed `collection` elements, stable sorting
  230. * them in ascending order.
  231. *
  232. * @private
  233. * @param {Object} a The object to compare to `b`.
  234. * @param {Object} b The object to compare to `a`.
  235. * @returns {number} Returns the sort order indicator of `1` or `-1`.
  236. */
  237. function compareAscending(a, b) {
  238. var ac = a.criteria,
  239. bc = b.criteria,
  240. index = -1,
  241. length = ac.length;
  242. while (++index < length) {
  243. var value = ac[index],
  244. other = bc[index];
  245. if (value !== other) {
  246. if (value > other || typeof value == 'undefined') {
  247. return 1;
  248. }
  249. if (value < other || typeof other == 'undefined') {
  250. return -1;
  251. }
  252. }
  253. }
  254. // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
  255. // that causes it, under certain circumstances, to return the same value for
  256. // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
  257. //
  258. // This also ensures a stable sort in V8 and other engines.
  259. // See http://code.google.com/p/v8/issues/detail?id=90
  260. return a.index - b.index;
  261. }
  262. /**
  263. * Creates a cache object to optimize linear searches of large arrays.
  264. *
  265. * @private
  266. * @param {Array} [array=[]] The array to search.
  267. * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
  268. */
  269. function createCache(array) {
  270. var index = -1,
  271. length = array.length,
  272. first = array[0],
  273. mid = array[(length / 2) | 0],
  274. last = array[length - 1];
  275. if (first && typeof first == 'object' &&
  276. mid && typeof mid == 'object' && last && typeof last == 'object') {
  277. return false;
  278. }
  279. var cache = getObject();
  280. cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
  281. var result = getObject();
  282. result.array = array;
  283. result.cache = cache;
  284. result.push = cachePush;
  285. while (++index < length) {
  286. result.push(array[index]);
  287. }
  288. return result;
  289. }
  290. /**
  291. * Used by `template` to escape characters for inclusion in compiled
  292. * string literals.
  293. *
  294. * @private
  295. * @param {string} match The matched character to escape.
  296. * @returns {string} Returns the escaped character.
  297. */
  298. function escapeStringChar(match) {
  299. return '\\' + stringEscapes[match];
  300. }
  301. /**
  302. * Gets an array from the array pool or creates a new one if the pool is empty.
  303. *
  304. * @private
  305. * @returns {Array} The array from the pool.
  306. */
  307. function getArray() {
  308. return arrayPool.pop() || [];
  309. }
  310. /**
  311. * Gets an object from the object pool or creates a new one if the pool is empty.
  312. *
  313. * @private
  314. * @returns {Object} The object from the pool.
  315. */
  316. function getObject() {
  317. return objectPool.pop() || {
  318. 'array': null,
  319. 'cache': null,
  320. 'criteria': null,
  321. 'false': false,
  322. 'index': 0,
  323. 'null': false,
  324. 'number': null,
  325. 'object': null,
  326. 'push': null,
  327. 'string': null,
  328. 'true': false,
  329. 'undefined': false,
  330. 'value': null
  331. };
  332. }
  333. /**
  334. * Checks if `value` is a DOM node in IE < 9.
  335. *
  336. * @private
  337. * @param {*} value The value to check.
  338. * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`.
  339. */
  340. function isNode(value) {
  341. // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
  342. // methods that are `typeof` "string" and still can coerce nodes to strings
  343. return typeof value.toString != 'function' && typeof (value + '') == 'string';
  344. }
  345. /**
  346. * Releases the given array back to the array pool.
  347. *
  348. * @private
  349. * @param {Array} [array] The array to release.
  350. */
  351. function releaseArray(array) {
  352. array.length = 0;
  353. if (arrayPool.length < maxPoolSize) {
  354. arrayPool.push(array);
  355. }
  356. }
  357. /**
  358. * Releases the given object back to the object pool.
  359. *
  360. * @private
  361. * @param {Object} [object] The object to release.
  362. */
  363. function releaseObject(object) {
  364. var cache = object.cache;
  365. if (cache) {
  366. releaseObject(cache);
  367. }
  368. object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
  369. if (objectPool.length < maxPoolSize) {
  370. objectPool.push(object);
  371. }
  372. }
  373. /**
  374. * Slices the `collection` from the `start` index up to, but not including,
  375. * the `end` index.
  376. *
  377. * Note: This function is used instead of `Array#slice` to support node lists
  378. * in IE < 9 and to ensure dense arrays are returned.
  379. *
  380. * @private
  381. * @param {Array|Object|string} collection The collection to slice.
  382. * @param {number} start The start index.
  383. * @param {number} end The end index.
  384. * @returns {Array} Returns the new array.
  385. */
  386. function slice(array, start, end) {
  387. start || (start = 0);
  388. if (typeof end == 'undefined') {
  389. end = array ? array.length : 0;
  390. }
  391. var index = -1,
  392. length = end - start || 0,
  393. result = Array(length < 0 ? 0 : length);
  394. while (++index < length) {
  395. result[index] = array[start + index];
  396. }
  397. return result;
  398. }
  399. /*--------------------------------------------------------------------------*/
  400. /**
  401. * Create a new `lodash` function using the given context object.
  402. *
  403. * @static
  404. * @memberOf _
  405. * @category Utilities
  406. * @param {Object} [context=root] The context object.
  407. * @returns {Function} Returns the `lodash` function.
  408. */
  409. function runInContext(context) {
  410. // Avoid issues with some ES3 environments that attempt to use values, named
  411. // after built-in constructors like `Object`, for the creation of literals.
  412. // ES5 clears this up by stating that literals must use built-in constructors.
  413. // See http://es5.github.io/#x11.1.5.
  414. context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
  415. /** Native constructor references */
  416. var Array = context.Array,
  417. Boolean = context.Boolean,
  418. Date = context.Date,
  419. Error = context.Error,
  420. Function = context.Function,
  421. Math = context.Math,
  422. Number = context.Number,
  423. Object = context.Object,
  424. RegExp = context.RegExp,
  425. String = context.String,
  426. TypeError = context.TypeError;
  427. /**
  428. * Used for `Array` method references.
  429. *
  430. * Normally `Array.prototype` would suffice, however, using an array literal
  431. * avoids issues in Narwhal.
  432. */
  433. var arrayRef = [];
  434. /** Used for native method references */
  435. var errorProto = Error.prototype,
  436. objectProto = Object.prototype,
  437. stringProto = String.prototype;
  438. /** Used to restore the original `_` reference in `noConflict` */
  439. var oldDash = context._;
  440. /** Used to resolve the internal [[Class]] of values */
  441. var toString = objectProto.toString;
  442. /** Used to detect if a method is native */
  443. var reNative = RegExp('^' +
  444. String(toString)
  445. .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  446. .replace(/toString| for [^\]]+/g, '.*?') + '$'
  447. );
  448. /** Native method shortcuts */
  449. var ceil = Math.ceil,
  450. clearTimeout = context.clearTimeout,
  451. floor = Math.floor,
  452. fnToString = Function.prototype.toString,
  453. getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
  454. hasOwnProperty = objectProto.hasOwnProperty,
  455. push = arrayRef.push,
  456. propertyIsEnumerable = objectProto.propertyIsEnumerable,
  457. setTimeout = context.setTimeout,
  458. splice = arrayRef.splice,
  459. unshift = arrayRef.unshift;
  460. /** Used to set meta data on functions */
  461. var defineProperty = (function() {
  462. // IE 8 only accepts DOM elements
  463. try {
  464. var o = {},
  465. func = isNative(func = Object.defineProperty) && func,
  466. result = func(o, o, o) && func;
  467. } catch(e) { }
  468. return result;
  469. }());
  470. /* Native method shortcuts for methods with the same name as other `lodash` methods */
  471. var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
  472. nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
  473. nativeIsFinite = context.isFinite,
  474. nativeIsNaN = context.isNaN,
  475. nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
  476. nativeMax = Math.max,
  477. nativeMin = Math.min,
  478. nativeParseInt = context.parseInt,
  479. nativeRandom = Math.random;
  480. /** Used to lookup a built-in constructor by [[Class]] */
  481. var ctorByClass = {};
  482. ctorByClass[arrayClass] = Array;
  483. ctorByClass[boolClass] = Boolean;
  484. ctorByClass[dateClass] = Date;
  485. ctorByClass[funcClass] = Function;
  486. ctorByClass[objectClass] = Object;
  487. ctorByClass[numberClass] = Number;
  488. ctorByClass[regexpClass] = RegExp;
  489. ctorByClass[stringClass] = String;
  490. /** Used to avoid iterating non-enumerable properties in IE < 9 */
  491. var nonEnumProps = {};
  492. nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
  493. nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
  494. nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
  495. nonEnumProps[objectClass] = { 'constructor': true };
  496. (function() {
  497. var length = shadowedProps.length;
  498. while (length--) {
  499. var key = shadowedProps[length];
  500. for (var className in nonEnumProps) {
  501. if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) {
  502. nonEnumProps[className][key] = false;
  503. }
  504. }
  505. }
  506. }());
  507. /*--------------------------------------------------------------------------*/
  508. /**
  509. * Creates a `lodash` object which wraps the given value to enable intuitive
  510. * method chaining.
  511. *
  512. * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
  513. * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
  514. * and `unshift`
  515. *
  516. * Chaining is supported in custom builds as long as the `value` method is
  517. * implicitly or explicitly included in the build.
  518. *
  519. * The chainable wrapper functions are:
  520. * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
  521. * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
  522. * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`,
  523. * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
  524. * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
  525. * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
  526. * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`,
  527. * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`,
  528. * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
  529. * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`,
  530. * and `zip`
  531. *
  532. * The non-chainable wrapper functions are:
  533. * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
  534. * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
  535. * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
  536. * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
  537. * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
  538. * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
  539. * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
  540. * `template`, `unescape`, `uniqueId`, and `value`
  541. *
  542. * The wrapper functions `first` and `last` return wrapped values when `n` is
  543. * provided, otherwise they return unwrapped values.
  544. *
  545. * Explicit chaining can be enabled by using the `_.chain` method.
  546. *
  547. * @name _
  548. * @constructor
  549. * @category Chaining
  550. * @param {*} value The value to wrap in a `lodash` instance.
  551. * @returns {Object} Returns a `lodash` instance.
  552. * @example
  553. *
  554. * var wrapped = _([1, 2, 3]);
  555. *
  556. * // returns an unwrapped value
  557. * wrapped.reduce(function(sum, num) {
  558. * return sum + num;
  559. * });
  560. * // => 6
  561. *
  562. * // returns a wrapped value
  563. * var squares = wrapped.map(function(num) {
  564. * return num * num;
  565. * });
  566. *
  567. * _.isArray(squares);
  568. * // => false
  569. *
  570. * _.isArray(squares.value());
  571. * // => true
  572. */
  573. function lodash(value) {
  574. // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
  575. return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
  576. ? value
  577. : new lodashWrapper(value);
  578. }
  579. /**
  580. * A fast path for creating `lodash` wrapper objects.
  581. *
  582. * @private
  583. * @param {*} value The value to wrap in a `lodash` instance.
  584. * @param {boolean} chainAll A flag to enable chaining for all methods
  585. * @returns {Object} Returns a `lodash` instance.
  586. */
  587. function lodashWrapper(value, chainAll) {
  588. this.__chain__ = !!chainAll;
  589. this.__wrapped__ = value;
  590. }
  591. // ensure `new lodashWrapper` is an instance of `lodash`
  592. lodashWrapper.prototype = lodash.prototype;
  593. /**
  594. * An object used to flag environments features.
  595. *
  596. * @static
  597. * @memberOf _
  598. * @type Object
  599. */
  600. var support = lodash.support = {};
  601. (function() {
  602. var ctor = function() { this.x = 1; },
  603. object = { '0': 1, 'length': 1 },
  604. props = [];
  605. ctor.prototype = { 'valueOf': 1, 'y': 1 };
  606. for (var key in new ctor) { props.push(key); }
  607. for (key in arguments) { }
  608. /**
  609. * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
  610. *
  611. * @memberOf _.support
  612. * @type boolean
  613. */
  614. support.argsClass = toString.call(arguments) == argsClass;
  615. /**
  616. * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
  617. *
  618. * @memberOf _.support
  619. * @type boolean
  620. */
  621. support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
  622. /**
  623. * Detect if `name` or `message` properties of `Error.prototype` are
  624. * enumerable by default. (IE < 9, Safari < 5.1)
  625. *
  626. * @memberOf _.support
  627. * @type boolean
  628. */
  629. support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
  630. /**
  631. * Detect if `prototype` properties are enumerable by default.
  632. *
  633. * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
  634. * (if the prototype or a property on the prototype has been set)
  635. * incorrectly sets a function's `prototype` property [[Enumerable]]
  636. * value to `true`.
  637. *
  638. * @memberOf _.support
  639. * @type boolean
  640. */
  641. support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
  642. /**
  643. * Detect if functions can be decompiled by `Function#toString`
  644. * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
  645. *
  646. * @memberOf _.support
  647. * @type boolean
  648. */
  649. support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
  650. /**
  651. * Detect if `Function#name` is supported (all but IE).
  652. *
  653. * @memberOf _.support
  654. * @type boolean
  655. */
  656. support.funcNames = typeof Function.name == 'string';
  657. /**
  658. * Detect if `arguments` object indexes are non-enumerable
  659. * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1).
  660. *
  661. * @memberOf _.support
  662. * @type boolean
  663. */
  664. support.nonEnumArgs = key != 0;
  665. /**
  666. * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
  667. *
  668. * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
  669. * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug).
  670. *
  671. * @memberOf _.support
  672. * @type boolean
  673. */
  674. support.nonEnumShadows = !/valueOf/.test(props);
  675. /**
  676. * Detect if own properties are iterated after inherited properties (all but IE < 9).
  677. *
  678. * @memberOf _.support
  679. * @type boolean
  680. */
  681. support.ownLast = props[0] != 'x';
  682. /**
  683. * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
  684. *
  685. * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
  686. * and `splice()` functions that fail to remove the last element, `value[0]`,
  687. * of array-like objects even though the `length` property is set to `0`.
  688. * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
  689. * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
  690. *
  691. * @memberOf _.support
  692. * @type boolean
  693. */
  694. support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
  695. /**
  696. * Detect lack of support for accessing string characters by index.
  697. *
  698. * IE < 8 can't access characters by index and IE 8 can only access
  699. * characters by index on string literals.
  700. *
  701. * @memberOf _.support
  702. * @type boolean
  703. */
  704. support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
  705. /**
  706. * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9)
  707. * and that the JS engine errors when attempting to coerce an object to
  708. * a string without a `toString` function.
  709. *
  710. * @memberOf _.support
  711. * @type boolean
  712. */
  713. try {
  714. support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
  715. } catch(e) {
  716. support.nodeClass = true;
  717. }
  718. }(1));
  719. /**
  720. * By default, the template delimiters used by Lo-Dash are similar to those in
  721. * embedded Ruby (ERB). Change the following template settings to use alternative
  722. * delimiters.
  723. *
  724. * @static
  725. * @memberOf _
  726. * @type Object
  727. */
  728. lodash.templateSettings = {
  729. /**
  730. * Used to detect `data` property values to be HTML-escaped.
  731. *
  732. * @memberOf _.templateSettings
  733. * @type RegExp
  734. */
  735. 'escape': /<%-([\s\S]+?)%>/g,
  736. /**
  737. * Used to detect code to be evaluated.
  738. *
  739. * @memberOf _.templateSettings
  740. * @type RegExp
  741. */
  742. 'evaluate': /<%([\s\S]+?)%>/g,
  743. /**
  744. * Used to detect `data` property values to inject.
  745. *
  746. * @memberOf _.templateSettings
  747. * @type RegExp
  748. */
  749. 'interpolate': reInterpolate,
  750. /**
  751. * Used to reference the data object in the template text.
  752. *
  753. * @memberOf _.templateSettings
  754. * @type string
  755. */
  756. 'variable': '',
  757. /**
  758. * Used to import variables into the compiled template.
  759. *
  760. * @memberOf _.templateSettings
  761. * @type Object
  762. */
  763. 'imports': {
  764. /**
  765. * A reference to the `lodash` function.
  766. *
  767. * @memberOf _.templateSettings.imports
  768. * @type Function
  769. */
  770. '_': lodash
  771. }
  772. };
  773. /*--------------------------------------------------------------------------*/
  774. /**
  775. * The template used to create iterator functions.
  776. *
  777. * @private
  778. * @param {Object} data The data object used to populate the text.
  779. * @returns {string} Returns the interpolated text.
  780. */
  781. var iteratorTemplate = function(obj) {
  782. var __p = 'var index, iterable = ' +
  783. (obj.firstArg) +
  784. ', result = ' +
  785. (obj.init) +
  786. ';\nif (!iterable) return result;\n' +
  787. (obj.top) +
  788. ';';
  789. if (obj.array) {
  790. __p += '\nvar length = iterable.length; index = -1;\nif (' +
  791. (obj.array) +
  792. ') { ';
  793. if (support.unindexedChars) {
  794. __p += '\n if (isString(iterable)) {\n iterable = iterable.split(\'\')\n } ';
  795. }
  796. __p += '\n while (++index < length) {\n ' +
  797. (obj.loop) +
  798. ';\n }\n}\nelse { ';
  799. } else if (support.nonEnumArgs) {
  800. __p += '\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += \'\';\n ' +
  801. (obj.loop) +
  802. ';\n }\n } else { ';
  803. }
  804. if (support.enumPrototypes) {
  805. __p += '\n var skipProto = typeof iterable == \'function\';\n ';
  806. }
  807. if (support.enumErrorProps) {
  808. __p += '\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n ';
  809. }
  810. var conditions = []; if (support.enumPrototypes) { conditions.push('!(skipProto && index == "prototype")'); } if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (index == "message" || index == "name"))'); }
  811. if (obj.useHas && obj.keys) {
  812. __p += '\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n';
  813. if (conditions.length) {
  814. __p += ' if (' +
  815. (conditions.join(' && ')) +
  816. ') {\n ';
  817. }
  818. __p +=
  819. (obj.loop) +
  820. '; ';
  821. if (conditions.length) {
  822. __p += '\n }';
  823. }
  824. __p += '\n } ';
  825. } else {
  826. __p += '\n for (index in iterable) {\n';
  827. if (obj.useHas) { conditions.push("hasOwnProperty.call(iterable, index)"); } if (conditions.length) {
  828. __p += ' if (' +
  829. (conditions.join(' && ')) +
  830. ') {\n ';
  831. }
  832. __p +=
  833. (obj.loop) +
  834. '; ';
  835. if (conditions.length) {
  836. __p += '\n }';
  837. }
  838. __p += '\n } ';
  839. if (support.nonEnumShadows) {
  840. __p += '\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n ';
  841. for (k = 0; k < 7; k++) {
  842. __p += '\n index = \'' +
  843. (obj.shadowedProps[k]) +
  844. '\';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))';
  845. if (!obj.useHas) {
  846. __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])';
  847. }
  848. __p += ') {\n ' +
  849. (obj.loop) +
  850. ';\n } ';
  851. }
  852. __p += '\n } ';
  853. }
  854. }
  855. if (obj.array || support.nonEnumArgs) {
  856. __p += '\n}';
  857. }
  858. __p +=
  859. (obj.bottom) +
  860. ';\nreturn result';
  861. return __p
  862. };
  863. /*--------------------------------------------------------------------------*/
  864. /**
  865. * The base implementation of `_.bind` that creates the bound function and
  866. * sets its meta data.
  867. *
  868. * @private
  869. * @param {Array} bindData The bind data array.
  870. * @returns {Function} Returns the new bound function.
  871. */
  872. function baseBind(bindData) {
  873. var func = bindData[0],
  874. partialArgs = bindData[2],
  875. thisArg = bindData[4];
  876. function bound() {
  877. // `Function#bind` spec
  878. // http://es5.github.io/#x15.3.4.5
  879. if (partialArgs) {
  880. // avoid `arguments` object deoptimizations by using `slice` instead
  881. // of `Array.prototype.slice.call` and not assigning `arguments` to a
  882. // variable as a ternary expression
  883. var args = slice(partialArgs);
  884. push.apply(args, arguments);
  885. }
  886. // mimic the constructor's `return` behavior
  887. // http://es5.github.io/#x13.2.2
  888. if (this instanceof bound) {
  889. // ensure `new bound` is an instance of `func`
  890. var thisBinding = baseCreate(func.prototype),
  891. result = func.apply(thisBinding, args || arguments);
  892. return isObject(result) ? result : thisBinding;
  893. }
  894. return func.apply(thisArg, args || arguments);
  895. }
  896. setBindData(bound, bindData);
  897. return bound;
  898. }
  899. /**
  900. * The base implementation of `_.clone` without argument juggling or support
  901. * for `thisArg` binding.
  902. *
  903. * @private
  904. * @param {*} value The value to clone.
  905. * @param {boolean} [isDeep=false] Specify a deep clone.
  906. * @param {Function} [callback] The function to customize cloning values.
  907. * @param {Array} [stackA=[]] Tracks traversed source objects.
  908. * @param {Array} [stackB=[]] Associates clones with source counterparts.
  909. * @returns {*} Returns the cloned value.
  910. */
  911. function baseClone(value, isDeep, callback, stackA, stackB) {
  912. if (callback) {
  913. var result = callback(value);
  914. if (typeof result != 'undefined') {
  915. return result;
  916. }
  917. }
  918. // inspect [[Class]]
  919. var isObj = isObject(value);
  920. if (isObj) {
  921. var className = toString.call(value);
  922. if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) {
  923. return value;
  924. }
  925. var ctor = ctorByClass[className];
  926. switch (className) {
  927. case boolClass:
  928. case dateClass:
  929. return new ctor(+value);
  930. case numberClass:
  931. case stringClass:
  932. return new ctor(value);
  933. case regexpClass:
  934. result = ctor(value.source, reFlags.exec(value));
  935. result.lastIndex = value.lastIndex;
  936. return result;
  937. }
  938. } else {
  939. return value;
  940. }
  941. var isArr = isArray(value);
  942. if (isDeep) {
  943. // check for circular references and return corresponding clone
  944. var initedStack = !stackA;
  945. stackA || (stackA = getArray());
  946. stackB || (stackB = getArray());
  947. var length = stackA.length;
  948. while (length--) {
  949. if (stackA[length] == value) {
  950. return stackB[length];
  951. }
  952. }
  953. result = isArr ? ctor(value.length) : {};
  954. }
  955. else {
  956. result = isArr ? slice(value) : assign({}, value);
  957. }
  958. // add array properties assigned by `RegExp#exec`
  959. if (isArr) {
  960. if (hasOwnProperty.call(value, 'index')) {
  961. result.index = value.index;
  962. }
  963. if (hasOwnProperty.call(value, 'input')) {
  964. result.input = value.input;
  965. }
  966. }
  967. // exit for shallow clone
  968. if (!isDeep) {
  969. return result;
  970. }
  971. // add the source value to the stack of traversed objects
  972. // and associate it with its clone
  973. stackA.push(value);
  974. stackB.push(result);
  975. // recursively populate clone (susceptible to call stack limits)
  976. (isArr ? baseEach : forOwn)(value, function(objValue, key) {
  977. result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
  978. });
  979. if (initedStack) {
  980. releaseArray(stackA);
  981. releaseArray(stackB);
  982. }
  983. return result;
  984. }
  985. /**
  986. * The base implementation of `_.create` without support for assigning
  987. * properties to the created object.
  988. *
  989. * @private
  990. * @param {Object} prototype The object to inherit from.
  991. * @returns {Object} Returns the new object.
  992. */
  993. function baseCreate(prototype, properties) {
  994. return isObject(prototype) ? nativeCreate(prototype) : {};
  995. }
  996. // fallback for browsers without `Object.create`
  997. if (!nativeCreate) {
  998. baseCreate = (function() {
  999. function Object() {}
  1000. return function(prototype) {
  1001. if (isObject(prototype)) {
  1002. Object.prototype = prototype;
  1003. var result = new Object;
  1004. Object.prototype = null;
  1005. }
  1006. return result || context.Object();
  1007. };
  1008. }());
  1009. }
  1010. /**
  1011. * The base implementation of `_.createCallback` without support for creating
  1012. * "_.pluck" or "_.where" style callbacks.
  1013. *
  1014. * @private
  1015. * @param {*} [func=identity] The value to convert to a callback.
  1016. * @param {*} [thisArg] The `this` binding of the created callback.
  1017. * @param {number} [argCount] The number of arguments the callback accepts.
  1018. * @returns {Function} Returns a callback function.
  1019. */
  1020. function baseCreateCallback(func, thisArg, argCount) {
  1021. if (typeof func != 'function') {
  1022. return identity;
  1023. }
  1024. // exit early for no `thisArg` or already bound by `Function#bind`
  1025. if (typeof thisArg == 'undefined' || !('prototype' in func)) {
  1026. return func;
  1027. }
  1028. var bindData = func.__bindData__;
  1029. if (typeof bindData == 'undefined') {
  1030. if (support.funcNames) {
  1031. bindData = !func.name;
  1032. }
  1033. bindData = bindData || !support.funcDecomp;
  1034. if (!bindData) {
  1035. var source = fnToString.call(func);
  1036. if (!support.funcNames) {
  1037. bindData = !reFuncName.test(source);
  1038. }
  1039. if (!bindData) {
  1040. // checks if `func` references the `this` keyword and stores the result
  1041. bindData = reThis.test(source);
  1042. setBindData(func, bindData);
  1043. }
  1044. }
  1045. }
  1046. // exit early if there are no `this` references or `func` is bound
  1047. if (bindData === false || (bindData !== true && bindData[1] & 1)) {
  1048. return func;
  1049. }
  1050. switch (argCount) {
  1051. case 1: return function(value) {
  1052. return func.call(thisArg, value);
  1053. };
  1054. case 2: return function(a, b) {
  1055. return func.call(thisArg, a, b);
  1056. };
  1057. case 3: return function(value, index, collection) {
  1058. return func.call(thisArg, value, index, collection);
  1059. };
  1060. case 4: return function(accumulator, value, index, collection) {
  1061. return func.call(thisArg, accumulator, value, index, collection);
  1062. };
  1063. }
  1064. return bind(func, thisArg);
  1065. }
  1066. /**
  1067. * The base implementation of `createWrapper` that creates the wrapper and
  1068. * sets its meta data.
  1069. *
  1070. * @private
  1071. * @param {Array} bindData The bind data array.
  1072. * @returns {Function} Returns the new function.
  1073. */
  1074. function baseCreateWrapper(bindData) {
  1075. var func = bindData[0],
  1076. bitmask = bindData[1],
  1077. partialArgs = bindData[2],
  1078. partialRightArgs = bindData[3],
  1079. thisArg = bindData[4],
  1080. arity = bindData[5];
  1081. var isBind = bitmask & 1,
  1082. isBindKey = bitmask & 2,
  1083. isCurry = bitmask & 4,
  1084. isCurryBound = bitmask & 8,
  1085. key = func;
  1086. function bound() {
  1087. var thisBinding = isBind ? thisArg : this;
  1088. if (partialArgs) {
  1089. var args = slice(partialArgs);
  1090. push.apply(args, arguments);
  1091. }
  1092. if (partialRightArgs || isCurry) {
  1093. args || (args = slice(arguments));
  1094. if (partialRightArgs) {
  1095. push.apply(args, partialRightArgs);
  1096. }
  1097. if (isCurry && args.length < arity) {
  1098. bitmask |= 16 & ~32;
  1099. return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]);
  1100. }
  1101. }
  1102. args || (args = arguments);
  1103. if (isBindKey) {
  1104. func = thisBinding[key];
  1105. }
  1106. if (this instanceof bound) {
  1107. thisBinding = baseCreate(func.prototype);
  1108. var result = func.apply(thisBinding, args);
  1109. return isObject(result) ? result : thisBinding;
  1110. }
  1111. return func.apply(thisBinding, args);
  1112. }
  1113. setBindData(bound, bindData);
  1114. return bound;
  1115. }
  1116. /**
  1117. * The base implementation of `_.difference` that accepts a single array
  1118. * of values to exclude.
  1119. *
  1120. * @private
  1121. * @param {Array} array The array to process.
  1122. * @param {Array} [values] The array of values to exclude.
  1123. * @returns {Array} Returns a new array of filtered values.
  1124. */
  1125. function baseDifference(array, values) {
  1126. var index = -1,
  1127. indexOf = getIndexOf(),
  1128. length = array ? array.length : 0,
  1129. isLarge = length >= largeArraySize && indexOf === baseIndexOf,
  1130. result = [];
  1131. if (isLarge) {
  1132. var cache = createCache(values);
  1133. if (cache) {
  1134. indexOf = cacheIndexOf;
  1135. values = cache;
  1136. } else {
  1137. isLarge = false;
  1138. }
  1139. }
  1140. while (++index < length) {
  1141. var value = array[index];
  1142. if (indexOf(values, value) < 0) {
  1143. result.push(value);
  1144. }
  1145. }
  1146. if (isLarge) {
  1147. releaseObject(values);
  1148. }
  1149. return result;
  1150. }
  1151. /**
  1152. * The base implementation of `_.flatten` without support for callback
  1153. * shorthands or `thisArg` binding.
  1154. *
  1155. * @private
  1156. * @param {Array} array The array to flatten.
  1157. * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
  1158. * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
  1159. * @param {number} [fromIndex=0] The index to start from.
  1160. * @returns {Array} Returns a new flattened array.
  1161. */
  1162. function baseFlatten(array, isShallow, isStrict, fromIndex) {
  1163. var index = (fromIndex || 0) - 1,
  1164. length = array ? array.length : 0,
  1165. result = [];
  1166. while (++index < length) {
  1167. var value = array[index];
  1168. if (value && typeof value == 'object' && typeof value.length == 'number'
  1169. && (isArray(value) || isArguments(value))) {
  1170. // recursively flatten arrays (susceptible to call stack limits)
  1171. if (!isShallow) {
  1172. value = baseFlatten(value, isShallow, isStrict);
  1173. }
  1174. var valIndex = -1,
  1175. valLength = value.length,
  1176. resIndex = result.length;
  1177. result.length += valLength;
  1178. while (++valIndex < valLength) {
  1179. result[resIndex++] = value[valIndex];
  1180. }
  1181. } else if (!isStrict) {
  1182. result.push(value);
  1183. }
  1184. }
  1185. return result;
  1186. }
  1187. /**
  1188. * The base implementation of `_.isEqual`, without support for `thisArg` binding,
  1189. * that allows partial "_.where" style comparisons.
  1190. *
  1191. * @private
  1192. * @param {*} a The value to compare.
  1193. * @param {*} b The other value to compare.
  1194. * @param {Function} [callback] The function to customize comparing values.
  1195. * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
  1196. * @param {Array} [stackA=[]] Tracks traversed `a` objects.
  1197. * @param {Array} [stackB=[]] Tracks traversed `b` objects.
  1198. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  1199. */
  1200. function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
  1201. // used to indicate that when comparing objects, `a` has at least the properties of `b`
  1202. if (callback) {
  1203. var result = callback(a, b);
  1204. if (typeof result != 'undefined') {
  1205. return !!result;
  1206. }
  1207. }
  1208. // exit early for identical values
  1209. if (a === b) {
  1210. // treat `+0` vs. `-0` as not equal
  1211. return a !== 0 || (1 / a == 1 / b);
  1212. }
  1213. var type = typeof a,
  1214. otherType = typeof b;
  1215. // exit early for unlike primitive values
  1216. if (a === a &&
  1217. !(a && objectTypes[type]) &&
  1218. !(b && objectTypes[otherType])) {
  1219. return false;
  1220. }
  1221. // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
  1222. // http://es5.github.io/#x15.3.4.4
  1223. if (a == null || b == null) {
  1224. return a === b;
  1225. }
  1226. // compare [[Class]] names
  1227. var className = toString.call(a),
  1228. otherClass = toString.call(b);
  1229. if (className == argsClass) {
  1230. className = objectClass;
  1231. }
  1232. if (otherClass == argsClass) {
  1233. otherClass = objectClass;
  1234. }
  1235. if (className != otherClass) {
  1236. return false;
  1237. }
  1238. switch (className) {
  1239. case boolClass:
  1240. case dateClass:
  1241. // coerce dates and booleans to numbers, dates to milliseconds and booleans
  1242. // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
  1243. return +a == +b;
  1244. case numberClass:
  1245. // treat `NaN` vs. `NaN` as equal
  1246. return (a != +a)
  1247. ? b != +b
  1248. // but treat `+0` vs. `-0` as not equal
  1249. : (a == 0 ? (1 / a == 1 / b) : a == +b);
  1250. case regexpClass:
  1251. case stringClass:
  1252. // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
  1253. // treat string primitives and their corresponding object instances as equal
  1254. return a == String(b);
  1255. }
  1256. var isArr = className == arrayClass;
  1257. if (!isArr) {
  1258. // unwrap any `lodash` wrapped values
  1259. var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
  1260. bWrapped = hasOwnProperty.call(b, '__wrapped__');
  1261. if (aWrapped || bWrapped) {
  1262. return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
  1263. }
  1264. // exit for functions and DOM nodes
  1265. if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) {
  1266. return false;
  1267. }
  1268. // in older versions of Opera, `arguments` objects have `Array` constructors
  1269. var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor,
  1270. ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor;
  1271. // non `Object` object instances with different constructors are not equal
  1272. if (ctorA != ctorB &&
  1273. !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
  1274. ('constructor' in a && 'constructor' in b)
  1275. ) {
  1276. return false;
  1277. }
  1278. }
  1279. // assume cyclic structures are equal
  1280. // the algorithm for detecting cyclic structures is adapted from ES 5.1
  1281. // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
  1282. var initedStack = !stackA;
  1283. stackA || (stackA = getArray());
  1284. stackB || (stackB = getArray());
  1285. var length = stackA.length;
  1286. while (length--) {
  1287. if (stackA[length] == a) {
  1288. return stackB[length] == b;
  1289. }
  1290. }
  1291. var size = 0;
  1292. result = true;
  1293. // add `a` and `b` to the stack of traversed objects
  1294. stackA.push(a);
  1295. stackB.push(b);
  1296. // recursively compare objects and arrays (susceptible to call stack limits)
  1297. if (isArr) {
  1298. // compare lengths to determine if a deep comparison is necessary
  1299. length = a.length;
  1300. size = b.length;
  1301. result = size == length;
  1302. if (result || isWhere) {
  1303. // deep compare the contents, ignoring non-numeric properties
  1304. while (size--) {
  1305. var index = length,
  1306. value = b[size];
  1307. if (isWhere) {
  1308. while (index--) {
  1309. if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
  1310. break;
  1311. }
  1312. }
  1313. } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
  1314. break;
  1315. }
  1316. }
  1317. }
  1318. }
  1319. else {
  1320. // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
  1321. // which, in this case, is more costly
  1322. forIn(b, function(value, key, b) {
  1323. if (hasOwnProperty.call(b, key)) {
  1324. // count the number of properties.
  1325. size++;
  1326. // deep compare each property value.
  1327. return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
  1328. }
  1329. });
  1330. if (result && !isWhere) {
  1331. // ensure both objects have the same number of properties
  1332. forIn(a, function(value, key, a) {
  1333. if (hasOwnProperty.call(a, key)) {
  1334. // `size` will be `-1` if `a` has more properties than `b`
  1335. return (result = --size > -1);
  1336. }
  1337. });
  1338. }
  1339. }
  1340. stackA.pop();
  1341. stackB.pop();
  1342. if (initedStack) {
  1343. releaseArray(stackA);
  1344. releaseArray(stackB);
  1345. }
  1346. return result;
  1347. }
  1348. /**
  1349. * The base implementation of `_.merge` without argument juggling or support
  1350. * for `thisArg` binding.
  1351. *
  1352. * @private
  1353. * @param {Object} object The destination object.
  1354. * @param {Object} source The source object.
  1355. * @param {Function} [callback] The function to customize merging properties.
  1356. * @param {Array} [stackA=[]] Tracks traversed source objects.
  1357. * @param {Array} [stackB=[]] Associates values with source counterparts.
  1358. */
  1359. function baseMerge(object, source, callback, stackA, stackB) {
  1360. (isArray(source) ? forEach : forOwn)(source, function(source, key) {
  1361. var found,
  1362. isArr,
  1363. result = source,
  1364. value = object[key];
  1365. if (source && ((isArr = isArray(so