summaryrefslogtreecommitdiff
path: root/webapp/vendor/underscore-1.7.0.js
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/vendor/underscore-1.7.0.js')
-rw-r--r--webapp/vendor/underscore-1.7.0.js1416
1 files changed, 1416 insertions, 0 deletions
diff --git a/webapp/vendor/underscore-1.7.0.js b/webapp/vendor/underscore-1.7.0.js
new file mode 100644
index 0000000..afd92e5
--- /dev/null
+++ b/webapp/vendor/underscore-1.7.0.js
@@ -0,0 +1,1416 @@
1// Underscore.js 1.7.0
2// http://underscorejs.org
3// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4// Underscore may be freely distributed under the MIT license.
5
6(function() {
7
8 // Baseline setup
9 // --------------
10
11 // Establish the root object, `window` in the browser, or `exports` on the server.
12 var root = this;
13
14 // Save the previous value of the `_` variable.
15 var previousUnderscore = root._;
16
17 // Save bytes in the minified (but not gzipped) version:
18 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
19
20 // Create quick reference variables for speed access to core prototypes.
21 var
22 push = ArrayProto.push,
23 slice = ArrayProto.slice,
24 concat = ArrayProto.concat,
25 toString = ObjProto.toString,
26 hasOwnProperty = ObjProto.hasOwnProperty;
27
28 // All **ECMAScript 5** native function implementations that we hope to use
29 // are declared here.
30 var
31 nativeIsArray = Array.isArray,
32 nativeKeys = Object.keys,
33 nativeBind = FuncProto.bind;
34
35 // Create a safe reference to the Underscore object for use below.
36 var _ = function(obj) {
37 if (obj instanceof _) return obj;
38 if (!(this instanceof _)) return new _(obj);
39 this._wrapped = obj;
40 };
41
42 // Export the Underscore object for **Node.js**, with
43 // backwards-compatibility for the old `require()` API. If we're in
44 // the browser, add `_` as a global object.
45 if (typeof exports !== 'undefined') {
46 if (typeof module !== 'undefined' && module.exports) {
47 exports = module.exports = _;
48 }
49 exports._ = _;
50 } else {
51 root._ = _;
52 }
53
54 // Current version.
55 _.VERSION = '1.7.0';
56
57 // Internal function that returns an efficient (for current engines) version
58 // of the passed-in callback, to be repeatedly applied in other Underscore
59 // functions.
60 var createCallback = function(func, context, argCount) {
61 if (context === void 0) return func;
62 switch (argCount == null ? 3 : argCount) {
63 case 1: return function(value) {
64 return func.call(context, value);
65 };
66 case 2: return function(value, other) {
67 return func.call(context, value, other);
68 };
69 case 3: return function(value, index, collection) {
70 return func.call(context, value, index, collection);
71 };
72 case 4: return function(accumulator, value, index, collection) {
73 return func.call(context, accumulator, value, index, collection);
74 };
75 }
76 return function() {
77 return func.apply(context, arguments);
78 };
79 };
80
81 // A mostly-internal function to generate callbacks that can be applied
82 // to each element in a collection, returning the desired result — either
83 // identity, an arbitrary callback, a property matcher, or a property accessor.
84 _.iteratee = function(value, context, argCount) {
85 if (value == null) return _.identity;
86 if (_.isFunction(value)) return createCallback(value, context, argCount);
87 if (_.isObject(value)) return _.matches(value);
88 return _.property(value);
89 };
90
91 // Collection Functions
92 // --------------------
93
94 // The cornerstone, an `each` implementation, aka `forEach`.
95 // Handles raw objects in addition to array-likes. Treats all
96 // sparse array-likes as if they were dense.
97 _.each = _.forEach = function(obj, iteratee, context) {
98 if (obj == null) return obj;
99 iteratee = createCallback(iteratee, context);
100 var i, length = obj.length;
101 if (length === +length) {
102 for (i = 0; i < length; i++) {
103 iteratee(obj[i], i, obj);
104 }
105 } else {
106 var keys = _.keys(obj);
107 for (i = 0, length = keys.length; i < length; i++) {
108 iteratee(obj[keys[i]], keys[i], obj);
109 }
110 }
111 return obj;
112 };
113
114 // Return the results of applying the iteratee to each element.
115 _.map = _.collect = function(obj, iteratee, context) {
116 if (obj == null) return [];
117 iteratee = _.iteratee(iteratee, context);
118 var keys = obj.length !== +obj.length && _.keys(obj),
119 length = (keys || obj).length,
120 results = Array(length),
121 currentKey;
122 for (var index = 0; index < length; index++) {
123 currentKey = keys ? keys[index] : index;
124 results[index] = iteratee(obj[currentKey], currentKey, obj);
125 }
126 return results;
127 };
128
129 var reduceError = 'Reduce of empty array with no initial value';
130
131 // **Reduce** builds up a single result from a list of values, aka `inject`,
132 // or `foldl`.
133 _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) {
134 if (obj == null) obj = [];
135 iteratee = createCallback(iteratee, context, 4);
136 var keys = obj.length !== +obj.length && _.keys(obj),
137 length = (keys || obj).length,
138 index = 0, currentKey;
139 if (arguments.length < 3) {
140 if (!length) throw new TypeError(reduceError);
141 memo = obj[keys ? keys[index++] : index++];
142 }
143 for (; index < length; index++) {
144 currentKey = keys ? keys[index] : index;
145 memo = iteratee(memo, obj[currentKey], currentKey, obj);
146 }
147 return memo;
148 };
149
150 // The right-associative version of reduce, also known as `foldr`.
151 _.reduceRight = _.foldr = function(obj, iteratee, memo, context) {
152 if (obj == null) obj = [];
153 iteratee = createCallback(iteratee, context, 4);
154 var keys = obj.length !== + obj.length && _.keys(obj),
155 index = (keys || obj).length,
156 currentKey;
157 if (arguments.length < 3) {
158 if (!index) throw new TypeError(reduceError);
159 memo = obj[keys ? keys[--index] : --index];
160 }
161 while (index--) {
162 currentKey = keys ? keys[index] : index;
163 memo = iteratee(memo, obj[currentKey], currentKey, obj);
164 }
165 return memo;
166 };
167
168 // Return the first value which passes a truth test. Aliased as `detect`.
169 _.find = _.detect = function(obj, predicate, context) {
170 var result;
171 predicate = _.iteratee(predicate, context);
172 _.some(obj, function(value, index, list) {
173 if (predicate(value, index, list)) {
174 result = value;
175 return true;
176 }
177 });
178 return result;
179 };
180
181 // Return all the elements that pass a truth test.
182 // Aliased as `select`.
183 _.filter = _.select = function(obj, predicate, context) {
184 var results = [];
185 if (obj == null) return results;
186 predicate = _.iteratee(predicate, context);
187 _.each(obj, function(value, index, list) {
188 if (predicate(value, index, list)) results.push(value);
189 });
190 return results;
191 };
192
193 // Return all the elements for which a truth test fails.
194 _.reject = function(obj, predicate, context) {
195 return _.filter(obj, _.negate(_.iteratee(predicate)), context);
196 };
197
198 // Determine whether all of the elements match a truth test.
199 // Aliased as `all`.
200 _.every = _.all = function(obj, predicate, context) {
201 if (obj == null) return true;
202 predicate = _.iteratee(predicate, context);
203 var keys = obj.length !== +obj.length && _.keys(obj),
204 length = (keys || obj).length,
205 index, currentKey;
206 for (index = 0; index < length; index++) {
207 currentKey = keys ? keys[index] : index;
208 if (!predicate(obj[currentKey], currentKey, obj)) return false;
209 }
210 return true;
211 };
212
213 // Determine if at least one element in the object matches a truth test.
214 // Aliased as `any`.
215 _.some = _.any = function(obj, predicate, context) {
216 if (obj == null) return false;
217 predicate = _.iteratee(predicate, context);
218 var keys = obj.length !== +obj.length && _.keys(obj),
219 length = (keys || obj).length,
220 index, currentKey;
221 for (index = 0; index < length; index++) {
222 currentKey = keys ? keys[index] : index;
223 if (predicate(obj[currentKey], currentKey, obj)) return true;
224 }
225 return false;
226 };
227
228 // Determine if the array or object contains a given value (using `===`).
229 // Aliased as `include`.
230 _.contains = _.include = function(obj, target) {
231 if (obj == null) return false;
232 if (obj.length !== +obj.length) obj = _.values(obj);
233 return _.indexOf(obj, target) >= 0;
234 };
235
236 // Invoke a method (with arguments) on every item in a collection.
237 _.invoke = function(obj, method) {
238 var args = slice.call(arguments, 2);
239 var isFunc = _.isFunction(method);
240 return _.map(obj, function(value) {
241 return (isFunc ? method : value[method]).apply(value, args);
242 });
243 };
244
245 // Convenience version of a common use case of `map`: fetching a property.
246 _.pluck = function(obj, key) {
247 return _.map(obj, _.property(key));
248 };
249
250 // Convenience version of a common use case of `filter`: selecting only objects
251 // containing specific `key:value` pairs.
252 _.where = function(obj, attrs) {
253 return _.filter(obj, _.matches(attrs));
254 };
255
256 // Convenience version of a common use case of `find`: getting the first object
257 // containing specific `key:value` pairs.
258 _.findWhere = function(obj, attrs) {
259 return _.find(obj, _.matches(attrs));
260 };
261
262 // Return the maximum element (or element-based computation).
263 _.max = function(obj, iteratee, context) {
264 var result = -Infinity, lastComputed = -Infinity,
265 value, computed;
266 if (iteratee == null && obj != null) {
267 obj = obj.length === +obj.length ? obj : _.values(obj);
268 for (var i = 0, length = obj.length; i < length; i++) {
269 value = obj[i];
270 if (value > result) {
271 result = value;
272 }
273 }
274 } else {
275 iteratee = _.iteratee(iteratee, context);
276 _.each(obj, function(value, index, list) {
277 computed = iteratee(value, index, list);
278 if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
279 result = value;
280 lastComputed = computed;
281 }
282 });
283 }
284 return result;
285 };
286
287 // Return the minimum element (or element-based computation).
288 _.min = function(obj, iteratee, context) {
289 var result = Infinity, lastComputed = Infinity,
290 value, computed;
291 if (iteratee == null && obj != null) {
292 obj = obj.length === +obj.length ? obj : _.values(obj);
293 for (var i = 0, length = obj.length; i < length; i++) {
294 value = obj[i];
295 if (value < result) {
296 result = value;
297 }
298 }
299 } else {
300 iteratee = _.iteratee(iteratee, context);
301 _.each(obj, function(value, index, list) {
302 computed = iteratee(value, index, list);
303 if (computed < lastComputed || computed === Infinity && result === Infinity) {
304 result = value;
305 lastComputed = computed;
306 }
307 });
308 }
309 return result;
310 };
311
312 // Shuffle a collection, using the modern version of the
313 // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
314 _.shuffle = function(obj) {
315 var set = obj && obj.length === +obj.length ? obj : _.values(obj);
316 var length = set.length;
317 var shuffled = Array(length);
318 for (var index = 0, rand; index < length; index++) {
319 rand = _.random(0, index);
320 if (rand !== index) shuffled[index] = shuffled[rand];
321 shuffled[rand] = set[index];
322 }
323 return shuffled;
324 };
325
326 // Sample **n** random values from a collection.
327 // If **n** is not specified, returns a single random element.
328 // The internal `guard` argument allows it to work with `map`.
329 _.sample = function(obj, n, guard) {
330 if (n == null || guard) {
331 if (obj.length !== +obj.length) obj = _.values(obj);
332 return obj[_.random(obj.length - 1)];
333 }
334 return _.shuffle(obj).slice(0, Math.max(0, n));
335 };
336
337 // Sort the object's values by a criterion produced by an iteratee.
338 _.sortBy = function(obj, iteratee, context) {
339 iteratee = _.iteratee(iteratee, context);
340 return _.pluck(_.map(obj, function(value, index, list) {
341 return {
342 value: value,
343 index: index,
344 criteria: iteratee(value, index, list)
345 };
346 }).sort(function(left, right) {
347 var a = left.criteria;
348 var b = right.criteria;
349 if (a !== b) {
350 if (a > b || a === void 0) return 1;
351 if (a < b || b === void 0) return -1;
352 }
353 return left.index - right.index;
354 }), 'value');
355 };
356
357 // An internal function used for aggregate "group by" operations.
358 var group = function(behavior) {
359 return function(obj, iteratee, context) {
360 var result = {};
361 iteratee = _.iteratee(iteratee, context);
362 _.each(obj, function(value, index) {
363 var key = iteratee(value, index, obj);
364 behavior(result, value, key);
365 });
366 return result;
367 };
368 };
369
370 // Groups the object's values by a criterion. Pass either a string attribute
371 // to group by, or a function that returns the criterion.
372 _.groupBy = group(function(result, value, key) {
373 if (_.has(result, key)) result[key].push(value); else result[key] = [value];
374 });
375
376 // Indexes the object's values by a criterion, similar to `groupBy`, but for
377 // when you know that your index values will be unique.
378 _.indexBy = group(function(result, value, key) {
379 result[key] = value;
380 });
381
382 // Counts instances of an object that group by a certain criterion. Pass
383 // either a string attribute to count by, or a function that returns the
384 // criterion.
385 _.countBy = group(function(result, value, key) {
386 if (_.has(result, key)) result[key]++; else result[key] = 1;
387 });
388
389 // Use a comparator function to figure out the smallest index at which
390 // an object should be inserted so as to maintain order. Uses binary search.
391 _.sortedIndex = function(array, obj, iteratee, context) {
392 iteratee = _.iteratee(iteratee, context, 1);
393 var value = iteratee(obj);
394 var low = 0, high = array.length;
395 while (low < high) {
396 var mid = low + high >>> 1;
397 if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
398 }
399 return low;
400 };
401
402 // Safely create a real, live array from anything iterable.
403 _.toArray = function(obj) {
404 if (!obj) return [];
405 if (_.isArray(obj)) return slice.call(obj);
406 if (obj.length === +obj.length) return _.map(obj, _.identity);
407 return _.values(obj);
408 };
409
410 // Return the number of elements in an object.
411 _.size = function(obj) {
412 if (obj == null) return 0;
413 return obj.length === +obj.length ? obj.length : _.keys(obj).length;
414 };
415
416 // Split a collection into two arrays: one whose elements all satisfy the given
417 // predicate, and one whose elements all do not satisfy the predicate.
418 _.partition = function(obj, predicate, context) {
419 predicate = _.iteratee(predicate, context);
420 var pass = [], fail = [];
421 _.each(obj, function(value, key, obj) {
422 (predicate(value, key, obj) ? pass : fail).push(value);
423 });
424 return [pass, fail];
425 };
426
427 // Array Functions
428 // ---------------
429
430 // Get the first element of an array. Passing **n** will return the first N
431 // values in the array. Aliased as `head` and `take`. The **guard** check
432 // allows it to work with `_.map`.
433 _.first = _.head = _.take = function(array, n, guard) {
434 if (array == null) return void 0;
435 if (n == null || guard) return array[0];
436 if (n < 0) return [];
437 return slice.call(array, 0, n);
438 };
439
440 // Returns everything but the last entry of the array. Especially useful on
441 // the arguments object. Passing **n** will return all the values in
442 // the array, excluding the last N. The **guard** check allows it to work with
443 // `_.map`.
444 _.initial = function(array, n, guard) {
445 return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
446 };
447
448 // Get the last element of an array. Passing **n** will return the last N
449 // values in the array. The **guard** check allows it to work with `_.map`.
450 _.last = function(array, n, guard) {
451 if (array == null) return void 0;
452 if (n == null || guard) return array[array.length - 1];
453 return slice.call(array, Math.max(array.length - n, 0));
454 };
455
456 // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
457 // Especially useful on the arguments object. Passing an **n** will return
458 // the rest N values in the array. The **guard**
459 // check allows it to work with `_.map`.
460 _.rest = _.tail = _.drop = function(array, n, guard) {
461 return slice.call(array, n == null || guard ? 1 : n);
462 };
463
464 // Trim out all falsy values from an array.
465 _.compact = function(array) {
466 return _.filter(array, _.identity);
467 };
468
469 // Internal implementation of a recursive `flatten` function.
470 var flatten = function(input, shallow, strict, output) {
471 if (shallow && _.every(input, _.isArray)) {
472 return concat.apply(output, input);
473 }
474 for (var i = 0, length = input.length; i < length; i++) {
475 var value = input[i];
476 if (!_.isArray(value) && !_.isArguments(value)) {
477 if (!strict) output.push(value);
478 } else if (shallow) {
479 push.apply(output, value);
480 } else {
481 flatten(value, shallow, strict, output);
482 }
483 }
484 return output;
485 };
486
487 // Flatten out an array, either recursively (by default), or just one level.
488 _.flatten = function(array, shallow) {
489 return flatten(array, shallow, false, []);
490 };
491
492 // Return a version of the array that does not contain the specified value(s).
493 _.without = function(array) {
494 return _.difference(array, slice.call(arguments, 1));
495 };
496
497 // Produce a duplicate-free version of the array. If the array has already
498 // been sorted, you have the option of using a faster algorithm.
499 // Aliased as `unique`.
500 _.uniq = _.unique = function(array, isSorted, iteratee, context) {
501 if (array == null) return [];
502 if (!_.isBoolean(isSorted)) {
503 context = iteratee;
504 iteratee = isSorted;
505 isSorted = false;
506 }
507 if (iteratee != null) iteratee = _.iteratee(iteratee, context);
508 var result = [];
509 var seen = [];
510 for (var i = 0, length = array.length; i < length; i++) {
511 var value = array[i];
512 if (isSorted) {
513 if (!i || seen !== value) result.push(value);
514 seen = value;
515 } else if (iteratee) {
516 var computed = iteratee(value, i, array);
517 if (_.indexOf(seen, computed) < 0) {
518 seen.push(computed);
519 result.push(value);
520 }
521 } else if (_.indexOf(result, value) < 0) {
522 result.push(value);
523 }
524 }
525 return result;
526 };
527
528 // Produce an array that contains the union: each distinct element from all of
529 // the passed-in arrays.
530 _.union = function() {
531 return _.uniq(flatten(arguments, true, true, []));
532 };
533
534 // Produce an array that contains every item shared between all the
535 // passed-in arrays.
536 _.intersection = function(array) {
537 if (array == null) return [];
538 var result = [];
539 var argsLength = arguments.length;
540 for (var i = 0, length = array.length; i < length; i++) {
541 var item = array[i];
542 if (_.contains(result, item)) continue;
543 for (var j = 1; j < argsLength; j++) {
544 if (!_.contains(arguments[j], item)) break;
545 }
546 if (j === argsLength) result.push(item);
547 }
548 return result;
549 };
550
551 // Take the difference between one array and a number of other arrays.
552 // Only the elements present in just the first array will remain.
553 _.difference = function(array) {
554 var rest = flatten(slice.call(arguments, 1), true, true, []);
555 return _.filter(array, function(value){
556 return !_.contains(rest, value);
557 });
558 };
559
560 // Zip together multiple lists into a single array -- elements that share
561 // an index go together.
562 _.zip = function(array) {
563 if (array == null) return [];
564 var length = _.max(arguments, 'length').length;
565 var results = Array(length);
566 for (var i = 0; i < length; i++) {
567 results[i] = _.pluck(arguments, i);
568 }
569 return results;
570 };
571
572 // Converts lists into objects. Pass either a single array of `[key, value]`
573 // pairs, or two parallel arrays of the same length -- one of keys, and one of
574 // the corresponding values.
575 _.object = function(list, values) {
576 if (list == null) return {};
577 var result = {};
578 for (var i = 0, length = list.length; i < length; i++) {
579 if (values) {
580 result[list[i]] = values[i];
581 } else {
582 result[list[i][0]] = list[i][1];
583 }
584 }
585 return result;
586 };
587
588 // Return the position of the first occurrence of an item in an array,
589 // or -1 if the item is not included in the array.
590 // If the array is large and already in sort order, pass `true`
591 // for **isSorted** to use binary search.
592 _.indexOf = function(array, item, isSorted) {
593 if (array == null) return -1;
594 var i = 0, length = array.length;
595 if (isSorted) {
596 if (typeof isSorted == 'number') {
597 i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
598 } else {
599 i = _.sortedIndex(array, item);
600 return array[i] === item ? i : -1;
601 }
602 }
603 for (; i < length; i++) if (array[i] === item) return i;
604 return -1;
605 };
606
607 _.lastIndexOf = function(array, item, from) {
608 if (array == null) return -1;
609 var idx = array.length;
610 if (typeof from == 'number') {
611 idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
612 }
613 while (--idx >= 0) if (array[idx] === item) return idx;
614 return -1;
615 };
616
617 // Generate an integer Array containing an arithmetic progression. A port of
618 // the native Python `range()` function. See
619 // [the Python documentation](http://docs.python.org/library/functions.html#range).
620 _.range = function(start, stop, step) {
621 if (arguments.length <= 1) {
622 stop = start || 0;
623 start = 0;
624 }
625 step = step || 1;
626
627 var length = Math.max(Math.ceil((stop - start) / step), 0);
628 var range = Array(length);
629
630 for (var idx = 0; idx < length; idx++, start += step) {
631 range[idx] = start;
632 }
633
634 return range;
635 };
636
637 // Function (ahem) Functions
638 // ------------------
639
640 // Reusable constructor function for prototype setting.
641 var Ctor = function(){};
642
643 // Create a function bound to a given object (assigning `this`, and arguments,
644 // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
645 // available.
646 _.bind = function(func, context) {
647 var args, bound;
648 if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
649 if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
650 args = slice.call(arguments, 2);
651 bound = function() {
652 if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
653 Ctor.prototype = func.prototype;
654 var self = new Ctor;
655 Ctor.prototype = null;
656 var result = func.apply(self, args.concat(slice.call(arguments)));
657 if (_.isObject(result)) return result;
658 return self;
659 };
660 return bound;
661 };
662
663 // Partially apply a function by creating a version that has had some of its
664 // arguments pre-filled, without changing its dynamic `this` context. _ acts
665 // as a placeholder, allowing any combination of arguments to be pre-filled.
666 _.partial = function(func) {
667 var boundArgs = slice.call(arguments, 1);
668 return function() {
669 var position = 0;
670 var args = boundArgs.slice();
671 for (var i = 0, length = args.length; i < length; i++) {
672 if (args[i] === _) args[i] = arguments[position++];
673 }
674 while (position < arguments.length) args.push(arguments[position++]);
675 return func.apply(this, args);
676 };
677 };
678
679 // Bind a number of an object's methods to that object. Remaining arguments
680 // are the method names to be bound. Useful for ensuring that all callbacks
681 // defined on an object belong to it.
682 _.bindAll = function(obj) {
683 var i, length = arguments.length, key;
684 if (length <= 1) throw new Error('bindAll must be passed function names');
685 for (i = 1; i < length; i++) {
686 key = arguments[i];
687 obj[key] = _.bind(obj[key], obj);
688 }
689 return obj;
690 };
691
692 // Memoize an expensive function by storing its results.
693 _.memoize = function(func, hasher) {
694 var memoize = function(key) {
695 var cache = memoize.cache;
696 var address = hasher ? hasher.apply(this, arguments) : key;
697 if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
698 return cache[address];
699 };
700 memoize.cache = {};
701 return memoize;
702 };
703
704 // Delays a function for the given number of milliseconds, and then calls
705 // it with the arguments supplied.
706 _.delay = function(func, wait) {
707 var args = slice.call(arguments, 2);
708 return setTimeout(function(){
709 return func.apply(null, args);
710 }, wait);
711 };
712
713 // Defers a function, scheduling it to run after the current call stack has
714 // cleared.
715 _.defer = function(func) {
716 return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
717 };
718
719 // Returns a function, that, when invoked, will only be triggered at most once
720 // during a given window of time. Normally, the throttled function will run
721 // as much as it can, without ever going more than once per `wait` duration;
722 // but if you'd like to disable the execution on the leading edge, pass
723 // `{leading: false}`. To disable execution on the trailing edge, ditto.
724 _.throttle = function(func, wait, options) {
725 var context, args, result;
726 var timeout = null;
727 var previous = 0;
728 if (!options) options = {};
729 var later = function() {
730 previous = options.leading === false ? 0 : _.now();
731 timeout = null;
732 result = func.apply(context, args);
733 if (!timeout) context = args = null;
734 };
735 return function() {
736 var now = _.now();
737 if (!previous && options.leading === false) previous = now;
738 var remaining = wait - (now - previous);
739 context = this;
740 args = arguments;
741 if (remaining <= 0 || remaining > wait) {
742 clearTimeout(timeout);
743 timeout = null;
744 previous = now;
745 result = func.apply(context, args);
746 if (!timeout) context = args = null;
747 } else if (!timeout && options.trailing !== false) {
748 timeout = setTimeout(later, remaining);
749 }
750 return result;
751 };
752 };
753
754 // Returns a function, that, as long as it continues to be invoked, will not
755 // be triggered. The function will be called after it stops being called for
756 // N milliseconds. If `immediate` is passed, trigger the function on the
757 // leading edge, instead of the trailing.
758 _.debounce = function(func, wait, immediate) {
759 var timeout, args, context, timestamp, result;
760
761 var later = function() {
762 var last = _.now() - timestamp;
763
764 if (last < wait && last > 0) {
765 timeout = setTimeout(later, wait - last);
766 } else {
767 timeout = null;
768 if (!immediate) {
769 result = func.apply(context, args);
770 if (!timeout) context = args = null;
771 }
772 }
773 };
774
775 return function() {
776 context = this;
777 args = arguments;
778 timestamp = _.now();
779 var callNow = immediate && !timeout;
780 if (!timeout) timeout = setTimeout(later, wait);
781 if (callNow) {
782 result = func.apply(context, args);
783 context = args = null;
784 }
785
786 return result;
787 };
788 };
789
790 // Returns the first function passed as an argument to the second,
791 // allowing you to adjust arguments, run code before and after, and
792 // conditionally execute the original function.
793 _.wrap = function(func, wrapper) {
794 return _.partial(wrapper, func);
795 };
796
797 // Returns a negated version of the passed-in predicate.
798 _.negate = function(predicate) {
799 return function() {
800 return !predicate.apply(this, arguments);
801 };
802 };
803
804 // Returns a function that is the composition of a list of functions, each
805 // consuming the return value of the function that follows.
806 _.compose = function() {
807 var args = arguments;
808 var start = args.length - 1;
809 return function() {
810 var i = start;
811 var result = args[start].apply(this, arguments);
812 while (i--) result = args[i].call(this, result);
813 return result;
814 };
815 };
816
817 // Returns a function that will only be executed after being called N times.
818 _.after = function(times, func) {
819 return function() {
820 if (--times < 1) {
821 return func.apply(this, arguments);
822 }
823 };
824 };
825
826 // Returns a function that will only be executed before being called N times.
827 _.before = function(times, func) {
828 var memo;
829 return function() {
830 if (--times > 0) {
831 memo = func.apply(this, arguments);
832 } else {
833 func = null;
834 }
835 return memo;
836 };
837 };
838
839 // Returns a function that will be executed at most one time, no matter how
840 // often you call it. Useful for lazy initialization.
841 _.once = _.partial(_.before, 2);
842
843 // Object Functions
844 // ----------------
845
846 // Retrieve the names of an object's properties.
847 // Delegates to **ECMAScript 5**'s native `Object.keys`
848 _.keys = function(obj) {
849 if (!_.isObject(obj)) return [];
850 if (nativeKeys) return nativeKeys(obj);
851 var keys = [];
852 for (var key in obj) if (_.has(obj, key)) keys.push(key);
853 return keys;
854 };
855
856 // Retrieve the values of an object's properties.
857 _.values = function(obj) {
858 var keys = _.keys(obj);
859 var length = keys.length;
860 var values = Array(length);
861 for (var i = 0; i < length; i++) {
862 values[i] = obj[keys[i]];
863 }
864 return values;
865 };
866
867 // Convert an object into a list of `[key, value]` pairs.
868 _.pairs = function(obj) {
869 var keys = _.keys(obj);
870 var length = keys.length;
871 var pairs = Array(length);
872 for (var i = 0; i < length; i++) {
873 pairs[i] = [keys[i], obj[keys[i]]];
874 }
875 return pairs;
876 };
877
878 // Invert the keys and values of an object. The values must be serializable.
879 _.invert = function(obj) {
880 var result = {};
881 var keys = _.keys(obj);
882 for (var i = 0, length = keys.length; i < length; i++) {
883 result[obj[keys[i]]] = keys[i];
884 }
885 return result;
886 };
887
888 // Return a sorted list of the function names available on the object.
889 // Aliased as `methods`
890 _.functions = _.methods = function(obj) {
891 var names = [];
892 for (var key in obj) {
893 if (_.isFunction(obj[key])) names.push(key);
894 }
895 return names.sort();
896 };
897
898 // Extend a given object with all the properties in passed-in object(s).
899 _.extend = function(obj) {
900 if (!_.isObject(obj)) return obj;
901 var source, prop;
902 for (var i = 1, length = arguments.length; i < length; i++) {
903 source = arguments[i];
904 for (prop in source) {
905 if (hasOwnProperty.call(source, prop)) {
906 obj[prop] = source[prop];
907 }
908 }
909 }
910 return obj;
911 };
912
913 // Return a copy of the object only containing the whitelisted properties.
914 _.pick = function(obj, iteratee, context) {
915 var result = {}, key;
916 if (obj == null) return result;
917 if (_.isFunction(iteratee)) {
918 iteratee = createCallback(iteratee, context);
919 for (key in obj) {
920 var value = obj[key];
921 if (iteratee(value, key, obj)) result[key] = value;
922 }
923 } else {
924 var keys = concat.apply([], slice.call(arguments, 1));
925 obj = new Object(obj);
926 for (var i = 0, length = keys.length; i < length; i++) {
927 key = keys[i];
928 if (key in obj) result[key] = obj[key];
929 }
930 }
931 return result;
932 };
933
934 // Return a copy of the object without the blacklisted properties.
935 _.omit = function(obj, iteratee, context) {
936 if (_.isFunction(iteratee)) {
937 iteratee = _.negate(iteratee);
938 } else {
939 var keys = _.map(concat.apply([], slice.call(arguments, 1)), String);
940 iteratee = function(value, key) {
941 return !_.contains(keys, key);
942 };
943 }
944 return _.pick(obj, iteratee, context);
945 };
946
947 // Fill in a given object with default properties.
948 _.defaults = function(obj) {
949 if (!_.isObject(obj)) return obj;
950 for (var i = 1, length = arguments.length; i < length; i++) {
951 var source = arguments[i];
952 for (var prop in source) {
953 if (obj[prop] === void 0) obj[prop] = source[prop];
954 }
955 }
956 return obj;
957 };
958
959 // Create a (shallow-cloned) duplicate of an object.
960 _.clone = function(obj) {
961 if (!_.isObject(obj)) return obj;
962 return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
963 };
964
965 // Invokes interceptor with the obj, and then returns obj.
966 // The primary purpose of this method is to "tap into" a method chain, in
967 // order to perform operations on intermediate results within the chain.
968 _.tap = function(obj, interceptor) {
969 interceptor(obj);
970 return obj;
971 };
972
973 // Internal recursive comparison function for `isEqual`.
974 var eq = function(a, b, aStack, bStack) {
975 // Identical objects are equal. `0 === -0`, but they aren't identical.
976 // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
977 if (a === b) return a !== 0 || 1 / a === 1 / b;
978 // A strict comparison is necessary because `null == undefined`.
979 if (a == null || b == null) return a === b;
980 // Unwrap any wrapped objects.
981 if (a instanceof _) a = a._wrapped;
982 if (b instanceof _) b = b._wrapped;
983 // Compare `[[Class]]` names.
984 var className = toString.call(a);
985 if (className !== toString.call(b)) return false;
986 switch (className) {
987 // Strings, numbers, regular expressions, dates, and booleans are compared by value.
988 case '[object RegExp]':
989 // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
990 case '[object String]':
991 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
992 // equivalent to `new String("5")`.
993 return '' + a === '' + b;
994 case '[object Number]':
995 // `NaN`s are equivalent, but non-reflexive.
996 // Object(NaN) is equivalent to NaN
997 if (+a !== +a) return +b !== +b;
998 // An `egal` comparison is performed for other numeric values.
999 return +a === 0 ? 1 / +a === 1 / b : +a === +b;
1000 case '[object Date]':
1001 case '[object Boolean]':
1002 // Coerce dates and booleans to numeric primitive values. Dates are compared by their
1003 // millisecond representations. Note that invalid dates with millisecond representations
1004 // of `NaN` are not equivalent.
1005 return +a === +b;
1006 }
1007 if (typeof a != 'object' || typeof b != 'object') return false;
1008 // Assume equality for cyclic structures. The algorithm for detecting cyclic
1009 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
1010 var length = aStack.length;
1011 while (length--) {
1012 // Linear search. Performance is inversely proportional to the number of
1013 // unique nested structures.
1014 if (aStack[length] === a) return bStack[length] === b;
1015 }
1016 // Objects with different constructors are not equivalent, but `Object`s
1017 // from different frames are.
1018 var aCtor = a.constructor, bCtor = b.constructor;
1019 if (
1020 aCtor !== bCtor &&
1021 // Handle Object.create(x) cases
1022 'constructor' in a && 'constructor' in b &&
1023 !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
1024 _.isFunction(bCtor) && bCtor instanceof bCtor)
1025 ) {
1026 return false;
1027 }
1028 // Add the first object to the stack of traversed objects.
1029 aStack.push(a);
1030 bStack.push(b);
1031 var size, result;
1032 // Recursively compare objects and arrays.
1033 if (className === '[object Array]') {
1034 // Compare array lengths to determine if a deep comparison is necessary.
1035 size = a.length;
1036 result = size === b.length;
1037 if (result) {
1038 // Deep compare the contents, ignoring non-numeric properties.
1039 while (size--) {
1040 if (!(result = eq(a[size], b[size], aStack, bStack))) break;
1041 }
1042 }
1043 } else {
1044 // Deep compare objects.
1045 var keys = _.keys(a), key;
1046 size = keys.length;
1047 // Ensure that both objects contain the same number of properties before comparing deep equality.
1048 result = _.keys(b).length === size;
1049 if (result) {
1050 while (size--) {
1051 // Deep compare each member
1052 key = keys[size];
1053 if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
1054 }
1055 }
1056 }
1057 // Remove the first object from the stack of traversed objects.
1058 aStack.pop();
1059 bStack.pop();
1060 return result;
1061 };
1062
1063 // Perform a deep comparison to check if two objects are equal.
1064 _.isEqual = function(a, b) {
1065 return eq(a, b, [], []);
1066 };
1067
1068 // Is a given array, string, or object empty?
1069 // An "empty" object has no enumerable own-properties.
1070 _.isEmpty = function(obj) {
1071 if (obj == null) return true;
1072 if (_.isArray(obj) || _.isString(obj) || _.isArguments(obj)) return obj.length === 0;
1073 for (var key in obj) if (_.has(obj, key)) return false;
1074 return true;
1075 };
1076
1077 // Is a given value a DOM element?
1078 _.isElement = function(obj) {
1079 return !!(obj && obj.nodeType === 1);
1080 };
1081
1082 // Is a given value an array?
1083 // Delegates to ECMA5's native Array.isArray
1084 _.isArray = nativeIsArray || function(obj) {
1085 return toString.call(obj) === '[object Array]';
1086 };
1087
1088 // Is a given variable an object?
1089 _.isObject = function(obj) {
1090 var type = typeof obj;
1091 return type === 'function' || type === 'object' && !!obj;
1092 };
1093
1094 // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
1095 _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
1096 _['is' + name] = function(obj) {
1097 return toString.call(obj) === '[object ' + name + ']';
1098 };
1099 });
1100
1101 // Define a fallback version of the method in browsers (ahem, IE), where
1102 // there isn't any inspectable "Arguments" type.
1103 if (!_.isArguments(arguments)) {
1104 _.isArguments = function(obj) {
1105 return _.has(obj, 'callee');
1106 };
1107 }
1108
1109 // Optimize `isFunction` if appropriate. Work around an IE 11 bug.
1110 if (typeof /./ !== 'function') {
1111 _.isFunction = function(obj) {
1112 return typeof obj == 'function' || false;
1113 };
1114 }
1115
1116 // Is a given object a finite number?
1117 _.isFinite = function(obj) {
1118 return isFinite(obj) && !isNaN(parseFloat(obj));
1119 };
1120
1121 // Is the given value `NaN`? (NaN is the only number which does not equal itself).
1122 _.isNaN = function(obj) {
1123 return _.isNumber(obj) && obj !== +obj;
1124 };
1125
1126 // Is a given value a boolean?
1127 _.isBoolean = function(obj) {
1128 return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
1129 };
1130
1131 // Is a given value equal to null?
1132 _.isNull = function(obj) {
1133 return obj === null;
1134 };
1135
1136 // Is a given variable undefined?
1137 _.isUndefined = function(obj) {
1138 return obj === void 0;
1139 };
1140
1141 // Shortcut function for checking if an object has a given property directly
1142 // on itself (in other words, not on a prototype).
1143 _.has = function(obj, key) {
1144 return obj != null && hasOwnProperty.call(obj, key);
1145 };
1146
1147 // Utility Functions
1148 // -----------------
1149
1150 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
1151 // previous owner. Returns a reference to the Underscore object.
1152 _.noConflict = function() {
1153 root._ = previousUnderscore;
1154 return this;
1155 };
1156
1157 // Keep the identity function around for default iteratees.
1158 _.identity = function(value) {
1159 return value;
1160 };
1161
1162 // Predicate-generating functions. Often useful outside of Underscore.
1163 _.constant = function(value) {
1164 return function() {
1165 return value;
1166 };
1167 };
1168
1169 _.noop = function(){};
1170
1171 _.property = function(key) {
1172 return function(obj) {
1173 return obj[key];
1174 };
1175 };
1176
1177 // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
1178 _.matches = function(attrs) {
1179 var pairs = _.pairs(attrs), length = pairs.length;
1180 return function(obj) {
1181 if (obj == null) return !length;
1182 obj = new Object(obj);
1183 for (var i = 0; i < length; i++) {
1184 var pair = pairs[i], key = pair[0];
1185 if (pair[1] !== obj[key] || !(key in obj)) return false;
1186 }
1187 return true;
1188 };
1189 };
1190
1191 // Run a function **n** times.
1192 _.times = function(n, iteratee, context) {
1193 var accum = Array(Math.max(0, n));
1194 iteratee = createCallback(iteratee, context, 1);
1195 for (var i = 0; i < n; i++) accum[i] = iteratee(i);
1196 return accum;
1197 };
1198
1199 // Return a random integer between min and max (inclusive).
1200 _.random = function(min, max) {
1201 if (max == null) {
1202 max = min;
1203 min = 0;
1204 }
1205 return min + Math.floor(Math.random() * (max - min + 1));
1206 };
1207
1208 // A (possibly faster) way to get the current timestamp as an integer.
1209 _.now = Date.now || function() {
1210 return new Date().getTime();
1211 };
1212
1213 // List of HTML entities for escaping.
1214 var escapeMap = {
1215 '&': '&amp;',
1216 '<': '&lt;',
1217 '>': '&gt;',
1218 '"': '&quot;',
1219 "'": '&#x27;',
1220 '`': '&#x60;'
1221 };
1222 var unescapeMap = _.invert(escapeMap);
1223
1224 // Functions for escaping and unescaping strings to/from HTML interpolation.
1225 var createEscaper = function(map) {
1226 var escaper = function(match) {
1227 return map[match];
1228 };
1229 // Regexes for identifying a key that needs to be escaped
1230 var source = '(?:' + _.keys(map).join('|') + ')';
1231 var testRegexp = RegExp(source);
1232 var replaceRegexp = RegExp(source, 'g');
1233 return function(string) {
1234 string = string == null ? '' : '' + string;
1235 return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
1236 };
1237 };
1238 _.escape = createEscaper(escapeMap);
1239 _.unescape = createEscaper(unescapeMap);
1240
1241 // If the value of the named `property` is a function then invoke it with the
1242 // `object` as context; otherwise, return it.
1243 _.result = function(object, property) {
1244 if (object == null) return void 0;
1245 var value = object[property];
1246 return _.isFunction(value) ? object[property]() : value;
1247 };
1248
1249 // Generate a unique integer id (unique within the entire client session).
1250 // Useful for temporary DOM ids.
1251 var idCounter = 0;
1252 _.uniqueId = function(prefix) {
1253 var id = ++idCounter + '';
1254 return prefix ? prefix + id : id;
1255 };
1256
1257 // By default, Underscore uses ERB-style template delimiters, change the
1258 // following template settings to use alternative delimiters.
1259 _.templateSettings = {
1260 evaluate : /<%([\s\S]+?)%>/g,
1261 interpolate : /<%=([\s\S]+?)%>/g,
1262 escape : /<%-([\s\S]+?)%>/g
1263 };
1264
1265 // When customizing `templateSettings`, if you don't want to define an
1266 // interpolation, evaluation or escaping regex, we need one that is
1267 // guaranteed not to match.
1268 var noMatch = /(.)^/;
1269
1270 // Certain characters need to be escaped so that they can be put into a
1271 // string literal.
1272 var escapes = {
1273 "'": "'",
1274 '\\': '\\',
1275 '\r': 'r',
1276 '\n': 'n',
1277 '\u2028': 'u2028',
1278 '\u2029': 'u2029'
1279 };
1280
1281 var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
1282
1283 var escapeChar = function(match) {
1284 return '\\' + escapes[match];
1285 };
1286
1287 // JavaScript micro-templating, similar to John Resig's implementation.
1288 // Underscore templating handles arbitrary delimiters, preserves whitespace,
1289 // and correctly escapes quotes within interpolated code.
1290 // NB: `oldSettings` only exists for backwards compatibility.
1291 _.template = function(text, settings, oldSettings) {
1292 if (!settings && oldSettings) settings = oldSettings;
1293 settings = _.defaults({}, settings, _.templateSettings);
1294
1295 // Combine delimiters into one regular expression via alternation.
1296 var matcher = RegExp([
1297 (settings.escape || noMatch).source,
1298 (settings.interpolate || noMatch).source,
1299 (settings.evaluate || noMatch).source
1300 ].join('|') + '|$', 'g');
1301
1302 // Compile the template source, escaping string literals appropriately.
1303 var index = 0;
1304 var source = "__p+='";
1305 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
1306 source += text.slice(index, offset).replace(escaper, escapeChar);
1307 index = offset + match.length;
1308
1309 if (escape) {
1310 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
1311 } else if (interpolate) {
1312 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
1313 } else if (evaluate) {
1314 source += "';\n" + evaluate + "\n__p+='";
1315 }
1316
1317 // Adobe VMs need the match returned to produce the correct offest.
1318 return match;
1319 });
1320 source += "';\n";
1321
1322 // If a variable is not specified, place data values in local scope.
1323 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
1324
1325 source = "var __t,__p='',__j=Array.prototype.join," +
1326 "print=function(){__p+=__j.call(arguments,'');};\n" +
1327 source + 'return __p;\n';
1328
1329 try {
1330 var render = new Function(settings.variable || 'obj', '_', source);
1331 } catch (e) {
1332 e.source = source;
1333 throw e;
1334 }
1335
1336 var template = function(data) {
1337 return render.call(this, data, _);
1338 };
1339
1340 // Provide the compiled source as a convenience for precompilation.
1341 var argument = settings.variable || 'obj';
1342 template.source = 'function(' + argument + '){\n' + source + '}';
1343
1344 return template;
1345 };
1346
1347 // Add a "chain" function. Start chaining a wrapped Underscore object.
1348 _.chain = function(obj) {
1349 var instance = _(obj);
1350 instance._chain = true;
1351 return instance;
1352 };
1353
1354 // OOP
1355 // ---------------
1356 // If Underscore is called as a function, it returns a wrapped object that
1357 // can be used OO-style. This wrapper holds altered versions of all the
1358 // underscore functions. Wrapped objects may be chained.
1359
1360 // Helper function to continue chaining intermediate results.
1361 var result = function(obj) {
1362 return this._chain ? _(obj).chain() : obj;
1363 };
1364
1365 // Add your own custom functions to the Underscore object.
1366 _.mixin = function(obj) {
1367 _.each(_.functions(obj), function(name) {
1368 var func = _[name] = obj[name];
1369 _.prototype[name] = function() {
1370 var args = [this._wrapped];
1371 push.apply(args, arguments);
1372 return result.call(this, func.apply(_, args));
1373 };
1374 });
1375 };
1376
1377 // Add all of the Underscore functions to the wrapper object.
1378 _.mixin(_);
1379
1380 // Add all mutator Array functions to the wrapper.
1381 _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
1382 var method = ArrayProto[name];
1383 _.prototype[name] = function() {
1384 var obj = this._wrapped;
1385 method.apply(obj, arguments);
1386 if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
1387 return result.call(this, obj);
1388 };
1389 });
1390
1391 // Add all accessor Array functions to the wrapper.
1392 _.each(['concat', 'join', 'slice'], function(name) {
1393 var method = ArrayProto[name];
1394 _.prototype[name] = function() {
1395 return result.call(this, method.apply(this._wrapped, arguments));
1396 };
1397 });
1398
1399 // Extracts the result from a wrapped and chained object.
1400 _.prototype.value = function() {
1401 return this._wrapped;
1402 };
1403
1404 // AMD registration happens at the end for compatibility with AMD loaders
1405 // that may not enforce next-turn semantics on modules. Even though general
1406 // practice for AMD registration is to be anonymous, underscore registers
1407 // as a named module because, like jQuery, it is a base library that is
1408 // popular enough to be bundled in a third party lib, but not be part of
1409 // an AMD load request. Those cases could generate an error when an
1410 // anonymous define() is called outside of a loader request.
1411 if (typeof define === 'function' && define.amd) {
1412 define('underscore', [], function() {
1413 return _;
1414 });
1415 }
1416}.call(this));