PageRenderTime 49ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/files/underscorejs/1.5.1/underscore.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 1246 lines | 926 code | 106 blank | 214 comment | 256 complexity | 1dccc53d7339439bc6fe8a01f54f56ca MD5 | raw file
  1. // Underscore.js 1.5.1
  2. // http://underscorejs.org
  3. // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  4. // Underscore may be freely distributed under the MIT license.
  5. (function() {
  6. // Baseline setup
  7. // --------------
  8. // Establish the root object, `window` in the browser, or `global` on the server.
  9. var root = this;
  10. // Save the previous value of the `_` variable.
  11. var previousUnderscore = root._;
  12. // Establish the object that gets returned to break out of a loop iteration.
  13. var breaker = {};
  14. // Save bytes in the minified (but not gzipped) version:
  15. var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
  16. // Create quick reference variables for speed access to core prototypes.
  17. var
  18. push = ArrayProto.push,
  19. slice = ArrayProto.slice,
  20. concat = ArrayProto.concat,
  21. toString = ObjProto.toString,
  22. hasOwnProperty = ObjProto.hasOwnProperty;
  23. // All **ECMAScript 5** native function implementations that we hope to use
  24. // are declared here.
  25. var
  26. nativeForEach = ArrayProto.forEach,
  27. nativeMap = ArrayProto.map,
  28. nativeReduce = ArrayProto.reduce,
  29. nativeReduceRight = ArrayProto.reduceRight,
  30. nativeFilter = ArrayProto.filter,
  31. nativeEvery = ArrayProto.every,
  32. nativeSome = ArrayProto.some,
  33. nativeIndexOf = ArrayProto.indexOf,
  34. nativeLastIndexOf = ArrayProto.lastIndexOf,
  35. nativeIsArray = Array.isArray,
  36. nativeKeys = Object.keys,
  37. nativeBind = FuncProto.bind;
  38. // Create a safe reference to the Underscore object for use below.
  39. var _ = function(obj) {
  40. if (obj instanceof _) return obj;
  41. if (!(this instanceof _)) return new _(obj);
  42. this._wrapped = obj;
  43. };
  44. // Export the Underscore object for **Node.js**, with
  45. // backwards-compatibility for the old `require()` API. If we're in
  46. // the browser, add `_` as a global object via a string identifier,
  47. // for Closure Compiler "advanced" mode.
  48. if (typeof exports !== 'undefined') {
  49. if (typeof module !== 'undefined' && module.exports) {
  50. exports = module.exports = _;
  51. }
  52. exports._ = _;
  53. } else {
  54. root._ = _;
  55. }
  56. // Current version.
  57. _.VERSION = '1.5.1';
  58. // Collection Functions
  59. // --------------------
  60. // The cornerstone, an `each` implementation, aka `forEach`.
  61. // Handles objects with the built-in `forEach`, arrays, and raw objects.
  62. // Delegates to **ECMAScript 5**'s native `forEach` if available.
  63. var each = _.each = _.forEach = function(obj, iterator, context) {
  64. if (obj == null) return;
  65. if (nativeForEach && obj.forEach === nativeForEach) {
  66. obj.forEach(iterator, context);
  67. } else if (obj.length === +obj.length) {
  68. for (var i = 0, l = obj.length; i < l; i++) {
  69. if (iterator.call(context, obj[i], i, obj) === breaker) return;
  70. }
  71. } else {
  72. for (var key in obj) {
  73. if (_.has(obj, key)) {
  74. if (iterator.call(context, obj[key], key, obj) === breaker) return;
  75. }
  76. }
  77. }
  78. };
  79. // Return the results of applying the iterator to each element.
  80. // Delegates to **ECMAScript 5**'s native `map` if available.
  81. _.map = _.collect = function(obj, iterator, context) {
  82. var results = [];
  83. if (obj == null) return results;
  84. if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
  85. each(obj, function(value, index, list) {
  86. results.push(iterator.call(context, value, index, list));
  87. });
  88. return results;
  89. };
  90. var reduceError = 'Reduce of empty array with no initial value';
  91. // **Reduce** builds up a single result from a list of values, aka `inject`,
  92. // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
  93. _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
  94. var initial = arguments.length > 2;
  95. if (obj == null) obj = [];
  96. if (nativeReduce && obj.reduce === nativeReduce) {
  97. if (context) iterator = _.bind(iterator, context);
  98. return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
  99. }
  100. each(obj, function(value, index, list) {
  101. if (!initial) {
  102. memo = value;
  103. initial = true;
  104. } else {
  105. memo = iterator.call(context, memo, value, index, list);
  106. }
  107. });
  108. if (!initial) throw new TypeError(reduceError);
  109. return memo;
  110. };
  111. // The right-associative version of reduce, also known as `foldr`.
  112. // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
  113. _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
  114. var initial = arguments.length > 2;
  115. if (obj == null) obj = [];
  116. if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
  117. if (context) iterator = _.bind(iterator, context);
  118. return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
  119. }
  120. var length = obj.length;
  121. if (length !== +length) {
  122. var keys = _.keys(obj);
  123. length = keys.length;
  124. }
  125. each(obj, function(value, index, list) {
  126. index = keys ? keys[--length] : --length;
  127. if (!initial) {
  128. memo = obj[index];
  129. initial = true;
  130. } else {
  131. memo = iterator.call(context, memo, obj[index], index, list);
  132. }
  133. });
  134. if (!initial) throw new TypeError(reduceError);
  135. return memo;
  136. };
  137. // Return the first value which passes a truth test. Aliased as `detect`.
  138. _.find = _.detect = function(obj, iterator, context) {
  139. var result;
  140. any(obj, function(value, index, list) {
  141. if (iterator.call(context, value, index, list)) {
  142. result = value;
  143. return true;
  144. }
  145. });
  146. return result;
  147. };
  148. // Return all the elements that pass a truth test.
  149. // Delegates to **ECMAScript 5**'s native `filter` if available.
  150. // Aliased as `select`.
  151. _.filter = _.select = function(obj, iterator, context) {
  152. var results = [];
  153. if (obj == null) return results;
  154. if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
  155. each(obj, function(value, index, list) {
  156. if (iterator.call(context, value, index, list)) results.push(value);
  157. });
  158. return results;
  159. };
  160. // Return all the elements for which a truth test fails.
  161. _.reject = function(obj, iterator, context) {
  162. return _.filter(obj, function(value, index, list) {
  163. return !iterator.call(context, value, index, list);
  164. }, context);
  165. };
  166. // Determine whether all of the elements match a truth test.
  167. // Delegates to **ECMAScript 5**'s native `every` if available.
  168. // Aliased as `all`.
  169. _.every = _.all = function(obj, iterator, context) {
  170. iterator || (iterator = _.identity);
  171. var result = true;
  172. if (obj == null) return result;
  173. if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
  174. each(obj, function(value, index, list) {
  175. if (!(result = result && iterator.call(context, value, index, list))) return breaker;
  176. });
  177. return !!result;
  178. };
  179. // Determine if at least one element in the object matches a truth test.
  180. // Delegates to **ECMAScript 5**'s native `some` if available.
  181. // Aliased as `any`.
  182. var any = _.some = _.any = function(obj, iterator, context) {
  183. iterator || (iterator = _.identity);
  184. var result = false;
  185. if (obj == null) return result;
  186. if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
  187. each(obj, function(value, index, list) {
  188. if (result || (result = iterator.call(context, value, index, list))) return breaker;
  189. });
  190. return !!result;
  191. };
  192. // Determine if the array or object contains a given value (using `===`).
  193. // Aliased as `include`.
  194. _.contains = _.include = function(obj, target) {
  195. if (obj == null) return false;
  196. if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
  197. return any(obj, function(value) {
  198. return value === target;
  199. });
  200. };
  201. // Invoke a method (with arguments) on every item in a collection.
  202. _.invoke = function(obj, method) {
  203. var args = slice.call(arguments, 2);
  204. var isFunc = _.isFunction(method);
  205. return _.map(obj, function(value) {
  206. return (isFunc ? method : value[method]).apply(value, args);
  207. });
  208. };
  209. // Convenience version of a common use case of `map`: fetching a property.
  210. _.pluck = function(obj, key) {
  211. return _.map(obj, function(value){ return value[key]; });
  212. };
  213. // Convenience version of a common use case of `filter`: selecting only objects
  214. // containing specific `key:value` pairs.
  215. _.where = function(obj, attrs, first) {
  216. if (_.isEmpty(attrs)) return first ? void 0 : [];
  217. return _[first ? 'find' : 'filter'](obj, function(value) {
  218. for (var key in attrs) {
  219. if (attrs[key] !== value[key]) return false;
  220. }
  221. return true;
  222. });
  223. };
  224. // Convenience version of a common use case of `find`: getting the first object
  225. // containing specific `key:value` pairs.
  226. _.findWhere = function(obj, attrs) {
  227. return _.where(obj, attrs, true);
  228. };
  229. // Return the maximum element or (element-based computation).
  230. // Can't optimize arrays of integers longer than 65,535 elements.
  231. // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
  232. _.max = function(obj, iterator, context) {
  233. if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
  234. return Math.max.apply(Math, obj);
  235. }
  236. if (!iterator && _.isEmpty(obj)) return -Infinity;
  237. var result = {computed : -Infinity, value: -Infinity};
  238. each(obj, function(value, index, list) {
  239. var computed = iterator ? iterator.call(context, value, index, list) : value;
  240. computed > result.computed && (result = {value : value, computed : computed});
  241. });
  242. return result.value;
  243. };
  244. // Return the minimum element (or element-based computation).
  245. _.min = function(obj, iterator, context) {
  246. if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
  247. return Math.min.apply(Math, obj);
  248. }
  249. if (!iterator && _.isEmpty(obj)) return Infinity;
  250. var result = {computed : Infinity, value: Infinity};
  251. each(obj, function(value, index, list) {
  252. var computed = iterator ? iterator.call(context, value, index, list) : value;
  253. computed < result.computed && (result = {value : value, computed : computed});
  254. });
  255. return result.value;
  256. };
  257. // Shuffle an array.
  258. _.shuffle = function(obj) {
  259. var rand;
  260. var index = 0;
  261. var shuffled = [];
  262. each(obj, function(value) {
  263. rand = _.random(index++);
  264. shuffled[index - 1] = shuffled[rand];
  265. shuffled[rand] = value;
  266. });
  267. return shuffled;
  268. };
  269. // An internal function to generate lookup iterators.
  270. var lookupIterator = function(value) {
  271. return _.isFunction(value) ? value : function(obj){ return obj[value]; };
  272. };
  273. // Sort the object's values by a criterion produced by an iterator.
  274. _.sortBy = function(obj, value, context) {
  275. var iterator = lookupIterator(value);
  276. return _.pluck(_.map(obj, function(value, index, list) {
  277. return {
  278. value : value,
  279. index : index,
  280. criteria : iterator.call(context, value, index, list)
  281. };
  282. }).sort(function(left, right) {
  283. var a = left.criteria;
  284. var b = right.criteria;
  285. if (a !== b) {
  286. if (a > b || a === void 0) return 1;
  287. if (a < b || b === void 0) return -1;
  288. }
  289. return left.index < right.index ? -1 : 1;
  290. }), 'value');
  291. };
  292. // An internal function used for aggregate "group by" operations.
  293. var group = function(obj, value, context, behavior) {
  294. var result = {};
  295. var iterator = lookupIterator(value == null ? _.identity : value);
  296. each(obj, function(value, index) {
  297. var key = iterator.call(context, value, index, obj);
  298. behavior(result, key, value);
  299. });
  300. return result;
  301. };
  302. // Groups the object's values by a criterion. Pass either a string attribute
  303. // to group by, or a function that returns the criterion.
  304. _.groupBy = function(obj, value, context) {
  305. return group(obj, value, context, function(result, key, value) {
  306. (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
  307. });
  308. };
  309. // Counts instances of an object that group by a certain criterion. Pass
  310. // either a string attribute to count by, or a function that returns the
  311. // criterion.
  312. _.countBy = function(obj, value, context) {
  313. return group(obj, value, context, function(result, key) {
  314. if (!_.has(result, key)) result[key] = 0;
  315. result[key]++;
  316. });
  317. };
  318. // Use a comparator function to figure out the smallest index at which
  319. // an object should be inserted so as to maintain order. Uses binary search.
  320. _.sortedIndex = function(array, obj, iterator, context) {
  321. iterator = iterator == null ? _.identity : lookupIterator(iterator);
  322. var value = iterator.call(context, obj);
  323. var low = 0, high = array.length;
  324. while (low < high) {
  325. var mid = (low + high) >>> 1;
  326. iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
  327. }
  328. return low;
  329. };
  330. // Safely create a real, live array from anything iterable.
  331. _.toArray = function(obj) {
  332. if (!obj) return [];
  333. if (_.isArray(obj)) return slice.call(obj);
  334. if (obj.length === +obj.length) return _.map(obj, _.identity);
  335. return _.values(obj);
  336. };
  337. // Return the number of elements in an object.
  338. _.size = function(obj) {
  339. if (obj == null) return 0;
  340. return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
  341. };
  342. // Array Functions
  343. // ---------------
  344. // Get the first element of an array. Passing **n** will return the first N
  345. // values in the array. Aliased as `head` and `take`. The **guard** check
  346. // allows it to work with `_.map`.
  347. _.first = _.head = _.take = function(array, n, guard) {
  348. if (array == null) return void 0;
  349. return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
  350. };
  351. // Returns everything but the last entry of the array. Especially useful on
  352. // the arguments object. Passing **n** will return all the values in
  353. // the array, excluding the last N. The **guard** check allows it to work with
  354. // `_.map`.
  355. _.initial = function(array, n, guard) {
  356. return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
  357. };
  358. // Get the last element of an array. Passing **n** will return the last N
  359. // values in the array. The **guard** check allows it to work with `_.map`.
  360. _.last = function(array, n, guard) {
  361. if (array == null) return void 0;
  362. if ((n != null) && !guard) {
  363. return slice.call(array, Math.max(array.length - n, 0));
  364. } else {
  365. return array[array.length - 1];
  366. }
  367. };
  368. // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
  369. // Especially useful on the arguments object. Passing an **n** will return
  370. // the rest N values in the array. The **guard**
  371. // check allows it to work with `_.map`.
  372. _.rest = _.tail = _.drop = function(array, n, guard) {
  373. return slice.call(array, (n == null) || guard ? 1 : n);
  374. };
  375. // Trim out all falsy values from an array.
  376. _.compact = function(array) {
  377. return _.filter(array, _.identity);
  378. };
  379. // Internal implementation of a recursive `flatten` function.
  380. var flatten = function(input, shallow, output) {
  381. if (shallow && _.every(input, _.isArray)) {
  382. return concat.apply(output, input);
  383. }
  384. each(input, function(value) {
  385. if (_.isArray(value) || _.isArguments(value)) {
  386. shallow ? push.apply(output, value) : flatten(value, shallow, output);
  387. } else {
  388. output.push(value);
  389. }
  390. });
  391. return output;
  392. };
  393. // Return a completely flattened version of an array.
  394. _.flatten = function(array, shallow) {
  395. return flatten(array, shallow, []);
  396. };
  397. // Return a version of the array that does not contain the specified value(s).
  398. _.without = function(array) {
  399. return _.difference(array, slice.call(arguments, 1));
  400. };
  401. // Produce a duplicate-free version of the array. If the array has already
  402. // been sorted, you have the option of using a faster algorithm.
  403. // Aliased as `unique`.
  404. _.uniq = _.unique = function(array, isSorted, iterator, context) {
  405. if (_.isFunction(isSorted)) {
  406. context = iterator;
  407. iterator = isSorted;
  408. isSorted = false;
  409. }
  410. var initial = iterator ? _.map(array, iterator, context) : array;
  411. var results = [];
  412. var seen = [];
  413. each(initial, function(value, index) {
  414. if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
  415. seen.push(value);
  416. results.push(array[index]);
  417. }
  418. });
  419. return results;
  420. };
  421. // Produce an array that contains the union: each distinct element from all of
  422. // the passed-in arrays.
  423. _.union = function() {
  424. return _.uniq(_.flatten(arguments, true));
  425. };
  426. // Produce an array that contains every item shared between all the
  427. // passed-in arrays.
  428. _.intersection = function(array) {
  429. var rest = slice.call(arguments, 1);
  430. return _.filter(_.uniq(array), function(item) {
  431. return _.every(rest, function(other) {
  432. return _.indexOf(other, item) >= 0;
  433. });
  434. });
  435. };
  436. // Take the difference between one array and a number of other arrays.
  437. // Only the elements present in just the first array will remain.
  438. _.difference = function(array) {
  439. var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
  440. return _.filter(array, function(value){ return !_.contains(rest, value); });
  441. };
  442. // Zip together multiple lists into a single array -- elements that share
  443. // an index go together.
  444. _.zip = function() {
  445. var length = _.max(_.pluck(arguments, "length").concat(0));
  446. var results = new Array(length);
  447. for (var i = 0; i < length; i++) {
  448. results[i] = _.pluck(arguments, '' + i);
  449. }
  450. return results;
  451. };
  452. // Converts lists into objects. Pass either a single array of `[key, value]`
  453. // pairs, or two parallel arrays of the same length -- one of keys, and one of
  454. // the corresponding values.
  455. _.object = function(list, values) {
  456. if (list == null) return {};
  457. var result = {};
  458. for (var i = 0, l = list.length; i < l; i++) {
  459. if (values) {
  460. result[list[i]] = values[i];
  461. } else {
  462. result[list[i][0]] = list[i][1];
  463. }
  464. }
  465. return result;
  466. };
  467. // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
  468. // we need this function. Return the position of the first occurrence of an
  469. // item in an array, or -1 if the item is not included in the array.
  470. // Delegates to **ECMAScript 5**'s native `indexOf` if available.
  471. // If the array is large and already in sort order, pass `true`
  472. // for **isSorted** to use binary search.
  473. _.indexOf = function(array, item, isSorted) {
  474. if (array == null) return -1;
  475. var i = 0, l = array.length;
  476. if (isSorted) {
  477. if (typeof isSorted == 'number') {
  478. i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
  479. } else {
  480. i = _.sortedIndex(array, item);
  481. return array[i] === item ? i : -1;
  482. }
  483. }
  484. if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
  485. for (; i < l; i++) if (array[i] === item) return i;
  486. return -1;
  487. };
  488. // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
  489. _.lastIndexOf = function(array, item, from) {
  490. if (array == null) return -1;
  491. var hasIndex = from != null;
  492. if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
  493. return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
  494. }
  495. var i = (hasIndex ? from : array.length);
  496. while (i--) if (array[i] === item) return i;
  497. return -1;
  498. };
  499. // Generate an integer Array containing an arithmetic progression. A port of
  500. // the native Python `range()` function. See
  501. // [the Python documentation](http://docs.python.org/library/functions.html#range).
  502. _.range = function(start, stop, step) {
  503. if (arguments.length <= 1) {
  504. stop = start || 0;
  505. start = 0;
  506. }
  507. step = arguments[2] || 1;
  508. var len = Math.max(Math.ceil((stop - start) / step), 0);
  509. var idx = 0;
  510. var range = new Array(len);
  511. while(idx < len) {
  512. range[idx++] = start;
  513. start += step;
  514. }
  515. return range;
  516. };
  517. // Function (ahem) Functions
  518. // ------------------
  519. // Reusable constructor function for prototype setting.
  520. var ctor = function(){};
  521. // Create a function bound to a given object (assigning `this`, and arguments,
  522. // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
  523. // available.
  524. _.bind = function(func, context) {
  525. var args, bound;
  526. if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
  527. if (!_.isFunction(func)) throw new TypeError;
  528. args = slice.call(arguments, 2);
  529. return bound = function() {
  530. if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
  531. ctor.prototype = func.prototype;
  532. var self = new ctor;
  533. ctor.prototype = null;
  534. var result = func.apply(self, args.concat(slice.call(arguments)));
  535. if (Object(result) === result) return result;
  536. return self;
  537. };
  538. };
  539. // Partially apply a function by creating a version that has had some of its
  540. // arguments pre-filled, without changing its dynamic `this` context.
  541. _.partial = function(func) {
  542. var args = slice.call(arguments, 1);
  543. return function() {
  544. return func.apply(this, args.concat(slice.call(arguments)));
  545. };
  546. };
  547. // Bind all of an object's methods to that object. Useful for ensuring that
  548. // all callbacks defined on an object belong to it.
  549. _.bindAll = function(obj) {
  550. var funcs = slice.call(arguments, 1);
  551. if (funcs.length === 0) throw new Error("bindAll must be passed function names");
  552. each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
  553. return obj;
  554. };
  555. // Memoize an expensive function by storing its results.
  556. _.memoize = function(func, hasher) {
  557. var memo = {};
  558. hasher || (hasher = _.identity);
  559. return function() {
  560. var key = hasher.apply(this, arguments);
  561. return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
  562. };
  563. };
  564. // Delays a function for the given number of milliseconds, and then calls
  565. // it with the arguments supplied.
  566. _.delay = function(func, wait) {
  567. var args = slice.call(arguments, 2);
  568. return setTimeout(function(){ return func.apply(null, args); }, wait);
  569. };
  570. // Defers a function, scheduling it to run after the current call stack has
  571. // cleared.
  572. _.defer = function(func) {
  573. return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
  574. };
  575. // Returns a function, that, when invoked, will only be triggered at most once
  576. // during a given window of time. Normally, the throttled function will run
  577. // as much as it can, without ever going more than once per `wait` duration;
  578. // but if you'd like to disable the execution on the leading edge, pass
  579. // `{leading: false}`. To disable execution on the trailing edge, ditto.
  580. _.throttle = function(func, wait, options) {
  581. var context, args, result;
  582. var timeout = null;
  583. var previous = 0;
  584. options || (options = {});
  585. var later = function() {
  586. previous = options.leading === false ? 0 : new Date;
  587. timeout = null;
  588. result = func.apply(context, args);
  589. };
  590. return function() {
  591. var now = new Date;
  592. if (!previous && options.leading === false) previous = now;
  593. var remaining = wait - (now - previous);
  594. context = this;
  595. args = arguments;
  596. if (remaining <= 0) {
  597. clearTimeout(timeout);
  598. timeout = null;
  599. previous = now;
  600. result = func.apply(context, args);
  601. } else if (!timeout && options.trailing !== false) {
  602. timeout = setTimeout(later, remaining);
  603. }
  604. return result;
  605. };
  606. };
  607. // Returns a function, that, as long as it continues to be invoked, will not
  608. // be triggered. The function will be called after it stops being called for
  609. // N milliseconds. If `immediate` is passed, trigger the function on the
  610. // leading edge, instead of the trailing.
  611. _.debounce = function(func, wait, immediate) {
  612. var result;
  613. var timeout = null;
  614. return function() {
  615. var context = this, args = arguments;
  616. var later = function() {
  617. timeout = null;
  618. if (!immediate) result = func.apply(context, args);
  619. };
  620. var callNow = immediate && !timeout;
  621. clearTimeout(timeout);
  622. timeout = setTimeout(later, wait);
  623. if (callNow) result = func.apply(context, args);
  624. return result;
  625. };
  626. };
  627. // Returns a function that will be executed at most one time, no matter how
  628. // often you call it. Useful for lazy initialization.
  629. _.once = function(func) {
  630. var ran = false, memo;
  631. return function() {
  632. if (ran) return memo;
  633. ran = true;
  634. memo = func.apply(this, arguments);
  635. func = null;
  636. return memo;
  637. };
  638. };
  639. // Returns the first function passed as an argument to the second,
  640. // allowing you to adjust arguments, run code before and after, and
  641. // conditionally execute the original function.
  642. _.wrap = function(func, wrapper) {
  643. return function() {
  644. var args = [func];
  645. push.apply(args, arguments);
  646. return wrapper.apply(this, args);
  647. };
  648. };
  649. // Returns a function that is the composition of a list of functions, each
  650. // consuming the return value of the function that follows.
  651. _.compose = function() {
  652. var funcs = arguments;
  653. return function() {
  654. var args = arguments;
  655. for (var i = funcs.length - 1; i >= 0; i--) {
  656. args = [funcs[i].apply(this, args)];
  657. }
  658. return args[0];
  659. };
  660. };
  661. // Returns a function that will only be executed after being called N times.
  662. _.after = function(times, func) {
  663. return function() {
  664. if (--times < 1) {
  665. return func.apply(this, arguments);
  666. }
  667. };
  668. };
  669. // Object Functions
  670. // ----------------
  671. // Retrieve the names of an object's properties.
  672. // Delegates to **ECMAScript 5**'s native `Object.keys`
  673. _.keys = nativeKeys || function(obj) {
  674. if (obj !== Object(obj)) throw new TypeError('Invalid object');
  675. var keys = [];
  676. for (var key in obj) if (_.has(obj, key)) keys.push(key);
  677. return keys;
  678. };
  679. // Retrieve the values of an object's properties.
  680. _.values = function(obj) {
  681. var values = [];
  682. for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
  683. return values;
  684. };
  685. // Convert an object into a list of `[key, value]` pairs.
  686. _.pairs = function(obj) {
  687. var pairs = [];
  688. for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
  689. return pairs;
  690. };
  691. // Invert the keys and values of an object. The values must be serializable.
  692. _.invert = function(obj) {
  693. var result = {};
  694. for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
  695. return result;
  696. };
  697. // Return a sorted list of the function names available on the object.
  698. // Aliased as `methods`
  699. _.functions = _.methods = function(obj) {
  700. var names = [];
  701. for (var key in obj) {
  702. if (_.isFunction(obj[key])) names.push(key);
  703. }
  704. return names.sort();
  705. };
  706. // Extend a given object with all the properties in passed-in object(s).
  707. _.extend = function(obj) {
  708. each(slice.call(arguments, 1), function(source) {
  709. if (source) {
  710. for (var prop in source) {
  711. obj[prop] = source[prop];
  712. }
  713. }
  714. });
  715. return obj;
  716. };
  717. // Return a copy of the object only containing the whitelisted properties.
  718. _.pick = function(obj) {
  719. var copy = {};
  720. var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
  721. each(keys, function(key) {
  722. if (key in obj) copy[key] = obj[key];
  723. });
  724. return copy;
  725. };
  726. // Return a copy of the object without the blacklisted properties.
  727. _.omit = function(obj) {
  728. var copy = {};
  729. var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
  730. for (var key in obj) {
  731. if (!_.contains(keys, key)) copy[key] = obj[key];
  732. }
  733. return copy;
  734. };
  735. // Fill in a given object with default properties.
  736. _.defaults = function(obj) {
  737. each(slice.call(arguments, 1), function(source) {
  738. if (source) {
  739. for (var prop in source) {
  740. if (obj[prop] === void 0) obj[prop] = source[prop];
  741. }
  742. }
  743. });
  744. return obj;
  745. };
  746. // Create a (shallow-cloned) duplicate of an object.
  747. _.clone = function(obj) {
  748. if (!_.isObject(obj)) return obj;
  749. return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
  750. };
  751. // Invokes interceptor with the obj, and then returns obj.
  752. // The primary purpose of this method is to "tap into" a method chain, in
  753. // order to perform operations on intermediate results within the chain.
  754. _.tap = function(obj, interceptor) {
  755. interceptor(obj);
  756. return obj;
  757. };
  758. // Internal recursive comparison function for `isEqual`.
  759. var eq = function(a, b, aStack, bStack) {
  760. // Identical objects are equal. `0 === -0`, but they aren't identical.
  761. // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
  762. if (a === b) return a !== 0 || 1 / a == 1 / b;
  763. // A strict comparison is necessary because `null == undefined`.
  764. if (a == null || b == null) return a === b;
  765. // Unwrap any wrapped objects.
  766. if (a instanceof _) a = a._wrapped;
  767. if (b instanceof _) b = b._wrapped;
  768. // Compare `[[Class]]` names.
  769. var className = toString.call(a);
  770. if (className != toString.call(b)) return false;
  771. switch (className) {
  772. // Strings, numbers, dates, and booleans are compared by value.
  773. case '[object String]':
  774. // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
  775. // equivalent to `new String("5")`.
  776. return a == String(b);
  777. case '[object Number]':
  778. // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
  779. // other numeric values.
  780. return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
  781. case '[object Date]':
  782. case '[object Boolean]':
  783. // Coerce dates and booleans to numeric primitive values. Dates are compared by their
  784. // millisecond representations. Note that invalid dates with millisecond representations
  785. // of `NaN` are not equivalent.
  786. return +a == +b;
  787. // RegExps are compared by their source patterns and flags.
  788. case '[object RegExp]':
  789. return a.source == b.source &&
  790. a.global == b.global &&
  791. a.multiline == b.multiline &&
  792. a.ignoreCase == b.ignoreCase;
  793. }
  794. if (typeof a != 'object' || typeof b != 'object') return false;
  795. // Assume equality for cyclic structures. The algorithm for detecting cyclic
  796. // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
  797. var length = aStack.length;
  798. while (length--) {
  799. // Linear search. Performance is inversely proportional to the number of
  800. // unique nested structures.
  801. if (aStack[length] == a) return bStack[length] == b;
  802. }
  803. // Objects with different constructors are not equivalent, but `Object`s
  804. // from different frames are.
  805. var aCtor = a.constructor, bCtor = b.constructor;
  806. if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
  807. _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
  808. return false;
  809. }
  810. // Add the first object to the stack of traversed objects.
  811. aStack.push(a);
  812. bStack.push(b);
  813. var size = 0, result = true;
  814. // Recursively compare objects and arrays.
  815. if (className == '[object Array]') {
  816. // Compare array lengths to determine if a deep comparison is necessary.
  817. size = a.length;
  818. result = size == b.length;
  819. if (result) {
  820. // Deep compare the contents, ignoring non-numeric properties.
  821. while (size--) {
  822. if (!(result = eq(a[size], b[size], aStack, bStack))) break;
  823. }
  824. }
  825. } else {
  826. // Deep compare objects.
  827. for (var key in a) {
  828. if (_.has(a, key)) {
  829. // Count the expected number of properties.
  830. size++;
  831. // Deep compare each member.
  832. if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
  833. }
  834. }
  835. // Ensure that both objects contain the same number of properties.
  836. if (result) {
  837. for (key in b) {
  838. if (_.has(b, key) && !(size--)) break;
  839. }
  840. result = !size;
  841. }
  842. }
  843. // Remove the first object from the stack of traversed objects.
  844. aStack.pop();
  845. bStack.pop();
  846. return result;
  847. };
  848. // Perform a deep comparison to check if two objects are equal.
  849. _.isEqual = function(a, b) {
  850. return eq(a, b, [], []);
  851. };
  852. // Is a given array, string, or object empty?
  853. // An "empty" object has no enumerable own-properties.
  854. _.isEmpty = function(obj) {
  855. if (obj == null) return true;
  856. if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
  857. for (var key in obj) if (_.has(obj, key)) return false;
  858. return true;
  859. };
  860. // Is a given value a DOM element?
  861. _.isElement = function(obj) {
  862. return !!(obj && obj.nodeType === 1);
  863. };
  864. // Is a given value an array?
  865. // Delegates to ECMA5's native Array.isArray
  866. _.isArray = nativeIsArray || function(obj) {
  867. return toString.call(obj) == '[object Array]';
  868. };
  869. // Is a given variable an object?
  870. _.isObject = function(obj) {
  871. return obj === Object(obj);
  872. };
  873. // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
  874. each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
  875. _['is' + name] = function(obj) {
  876. return toString.call(obj) == '[object ' + name + ']';
  877. };
  878. });
  879. // Define a fallback version of the method in browsers (ahem, IE), where
  880. // there isn't any inspectable "Arguments" type.
  881. if (!_.isArguments(arguments)) {
  882. _.isArguments = function(obj) {
  883. return !!(obj && _.has(obj, 'callee'));
  884. };
  885. }
  886. // Optimize `isFunction` if appropriate.
  887. if (typeof (/./) !== 'function') {
  888. _.isFunction = function(obj) {
  889. return typeof obj === 'function';
  890. };
  891. }
  892. // Is a given object a finite number?
  893. _.isFinite = function(obj) {
  894. return isFinite(obj) && !isNaN(parseFloat(obj));
  895. };
  896. // Is the given value `NaN`? (NaN is the only number which does not equal itself).
  897. _.isNaN = function(obj) {
  898. return _.isNumber(obj) && obj != +obj;
  899. };
  900. // Is a given value a boolean?
  901. _.isBoolean = function(obj) {
  902. return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
  903. };
  904. // Is a given value equal to null?
  905. _.isNull = function(obj) {
  906. return obj === null;
  907. };
  908. // Is a given variable undefined?
  909. _.isUndefined = function(obj) {
  910. return obj === void 0;
  911. };
  912. // Shortcut function for checking if an object has a given property directly
  913. // on itself (in other words, not on a prototype).
  914. _.has = function(obj, key) {
  915. return hasOwnProperty.call(obj, key);
  916. };
  917. // Utility Functions
  918. // -----------------
  919. // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
  920. // previous owner. Returns a reference to the Underscore object.
  921. _.noConflict = function() {
  922. root._ = previousUnderscore;
  923. return this;
  924. };
  925. // Keep the identity function around for default iterators.
  926. _.identity = function(value) {
  927. return value;
  928. };
  929. // Run a function **n** times.
  930. _.times = function(n, iterator, context) {
  931. var accum = Array(Math.max(0, n));
  932. for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
  933. return accum;
  934. };
  935. // Return a random integer between min and max (inclusive).
  936. _.random = function(min, max) {
  937. if (max == null) {
  938. max = min;
  939. min = 0;
  940. }
  941. return min + Math.floor(Math.random() * (max - min + 1));
  942. };
  943. // List of HTML entities for escaping.
  944. var entityMap = {
  945. escape: {
  946. '&': '&amp;',
  947. '<': '&lt;',
  948. '>': '&gt;',
  949. '"': '&quot;',
  950. "'": '&#x27;',
  951. '/': '&#x2F;'
  952. }
  953. };
  954. entityMap.unescape = _.invert(entityMap.escape);
  955. // Regexes containing the keys and values listed immediately above.
  956. var entityRegexes = {
  957. escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
  958. unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
  959. };
  960. // Functions for escaping and unescaping strings to/from HTML interpolation.
  961. _.each(['escape', 'unescape'], function(method) {
  962. _[method] = function(string) {
  963. if (string == null) return '';
  964. return ('' + string).replace(entityRegexes[method], function(match) {
  965. return entityMap[method][match];
  966. });
  967. };
  968. });
  969. // If the value of the named `property` is a function then invoke it with the
  970. // `object` as context; otherwise, return it.
  971. _.result = function(object, property) {
  972. if (object == null) return void 0;
  973. var value = object[property];
  974. return _.isFunction(value) ? value.call(object) : value;
  975. };
  976. // Add your own custom functions to the Underscore object.
  977. _.mixin = function(obj) {
  978. each(_.functions(obj), function(name){
  979. var func = _[name] = obj[name];
  980. _.prototype[name] = function() {
  981. var args = [this._wrapped];
  982. push.apply(args, arguments);
  983. return result.call(this, func.apply(_, args));
  984. };
  985. });
  986. };
  987. // Generate a unique integer id (unique within the entire client session).
  988. // Useful for temporary DOM ids.
  989. var idCounter = 0;
  990. _.uniqueId = function(prefix) {
  991. var id = ++idCounter + '';
  992. return prefix ? prefix + id : id;
  993. };
  994. // By default, Underscore uses ERB-style template delimiters, change the
  995. // following template settings to use alternative delimiters.
  996. _.templateSettings = {
  997. evaluate : /<%([\s\S]+?)%>/g,
  998. interpolate : /<%=([\s\S]+?)%>/g,
  999. escape : /<%-([\s\S]+?)%>/g
  1000. };
  1001. // When customizing `templateSettings`, if you don't want to define an
  1002. // interpolation, evaluation or escaping regex, we need one that is
  1003. // guaranteed not to match.
  1004. var noMatch = /(.)^/;
  1005. // Certain characters need to be escaped so that they can be put into a
  1006. // string literal.
  1007. var escapes = {
  1008. "'": "'",
  1009. '\\': '\\',
  1010. '\r': 'r',
  1011. '\n': 'n',
  1012. '\t': 't',
  1013. '\u2028': 'u2028',
  1014. '\u2029': 'u2029'
  1015. };
  1016. var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
  1017. // JavaScript micro-templating, similar to John Resig's implementation.
  1018. // Underscore templating handles arbitrary delimiters, preserves whitespace,
  1019. // and correctly escapes quotes within interpolated code.
  1020. _.template = function(text, data, settings) {
  1021. var render;
  1022. settings = _.defaults({}, settings, _.templateSettings);
  1023. // Combine delimiters into one regular expression via alternation.
  1024. var matcher = new RegExp([
  1025. (settings.escape || noMatch).source,
  1026. (settings.interpolate || noMatch).source,
  1027. (settings.evaluate || noMatch).source
  1028. ].join('|') + '|$', 'g');
  1029. // Compile the template source, escaping string literals appropriately.
  1030. var index = 0;
  1031. var source = "__p+='";
  1032. text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
  1033. source += text.slice(index, offset)
  1034. .replace(escaper, function(match) { return '\\' + escapes[match]; });
  1035. if (escape) {
  1036. source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
  1037. }
  1038. if (interpolate) {
  1039. source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
  1040. }
  1041. if (evaluate) {
  1042. source += "';\n" + evaluate + "\n__p+='";
  1043. }
  1044. index = offset + match.length;
  1045. return match;
  1046. });
  1047. source += "';\n";
  1048. // If a variable is not specified, place data values in local scope.
  1049. if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
  1050. source = "var __t,__p='',__j=Array.prototype.join," +
  1051. "print=function(){__p+=__j.call(arguments,'');};\n" +
  1052. source + "return __p;\n";
  1053. try {
  1054. render = new Function(settings.variable || 'obj', '_', source);
  1055. } catch (e) {
  1056. e.source = source;
  1057. throw e;
  1058. }
  1059. if (data) return render(data, _);
  1060. var template = function(data) {
  1061. return render.call(this, data, _);
  1062. };
  1063. // Provide the compiled function source as a convenience for precompilation.
  1064. template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
  1065. return template;
  1066. };
  1067. // Add a "chain" function, which will delegate to the wrapper.
  1068. _.chain = function(obj) {
  1069. return _(obj).chain();
  1070. };
  1071. // OOP
  1072. // ---------------
  1073. // If Underscore is called as a function, it returns a wrapped object that
  1074. // can be used OO-style. This wrapper holds altered versions of all the
  1075. // underscore functions. Wrapped objects may be chained.
  1076. // Helper function to continue chaining intermediate results.
  1077. var result = function(obj) {
  1078. return this._chain ? _(obj).chain() : obj;
  1079. };
  1080. // Add all of the Underscore functions to the wrapper object.
  1081. _.mixin(_);
  1082. // Add all mutator Array functions to the wrapper.
  1083. each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
  1084. var method = ArrayProto[name];
  1085. _.prototype[name] = function() {
  1086. var obj = this._wrapped;
  1087. method.apply(obj, arguments);
  1088. if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
  1089. return result.call(this, obj);
  1090. };
  1091. });
  1092. // Add all accessor Array functions to the wrapper.
  1093. each(['concat', 'join', 'slice'], function(name) {
  1094. var method = ArrayProto[name];
  1095. _.prototype[name] = function() {
  1096. return result.call(this, method.apply(this._wrapped, arguments));
  1097. };
  1098. });
  1099. _.extend(_.prototype, {
  1100. // Start chaining a wrapped Underscore object.
  1101. chain: function() {
  1102. this._chain = true;
  1103. return this;
  1104. },
  1105. // Extracts the result from a wrapped and chained object.
  1106. value: function() {
  1107. return this._wrapped;
  1108. }
  1109. });
  1110. }).call(this);