PageRenderTime 54ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/files/lodash/2.2.1/lodash.js

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