js_stack 1.8.0 → 1.9.0

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