PageSourceSearch

http://nube.utparral.edu.mx/core/vendor/underscore/underscore.js?v=22b4f684d0564fa891b736c20c66da9a

js utparral.edu.mx collected 2026-10-06 00:16:36 UTC 58,319 bytes, 1,692 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.