Re: Re: underscore.js

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

Replies to Re: Re: underscore.js rss

Title Name Language When
Re:initializer.js disqus.com javascript 2 Months ago.

Reply to "Re: Re: underscore.js"

Here you can reply to the paste above