You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mesos.apache.org by "Mattmann, Chris A (388J)" <ch...@jpl.nasa.gov> on 2013/03/03 00:25:44 UTC

Re: svn commit: r1449845 - in /incubator/mesos/trunk/src: ./ webui/master/static/

Jeez, who says Ben Hindman is the "lead developer" of Mesos :)

You are doing a pretty good job yourself here Vinod.

BTW, I had a great talk with Ben at ApacheCon and he made this same
comment so I feel OK making it :)

Take care and keep it up!

Cheers,
Chris


On 2/25/13 11:45 AM, "vinodkone@apache.org" <vi...@apache.org> wrote:

>Author: vinodkone
>Date: Mon Feb 25 19:45:45 2013
>New Revision: 1449845
>
>URL: http://svn.apache.org/r1449845
>Log:
>Resource Monitoring 11: Upgraded underscore.js (to use _.object).
>
>From: Ben Mahler <be...@gmail.com>
>Review: https://reviews.apache.org/r/9267
>
>Added:
>    incubator/mesos/trunk/src/webui/master/static/underscore-1.4.3.js
>    incubator/mesos/trunk/src/webui/master/static/underscore-1.4.3.min.js
>Removed:
>    incubator/mesos/trunk/src/webui/master/static/underscore-1.3.3.min.js
>Modified:
>    incubator/mesos/trunk/src/Makefile.am
>    incubator/mesos/trunk/src/webui/master/static/index.html
>    incubator/mesos/trunk/src/webui/master/static/pailer.html
>
>Modified: incubator/mesos/trunk/src/Makefile.am
>URL: 
>http://svn.apache.org/viewvc/incubator/mesos/trunk/src/Makefile.am?rev=144
>9845&r1=1449844&r2=1449845&view=diff
>==========================================================================
>====
>--- incubator/mesos/trunk/src/Makefile.am (original)
>+++ incubator/mesos/trunk/src/Makefile.am Mon Feb 25 19:45:45 2013
>@@ -395,7 +395,8 @@ nobase_dist_webui_DATA += webui/master/s
> nobase_dist_webui_DATA +=						\
>   webui/master/static/angular-1.0.0rc8.js				\
>   webui/master/static/angular-1.0.0rc8.min.js				\
>-  webui/master/static/underscore-1.3.3.min.js				\
>+  webui/master/static/underscore-1.4.3.js				\
>+  webui/master/static/underscore-1.4.3.min.js				\
>   webui/master/static/cubism.v1.js					\
>   webui/master/static/cubism.v1.min.js					\
>   webui/master/static/d3.v2.js						\
>
>Modified: incubator/mesos/trunk/src/webui/master/static/index.html
>URL: 
>http://svn.apache.org/viewvc/incubator/mesos/trunk/src/webui/master/static
>/index.html?rev=1449845&r1=1449844&r2=1449845&view=diff
>==========================================================================
>====
>--- incubator/mesos/trunk/src/webui/master/static/index.html (original)
>+++ incubator/mesos/trunk/src/webui/master/static/index.html Mon Feb 25
>19:45:45 2013
>@@ -89,7 +89,7 @@
>     <script src="/static/bootstrap/js/jquery-1.7.1.min.js"></script>
>     <script src="/static/bootstrap/js/bootstrap.min.js"></script>
> 
>-    <script src="/static/underscore-1.3.3.min.js"></script>
>+    <script src="/static/underscore-1.4.3.min.js"></script>
>     <script src="/static/angular-1.0.0rc8.min.js"></script>
>     <script src="/static/d3.v2.min.js"></script>
>     <script src="/static/cubism.v1.min.js"></script>
>
>Modified: incubator/mesos/trunk/src/webui/master/static/pailer.html
>URL: 
>http://svn.apache.org/viewvc/incubator/mesos/trunk/src/webui/master/static
>/pailer.html?rev=1449845&r1=1449844&r2=1449845&view=diff
>==========================================================================
>====
>--- incubator/mesos/trunk/src/webui/master/static/pailer.html (original)
>+++ incubator/mesos/trunk/src/webui/master/static/pailer.html Mon Feb 25
>19:45:45 2013
>@@ -28,7 +28,7 @@
> 
>     <script src="/static/bootstrap/js/jquery-1.7.1.min.js"></script>
> 
>-    <script src="/static/underscore-1.3.3.min.js"></script>
>+    <script src="/static/underscore-1.4.3.min.js"></script>
> 
>     <script src="/static/jquery.pailer.js"></script>
> 
>
>Added: incubator/mesos/trunk/src/webui/master/static/underscore-1.4.3.js
>URL: 
>http://svn.apache.org/viewvc/incubator/mesos/trunk/src/webui/master/static
>/underscore-1.4.3.js?rev=1449845&view=auto
>==========================================================================
>====
>--- incubator/mesos/trunk/src/webui/master/static/underscore-1.4.3.js
>(added)
>+++ incubator/mesos/trunk/src/webui/master/static/underscore-1.4.3.js Mon
>Feb 25 19:45:45 2013
>@@ -0,0 +1,1221 @@
>+//     Underscore.js 1.4.3
>+//     http://underscorejs.org
>+//     (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
>+//     Underscore may be freely distributed under the MIT license.
>+
>+(function() {
>+
>+  // Baseline setup
>+  // --------------
>+
>+  // Establish the root object, `window` in the browser, or `global` on
>the server.
>+  var root = this;
>+
>+  // Save the previous value of the `_` variable.
>+  var previousUnderscore = root._;
>+
>+  // Establish the object that gets returned to break out of a loop
>iteration.
>+  var breaker = {};
>+
>+  // Save bytes in the minified (but not gzipped) version:
>+  var ArrayProto = Array.prototype, ObjProto = Object.prototype,
>FuncProto = Function.prototype;
>+
>+  // Create quick reference variables for speed access to core
>prototypes.
>+  var push             = ArrayProto.push,
>+      slice            = ArrayProto.slice,
>+      concat           = ArrayProto.concat,
>+      toString         = ObjProto.toString,
>+      hasOwnProperty   = ObjProto.hasOwnProperty;
>+
>+  // All **ECMAScript 5** native function implementations that we hope
>to use
>+  // are declared here.
>+  var
>+    nativeForEach      = ArrayProto.forEach,
>+    nativeMap          = ArrayProto.map,
>+    nativeReduce       = ArrayProto.reduce,
>+    nativeReduceRight  = ArrayProto.reduceRight,
>+    nativeFilter       = ArrayProto.filter,
>+    nativeEvery        = ArrayProto.every,
>+    nativeSome         = ArrayProto.some,
>+    nativeIndexOf      = ArrayProto.indexOf,
>+    nativeLastIndexOf  = ArrayProto.lastIndexOf,
>+    nativeIsArray      = Array.isArray,
>+    nativeKeys         = Object.keys,
>+    nativeBind         = FuncProto.bind;
>+
>+  // Create a safe reference to the Underscore object for use below.
>+  var _ = function(obj) {
>+    if (obj instanceof _) return obj;
>+    if (!(this instanceof _)) return new _(obj);
>+    this._wrapped = obj;
>+  };
>+
>+  // Export the Underscore object for **Node.js**, with
>+  // backwards-compatibility for the old `require()` API. If we're in
>+  // the browser, add `_` as a global object via a string identifier,
>+  // for Closure Compiler "advanced" mode.
>+  if (typeof exports !== 'undefined') {
>+    if (typeof module !== 'undefined' && module.exports) {
>+      exports = module.exports = _;
>+    }
>+    exports._ = _;
>+  } else {
>+    root._ = _;
>+  }
>+
>+  // Current version.
>+  _.VERSION = '1.4.3';
>+
>+  // Collection Functions
>+  // --------------------
>+
>+  // The cornerstone, an `each` implementation, aka `forEach`.
>+  // Handles objects with the built-in `forEach`, arrays, and raw
>objects.
>+  // Delegates to **ECMAScript 5**'s native `forEach` if available.
>+  var each = _.each = _.forEach = function(obj, iterator, context) {
>+    if (obj == null) return;
>+    if (nativeForEach && obj.forEach === nativeForEach) {
>+      obj.forEach(iterator, context);
>+    } else if (obj.length === +obj.length) {
>+      for (var i = 0, l = obj.length; i < l; i++) {
>+        if (iterator.call(context, obj[i], i, obj) === breaker) return;
>+      }
>+    } else {
>+      for (var key in obj) {
>+        if (_.has(obj, key)) {
>+          if (iterator.call(context, obj[key], key, obj) === breaker)
>return;
>+        }
>+      }
>+    }
>+  };
>+
>+  // Return the results of applying the iterator to each element.
>+  // Delegates to **ECMAScript 5**'s native `map` if available.
>+  _.map = _.collect = function(obj, iterator, context) {
>+    var results = [];
>+    if (obj == null) return results;
>+    if (nativeMap && obj.map === nativeMap) return obj.map(iterator,
>context);
>+    each(obj, function(value, index, list) {
>+      results[results.length] = iterator.call(context, value, index,
>list);
>+    });
>+    return results;
>+  };
>+
>+  var reduceError = 'Reduce of empty array with no initial value';
>+
>+  // **Reduce** builds up a single result from a list of values, aka
>`inject`,
>+  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if
>available.
>+  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context)
>{
>+    var initial = arguments.length > 2;
>+    if (obj == null) obj = [];
>+    if (nativeReduce && obj.reduce === nativeReduce) {
>+      if (context) iterator = _.bind(iterator, context);
>+      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
>+    }
>+    each(obj, function(value, index, list) {
>+      if (!initial) {
>+        memo = value;
>+        initial = true;
>+      } else {
>+        memo = iterator.call(context, memo, value, index, list);
>+      }
>+    });
>+    if (!initial) throw new TypeError(reduceError);
>+    return memo;
>+  };
>+
>+  // The right-associative version of reduce, also known as `foldr`.
>+  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
>+  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
>+    var initial = arguments.length > 2;
>+    if (obj == null) obj = [];
>+    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
>+      if (context) iterator = _.bind(iterator, context);
>+      return initial ? obj.reduceRight(iterator, memo) :
>obj.reduceRight(iterator);
>+    }
>+    var length = obj.length;
>+    if (length !== +length) {
>+      var keys = _.keys(obj);
>+      length = keys.length;
>+    }
>+    each(obj, function(value, index, list) {
>+      index = keys ? keys[--length] : --length;
>+      if (!initial) {
>+        memo = obj[index];
>+        initial = true;
>+      } else {
>+        memo = iterator.call(context, memo, obj[index], index, list);
>+      }
>+    });
>+    if (!initial) throw new TypeError(reduceError);
>+    return memo;
>+  };
>+
>+  // Return the first value which passes a truth test. Aliased as
>`detect`.
>+  _.find = _.detect = function(obj, iterator, context) {
>+    var result;
>+    any(obj, function(value, index, list) {
>+      if (iterator.call(context, value, index, list)) {
>+        result = value;
>+        return true;
>+      }
>+    });
>+    return result;
>+  };
>+
>+  // Return all the elements that pass a truth test.
>+  // Delegates to **ECMAScript 5**'s native `filter` if available.
>+  // Aliased as `select`.
>+  _.filter = _.select = function(obj, iterator, context) {
>+    var results = [];
>+    if (obj == null) return results;
>+    if (nativeFilter && obj.filter === nativeFilter) return
>obj.filter(iterator, context);
>+    each(obj, function(value, index, list) {
>+      if (iterator.call(context, value, index, list))
>results[results.length] = value;
>+    });
>+    return results;
>+  };
>+
>+  // Return all the elements for which a truth test fails.
>+  _.reject = function(obj, iterator, context) {
>+    return _.filter(obj, function(value, index, list) {
>+      return !iterator.call(context, value, index, list);
>+    }, context);
>+  };
>+
>+  // Determine whether all of the elements match a truth test.
>+  // Delegates to **ECMAScript 5**'s native `every` if available.
>+  // Aliased as `all`.
>+  _.every = _.all = function(obj, iterator, context) {
>+    iterator || (iterator = _.identity);
>+    var result = true;
>+    if (obj == null) return result;
>+    if (nativeEvery && obj.every === nativeEvery) return
>obj.every(iterator, context);
>+    each(obj, function(value, index, list) {
>+      if (!(result = result && iterator.call(context, value, index,
>list))) return breaker;
>+    });
>+    return !!result;
>+  };
>+
>+  // Determine if at least one element in the object matches a truth
>test.
>+  // Delegates to **ECMAScript 5**'s native `some` if available.
>+  // Aliased as `any`.
>+  var any = _.some = _.any = function(obj, iterator, context) {
>+    iterator || (iterator = _.identity);
>+    var result = false;
>+    if (obj == null) return result;
>+    if (nativeSome && obj.some === nativeSome) return obj.some(iterator,
>context);
>+    each(obj, function(value, index, list) {
>+      if (result || (result = iterator.call(context, value, index,
>list))) return breaker;
>+    });
>+    return !!result;
>+  };
>+
>+  // Determine if the array or object contains a given value (using
>`===`).
>+  // Aliased as `include`.
>+  _.contains = _.include = function(obj, target) {
>+    if (obj == null) return false;
>+    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return
>obj.indexOf(target) != -1;
>+    return any(obj, function(value) {
>+      return value === target;
>+    });
>+  };
>+
>+  // Invoke a method (with arguments) on every item in a collection.
>+  _.invoke = function(obj, method) {
>+    var args = slice.call(arguments, 2);
>+    return _.map(obj, function(value) {
>+      return (_.isFunction(method) ? method :
>value[method]).apply(value, args);
>+    });
>+  };
>+
>+  // Convenience version of a common use case of `map`: fetching a
>property.
>+  _.pluck = function(obj, key) {
>+    return _.map(obj, function(value){ return value[key]; });
>+  };
>+
>+  // Convenience version of a common use case of `filter`: selecting
>only objects
>+  // with specific `key:value` pairs.
>+  _.where = function(obj, attrs) {
>+    if (_.isEmpty(attrs)) return [];
>+    return _.filter(obj, function(value) {
>+      for (var key in attrs) {
>+        if (attrs[key] !== value[key]) return false;
>+      }
>+      return true;
>+    });
>+  };
>+
>+  // Return the maximum element or (element-based computation).
>+  // Can't optimize arrays of integers longer than 65,535 elements.
>+  // See: https://bugs.webkit.org/show_bug.cgi?id=80797
>+  _.max = function(obj, iterator, context) {
>+    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length
>< 65535) {
>+      return Math.max.apply(Math, obj);
>+    }
>+    if (!iterator && _.isEmpty(obj)) return -Infinity;
>+    var result = {computed : -Infinity, value: -Infinity};
>+    each(obj, function(value, index, list) {
>+      var computed = iterator ? iterator.call(context, value, index,
>list) : value;
>+      computed >= result.computed && (result = {value : value, computed
>: computed});
>+    });
>+    return result.value;
>+  };
>+
>+  // Return the minimum element (or element-based computation).
>+  _.min = function(obj, iterator, context) {
>+    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length
>< 65535) {
>+      return Math.min.apply(Math, obj);
>+    }
>+    if (!iterator && _.isEmpty(obj)) return Infinity;
>+    var result = {computed : Infinity, value: Infinity};
>+    each(obj, function(value, index, list) {
>+      var computed = iterator ? iterator.call(context, value, index,
>list) : value;
>+      computed < result.computed && (result = {value : value, computed :
>computed});
>+    });
>+    return result.value;
>+  };
>+
>+  // Shuffle an array.
>+  _.shuffle = function(obj) {
>+    var rand;
>+    var index = 0;
>+    var shuffled = [];
>+    each(obj, function(value) {
>+      rand = _.random(index++);
>+      shuffled[index - 1] = shuffled[rand];
>+      shuffled[rand] = value;
>+    });
>+    return shuffled;
>+  };
>+
>+  // An internal function to generate lookup iterators.
>+  var lookupIterator = function(value) {
>+    return _.isFunction(value) ? value : function(obj){ return
>obj[value]; };
>+  };
>+
>+  // Sort the object's values by a criterion produced by an iterator.
>+  _.sortBy = function(obj, value, context) {
>+    var iterator = lookupIterator(value);
>+    return _.pluck(_.map(obj, function(value, index, list) {
>+      return {
>+        value : value,
>+        index : index,
>+        criteria : iterator.call(context, value, index, list)
>+      };
>+    }).sort(function(left, right) {
>+      var a = left.criteria;
>+      var b = right.criteria;
>+      if (a !== b) {
>+        if (a > b || a === void 0) return 1;
>+        if (a < b || b === void 0) return -1;
>+      }
>+      return left.index < right.index ? -1 : 1;
>+    }), 'value');
>+  };
>+
>+  // An internal function used for aggregate "group by" operations.
>+  var group = function(obj, value, context, behavior) {
>+    var result = {};
>+    var iterator = lookupIterator(value || _.identity);
>+    each(obj, function(value, index) {
>+      var key = iterator.call(context, value, index, obj);
>+      behavior(result, key, value);
>+    });
>+    return result;
>+  };
>+
>+  // Groups the object's values by a criterion. Pass either a string
>attribute
>+  // to group by, or a function that returns the criterion.
>+  _.groupBy = function(obj, value, context) {
>+    return group(obj, value, context, function(result, key, value) {
>+      (_.has(result, key) ? result[key] : (result[key] =
>[])).push(value);
>+    });
>+  };
>+
>+  // Counts instances of an object that group by a certain criterion.
>Pass
>+  // either a string attribute to count by, or a function that returns
>the
>+  // criterion.
>+  _.countBy = function(obj, value, context) {
>+    return group(obj, value, context, function(result, key) {
>+      if (!_.has(result, key)) result[key] = 0;
>+      result[key]++;
>+    });
>+  };
>+
>+  // Use a comparator function to figure out the smallest index at which
>+  // an object should be inserted so as to maintain order. Uses binary
>search.
>+  _.sortedIndex = function(array, obj, iterator, context) {
>+    iterator = iterator == null ? _.identity : lookupIterator(iterator);
>+    var value = iterator.call(context, obj);
>+    var low = 0, high = array.length;
>+    while (low < high) {
>+      var mid = (low + high) >>> 1;
>+      iterator.call(context, array[mid]) < value ? low = mid + 1 : high
>= mid;
>+    }
>+    return low;
>+  };
>+
>+  // Safely convert anything iterable into a real, live array.
>+  _.toArray = function(obj) {
>+    if (!obj) return [];
>+    if (_.isArray(obj)) return slice.call(obj);
>+    if (obj.length === +obj.length) return _.map(obj, _.identity);
>+    return _.values(obj);
>+  };
>+
>+  // Return the number of elements in an object.
>+  _.size = function(obj) {
>+    if (obj == null) return 0;
>+    return (obj.length === +obj.length) ? obj.length :
>_.keys(obj).length;
>+  };
>+
>+  // Array Functions
>+  // ---------------
>+
>+  // Get the first element of an array. Passing **n** will return the
>first N
>+  // values in the array. Aliased as `head` and `take`. The **guard**
>check
>+  // allows it to work with `_.map`.
>+  _.first = _.head = _.take = function(array, n, guard) {
>+    if (array == null) return void 0;
>+    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
>+  };
>+
>+  // Returns everything but the last entry of the array. Especially
>useful on
>+  // the arguments object. Passing **n** will return all the values in
>+  // the array, excluding the last N. The **guard** check allows it to
>work with
>+  // `_.map`.
>+  _.initial = function(array, n, guard) {
>+    return slice.call(array, 0, array.length - ((n == null) || guard ? 1
>: n));
>+  };
>+
>+  // Get the last element of an array. Passing **n** will return the
>last N
>+  // values in the array. The **guard** check allows it to work with
>`_.map`.
>+  _.last = function(array, n, guard) {
>+    if (array == null) return void 0;
>+    if ((n != null) && !guard) {
>+      return slice.call(array, Math.max(array.length - n, 0));
>+    } else {
>+      return array[array.length - 1];
>+    }
>+  };
>+
>+  // Returns everything but the first entry of the array. Aliased as
>`tail` and `drop`.
>+  // Especially useful on the arguments object. Passing an **n** will
>return
>+  // the rest N values in the array. The **guard**
>+  // check allows it to work with `_.map`.
>+  _.rest = _.tail = _.drop = function(array, n, guard) {
>+    return slice.call(array, (n == null) || guard ? 1 : n);
>+  };
>+
>+  // Trim out all falsy values from an array.
>+  _.compact = function(array) {
>+    return _.filter(array, _.identity);
>+  };
>+
>+  // Internal implementation of a recursive `flatten` function.
>+  var flatten = function(input, shallow, output) {
>+    each(input, function(value) {
>+      if (_.isArray(value)) {
>+        shallow ? push.apply(output, value) : flatten(value, shallow,
>output);
>+      } else {
>+        output.push(value);
>+      }
>+    });
>+    return output;
>+  };
>+
>+  // Return a completely flattened version of an array.
>+  _.flatten = function(array, shallow) {
>+    return flatten(array, shallow, []);
>+  };
>+
>+  // Return a version of the array that does not contain the specified
>value(s).
>+  _.without = function(array) {
>+    return _.difference(array, slice.call(arguments, 1));
>+  };
>+
>+  // Produce a duplicate-free version of the array. If the array has
>already
>+  // been sorted, you have the option of using a faster algorithm.
>+  // Aliased as `unique`.
>+  _.uniq = _.unique = function(array, isSorted, iterator, context) {
>+    if (_.isFunction(isSorted)) {
>+      context = iterator;
>+      iterator = isSorted;
>+      isSorted = false;
>+    }
>+    var initial = iterator ? _.map(array, iterator, context) : array;
>+    var results = [];
>+    var seen = [];
>+    each(initial, function(value, index) {
>+      if (isSorted ? (!index || seen[seen.length - 1] !== value) :
>!_.contains(seen, value)) {
>+        seen.push(value);
>+        results.push(array[index]);
>+      }
>+    });
>+    return results;
>+  };
>+
>+  // Produce an array that contains the union: each distinct element
>from all of
>+  // the passed-in arrays.
>+  _.union = function() {
>+    return _.uniq(concat.apply(ArrayProto, arguments));
>+  };
>+
>+  // Produce an array that contains every item shared between all the
>+  // passed-in arrays.
>+  _.intersection = function(array) {
>+    var rest = slice.call(arguments, 1);
>+    return _.filter(_.uniq(array), function(item) {
>+      return _.every(rest, function(other) {
>+        return _.indexOf(other, item) >= 0;
>+      });
>+    });
>+  };
>+
>+  // Take the difference between one array and a number of other arrays.
>+  // Only the elements present in just the first array will remain.
>+  _.difference = function(array) {
>+    var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
>+    return _.filter(array, function(value){ return !_.contains(rest,
>value); });
>+  };
>+
>+  // Zip together multiple lists into a single array -- elements that
>share
>+  // an index go together.
>+  _.zip = function() {
>+    var args = slice.call(arguments);
>+    var length = _.max(_.pluck(args, 'length'));
>+    var results = new Array(length);
>+    for (var i = 0; i < length; i++) {
>+      results[i] = _.pluck(args, "" + i);
>+    }
>+    return results;
>+  };
>+
>+  // Converts lists into objects. Pass either a single array of `[key,
>value]`
>+  // pairs, or two parallel arrays of the same length -- one of keys,
>and one of
>+  // the corresponding values.
>+  _.object = function(list, values) {
>+    if (list == null) return {};
>+    var result = {};
>+    for (var i = 0, l = list.length; i < l; i++) {
>+      if (values) {
>+        result[list[i]] = values[i];
>+      } else {
>+        result[list[i][0]] = list[i][1];
>+      }
>+    }
>+    return result;
>+  };
>+
>+  // If the browser doesn't supply us with indexOf (I'm looking at you,
>**MSIE**),
>+  // we need this function. Return the position of the first occurrence
>of an
>+  // item in an array, or -1 if the item is not included in the array.
>+  // Delegates to **ECMAScript 5**'s native `indexOf` if available.
>+  // If the array is large and already in sort order, pass `true`
>+  // for **isSorted** to use binary search.
>+  _.indexOf = function(array, item, isSorted) {
>+    if (array == null) return -1;
>+    var i = 0, l = array.length;
>+    if (isSorted) {
>+      if (typeof isSorted == 'number') {
>+        i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
>+      } else {
>+        i = _.sortedIndex(array, item);
>+        return array[i] === item ? i : -1;
>+      }
>+    }
>+    if (nativeIndexOf && array.indexOf === nativeIndexOf) return
>array.indexOf(item, isSorted);
>+    for (; i < l; i++) if (array[i] === item) return i;
>+    return -1;
>+  };
>+
>+  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
>+  _.lastIndexOf = function(array, item, from) {
>+    if (array == null) return -1;
>+    var hasIndex = from != null;
>+    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
>+      return hasIndex ? array.lastIndexOf(item, from) :
>array.lastIndexOf(item);
>+    }
>+    var i = (hasIndex ? from : array.length);
>+    while (i--) if (array[i] === item) return i;
>+    return -1;
>+  };
>+
>+  // Generate an integer Array containing an arithmetic progression. A
>port of
>+  // the native Python `range()` function. See
>+  // [the Python 
>documentation](http://docs.python.org/library/functions.html#range).
>+  _.range = function(start, stop, step) {
>+    if (arguments.length <= 1) {
>+      stop = start || 0;
>+      start = 0;
>+    }
>+    step = arguments[2] || 1;
>+
>+    var len = Math.max(Math.ceil((stop - start) / step), 0);
>+    var idx = 0;
>+    var range = new Array(len);
>+
>+    while(idx < len) {
>+      range[idx++] = start;
>+      start += step;
>+    }
>+
>+    return range;
>+  };
>+
>+  // Function (ahem) Functions
>+  // ------------------
>+
>+  // Reusable constructor function for prototype setting.
>+  var ctor = function(){};
>+
>+  // Create a function bound to a given object (assigning `this`, and
>arguments,
>+  // optionally). Binding with arguments is also known as `curry`.
>+  // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
>+  // We check for `func.bind` first, to fail fast when `func` is
>undefined.
>+  _.bind = function(func, context) {
>+    var args, bound;
>+    if (func.bind === nativeBind && nativeBind) return
>nativeBind.apply(func, slice.call(arguments, 1));
>+    if (!_.isFunction(func)) throw new TypeError;
>+    args = slice.call(arguments, 2);
>+    return bound = function() {
>+      if (!(this instanceof bound)) return func.apply(context,
>args.concat(slice.call(arguments)));
>+      ctor.prototype = func.prototype;
>+      var self = new ctor;
>+      ctor.prototype = null;
>+      var result = func.apply(self, args.concat(slice.call(arguments)));
>+      if (Object(result) === result) return result;
>+      return self;
>+    };
>+  };
>+
>+  // Bind all of an object's methods to that object. Useful for ensuring
>that
>+  // all callbacks defined on an object belong to it.
>+  _.bindAll = function(obj) {
>+    var funcs = slice.call(arguments, 1);
>+    if (funcs.length == 0) funcs = _.functions(obj);
>+    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
>+    return obj;
>+  };
>+
>+  // Memoize an expensive function by storing its results.
>+  _.memoize = function(func, hasher) {
>+    var memo = {};
>+    hasher || (hasher = _.identity);
>+    return function() {
>+      var key = hasher.apply(this, arguments);
>+      return _.has(memo, key) ? memo[key] : (memo[key] =
>func.apply(this, arguments));
>+    };
>+  };
>+
>+  // Delays a function for the given number of milliseconds, and then
>calls
>+  // it with the arguments supplied.
>+  _.delay = function(func, wait) {
>+    var args = slice.call(arguments, 2);
>+    return setTimeout(function(){ return func.apply(null, args); },
>wait);
>+  };
>+
>+  // Defers a function, scheduling it to run after the current call
>stack has
>+  // cleared.
>+  _.defer = function(func) {
>+    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
>+  };
>+
>+  // Returns a function, that, when invoked, will only be triggered at
>most once
>+  // during a given window of time.
>+  _.throttle = function(func, wait) {
>+    var context, args, timeout, result;
>+    var previous = 0;
>+    var later = function() {
>+      previous = new Date;
>+      timeout = null;
>+      result = func.apply(context, args);
>+    };
>+    return function() {
>+      var now = new Date;
>+      var remaining = wait - (now - previous);
>+      context = this;
>+      args = arguments;
>+      if (remaining <= 0) {
>+        clearTimeout(timeout);
>+        timeout = null;
>+        previous = now;
>+        result = func.apply(context, args);
>+      } else if (!timeout) {
>+        timeout = setTimeout(later, remaining);
>+      }
>+      return result;
>+    };
>+  };
>+
>+  // Returns a function, that, as long as it continues to be invoked,
>will not
>+  // be triggered. The function will be called after it stops being
>called for
>+  // N milliseconds. If `immediate` is passed, trigger the function on
>the
>+  // leading edge, instead of the trailing.
>+  _.debounce = function(func, wait, immediate) {
>+    var timeout, result;
>+    return function() {
>+      var context = this, args = arguments;
>+      var later = function() {
>+        timeout = null;
>+        if (!immediate) result = func.apply(context, args);
>+      };
>+      var callNow = immediate && !timeout;
>+      clearTimeout(timeout);
>+      timeout = setTimeout(later, wait);
>+      if (callNow) result = func.apply(context, args);
>+      return result;
>+    };
>+  };
>+
>+  // Returns a function that will be executed at most one time, no
>matter how
>+  // often you call it. Useful for lazy initialization.
>+  _.once = function(func) {
>+    var ran = false, memo;
>+    return function() {
>+      if (ran) return memo;
>+      ran = true;
>+      memo = func.apply(this, arguments);
>+      func = null;
>+      return memo;
>+    };
>+  };
>+
>+  // Returns the first function passed as an argument to the second,
>+  // allowing you to adjust arguments, run code before and after, and
>+  // conditionally execute the original function.
>+  _.wrap = function(func, wrapper) {
>+    return function() {
>+      var args = [func];
>+      push.apply(args, arguments);
>+      return wrapper.apply(this, args);
>+    };
>+  };
>+
>+  // Returns a function that is the composition of a list of functions,
>each
>+  // consuming the return value of the function that follows.
>+  _.compose = function() {
>+    var funcs = arguments;
>+    return function() {
>+      var args = arguments;
>+      for (var i = funcs.length - 1; i >= 0; i--) {
>+        args = [funcs[i].apply(this, args)];
>+      }
>+      return args[0];
>+    };
>+  };
>+
>+  // Returns a function that will only be executed after being called N
>times.
>+  _.after = function(times, func) {
>+    if (times <= 0) return func();
>+    return function() {
>+      if (--times < 1) {
>+        return func.apply(this, arguments);
>+      }
>+    };
>+  };
>+
>+  // Object Functions
>+  // ----------------
>+
>+  // Retrieve the names of an object's properties.
>+  // Delegates to **ECMAScript 5**'s native `Object.keys`
>+  _.keys = nativeKeys || function(obj) {
>+    if (obj !== Object(obj)) throw new TypeError('Invalid object');
>+    var keys = [];
>+    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
>+    return keys;
>+  };
>+
>+  // Retrieve the values of an object's properties.
>+  _.values = function(obj) {
>+    var values = [];
>+    for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
>+    return values;
>+  };
>+
>+  // Convert an object into a list of `[key, value]` pairs.
>+  _.pairs = function(obj) {
>+    var pairs = [];
>+    for (var key in obj) if (_.has(obj, key)) pairs.push([key,
>obj[key]]);
>+    return pairs;
>+  };
>+
>+  // Invert the keys and values of an object. The values must be
>serializable.
>+  _.invert = function(obj) {
>+    var result = {};
>+    for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
>+    return result;
>+  };
>+
>+  // Return a sorted list of the function names available on the object.
>+  // Aliased as `methods`
>+  _.functions = _.methods = function(obj) {
>+    var names = [];
>+    for (var key in obj) {
>+      if (_.isFunction(obj[key])) names.push(key);
>+    }
>+    return names.sort();
>+  };
>+
>+  // Extend a given object with all the properties in passed-in
>object(s).
>+  _.extend = function(obj) {
>+    each(slice.call(arguments, 1), function(source) {
>+      if (source) {
>+        for (var prop in source) {
>+          obj[prop] = source[prop];
>+        }
>+      }
>+    });
>+    return obj;
>+  };
>+
>+  // Return a copy of the object only containing the whitelisted
>properties.
>+  _.pick = function(obj) {
>+    var copy = {};
>+    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
>+    each(keys, function(key) {
>+      if (key in obj) copy[key] = obj[key];
>+    });
>+    return copy;
>+  };
>+
>+   // Return a copy of the object without the blacklisted properties.
>+  _.omit = function(obj) {
>+    var copy = {};
>+    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
>+    for (var key in obj) {
>+      if (!_.contains(keys, key)) copy[key] = obj[key];
>+    }
>+    return copy;
>+  };
>+
>+  // Fill in a given object with default properties.
>+  _.defaults = function(obj) {
>+    each(slice.call(arguments, 1), function(source) {
>+      if (source) {
>+        for (var prop in source) {
>+          if (obj[prop] == null) obj[prop] = source[prop];
>+        }
>+      }
>+    });
>+    return obj;
>+  };
>+
>+  // Create a (shallow-cloned) duplicate of an object.
>+  _.clone = function(obj) {
>+    if (!_.isObject(obj)) return obj;
>+    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
>+  };
>+
>+  // Invokes interceptor with the obj, and then returns obj.
>+  // The primary purpose of this method is to "tap into" a method chain, 
>in
>+  // order to perform operations on intermediate results within the 
>chain.
>+  _.tap = function(obj, interceptor) {
>+    interceptor(obj);
>+    return obj;
>+  };
>+
>+  // Internal recursive comparison function for `isEqual`.
>+  var eq = function(a, b, aStack, bStack) {
>+    // Identical objects are equal. `0 === -0`, but they aren't 
>identical.
>+    // See the Harmony `egal` proposal: 
>http://wiki.ecmascript.org/doku.php?id=harmony:egal.
>+    if (a === b) return a !== 0 || 1 / a == 1 / b;
>+    // A strict comparison is necessary because `null == undefined`.
>+    if (a == null || b == null) return a === b;
>+    // Unwrap any wrapped objects.
>+    if (a instanceof _) a = a._wrapped;
>+    if (b instanceof _) b = b._wrapped;
>+    // Compare `[[Class]]` names.
>+    var className = toString.call(a);
>+    if (className != toString.call(b)) return false;
>+    switch (className) {
>+      // Strings, numbers, dates, and booleans are compared by value.
>+      case '[object String]':
>+        // Primitives and their corresponding object wrappers are 
>equivalent; thus, `"5"` is
>+        // equivalent to `new String("5")`.
>+        return a == String(b);
>+      case '[object Number]':
>+        // `NaN`s are equivalent, but non-reflexive. An `egal` 
>comparison is performed for
>+        // other numeric values.
>+        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
>+      case '[object Date]':
>+      case '[object Boolean]':
>+        // Coerce dates and booleans to numeric primitive values. Dates 
>are compared by their
>+        // millisecond representations. Note that invalid dates with 
>millisecond representations
>+        // of `NaN` are not equivalent.
>+        return +a == +b;
>+      // RegExps are compared by their source patterns and flags.
>+      case '[object RegExp]':
>+        return a.source == b.source &&
>+               a.global == b.global &&
>+               a.multiline == b.multiline &&
>+               a.ignoreCase == b.ignoreCase;
>+    }
>+    if (typeof a != 'object' || typeof b != 'object') return false;
>+    // Assume equality for cyclic structures. The algorithm for 
>detecting cyclic
>+    // structures is adapted from ES 5.1 section 15.12.3, abstract 
>operation `JO`.
>+    var length = aStack.length;
>+    while (length--) {
>+      // Linear search. Performance is inversely proportional to the 
>number of
>+      // unique nested structures.
>+      if (aStack[length] == a) return bStack[length] == b;
>+    }
>+    // Add the first object to the stack of traversed objects.
>+    aStack.push(a);
>+    bStack.push(b);
>+    var size = 0, result = true;
>+    // Recursively compare objects and arrays.
>+    if (className == '[object Array]') {
>+      // Compare array lengths to determine if a deep comparison is 
>necessary.
>+      size = a.length;
>+      result = size == b.length;
>+      if (result) {
>+        // Deep compare the contents, ignoring non-numeric properties.
>+        while (size--) {
>+          if (!(result = eq(a[size], b[size], aStack, bStack))) break;
>+        }
>+      }
>+    } else {
>+      // Objects with different constructors are not equivalent, but 
>`Object`s
>+      // from different frames are.
>+      var aCtor = a.constructor, bCtor = b.constructor;
>+      if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof 
>aCtor) &&
>+                               _.isFunction(bCtor) && (bCtor instanceof 
>bCtor))) {
>+        return false;
>+      }
>+      // Deep compare objects.
>+      for (var key in a) {
>+        if (_.has(a, key)) {
>+          // Count the expected number of properties.
>+          size++;
>+          // Deep compare each member.
>+          if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, 
>bStack))) break;
>+        }
>+      }
>+      // Ensure that both objects contain the same number of properties.
>+      if (result) {
>+        for (key in b) {
>+          if (_.has(b, key) && !(size--)) break;
>+        }
>+        result = !size;
>+      }
>+    }
>+    // Remove the first object from the stack of traversed objects.
>+    aStack.pop();
>+    bStack.pop();
>+    return result;
>+  };
>+
>+  // Perform a deep comparison to check if two objects are equal.
>+  _.isEqual = function(a, b) {
>+    return eq(a, b, [], []);
>+  };
>+
>+  // Is a given array, string, or object empty?
>+  // An "empty" object has no enumerable own-properties.
>+  _.isEmpty = function(obj) {
>+    if (obj == null) return true;
>+    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
>+    for (var key in obj) if (_.has(obj, key)) return false;
>+    return true;
>+  };
>+
>+  // Is a given value a DOM element?
>+  _.isElement = function(obj) {
>+    return !!(obj && obj.nodeType === 1);
>+  };
>+
>+  // Is a given value an array?
>+  // Delegates to ECMA5's native Array.isArray
>+  _.isArray = nativeIsArray || function(obj) {
>+    return toString.call(obj) == '[object Array]';
>+  };
>+
>+  // Is a given variable an object?
>+  _.isObject = function(obj) {
>+    return obj === Object(obj);
>+  };
>+
>+  // Add some isType methods: isArguments, isFunction, isString, 
>isNumber, isDate, isRegExp.
>+  each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], 
>function(name) {
>+    _['is' + name] = function(obj) {
>+      return toString.call(obj) == '[object ' + name + ']';
>+    };
>+  });
>+
>+  // Define a fallback version of the method in browsers (ahem, IE), 
>where
>+  // there isn't any inspectable "Arguments" type.
>+  if (!_.isArguments(arguments)) {
>+    _.isArguments = function(obj) {
>+      return !!(obj && _.has(obj, 'callee'));
>+    };
>+  }
>+
>+  // Optimize `isFunction` if appropriate.
>+  if (typeof (/./) !== 'function') {
>+    _.isFunction = function(obj) {
>+      return typeof obj === 'function';
>+    };
>+  }
>+
>+  // Is a given object a finite number?
>+  _.isFinite = function(obj) {
>+    return isFinite(obj) && !isNaN(parseFloat(obj));
>+  };
>+
>+  // Is the given value `NaN`? (NaN is the only number which does not 
>equal itself).
>+  _.isNaN = function(obj) {
>+    return _.isNumber(obj) && obj != +obj;
>+  };
>+
>+  // Is a given value a boolean?
>+  _.isBoolean = function(obj) {
>+    return obj === true || obj === false || toString.call(obj) == 
>'[object Boolean]';
>+  };
>+
>+  // Is a given value equal to null?
>+  _.isNull = function(obj) {
>+    return obj === null;
>+  };
>+
>+  // Is a given variable undefined?
>+  _.isUndefined = function(obj) {
>+    return obj === void 0;
>+  };
>+
>+  // Shortcut function for checking if an object has a given property 
>directly
>+  // on itself (in other words, not on a prototype).
>+  _.has = function(obj, key) {
>+    return hasOwnProperty.call(obj, key);
>+  };
>+
>+  // Utility Functions
>+  // -----------------
>+
>+  // Run Underscore.js in *noConflict* mode, returning the `_` variable 
>to its
>+  // previous owner. Returns a reference to the Underscore object.
>+  _.noConflict = function() {
>+    root._ = previousUnderscore;
>+    return this;
>+  };
>+
>+  // Keep the identity function around for default iterators.
>+  _.identity = function(value) {
>+    return value;
>+  };
>+
>+  // Run a function **n** times.
>+  _.times = function(n, iterator, context) {
>+    var accum = Array(n);
>+    for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
>+    return accum;
>+  };
>+
>+  // Return a random integer between min and max (inclusive).
>+  _.random = function(min, max) {
>+    if (max == null) {
>+      max = min;
>+      min = 0;
>+    }
>+    return min + (0 | Math.random() * (max - min + 1));
>+  };
>+
>+  // List of HTML entities for escaping.
>+  var entityMap = {
>+    escape: {
>+      '&': '&amp;',
>+      '<': '&lt;',
>+      '>': '&gt;',
>+      '"': '&quot;',
>+      "'": '&#x27;',
>+      '/': '&#x2F;'
>+    }
>+  };
>+  entityMap.unescape = _.invert(entityMap.escape);
>+
>+  // Regexes containing the keys and values listed immediately above.
>+  var entityRegexes = {
>+    escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 
>'g'),
>+    unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + 
>')', 'g')
>+  };
>+
>+  // Functions for escaping and unescaping strings to/from HTML 
>interpolation.
>+  _.each(['escape', 'unescape'], function(method) {
>+    _[method] = function(string) {
>+      if (string == null) return '';
>+      return ('' + string).replace(entityRegexes[method], 
>function(match) {
>+        return entityMap[method][match];
>+      });
>+    };
>+  });
>+
>+  // If the value of the named property is a function then invoke it;
>+  // otherwise, return it.
>+  _.result = function(object, property) {
>+    if (object == null) return null;
>+    var value = object[property];
>+    return _.isFunction(value) ? value.call(object) : value;
>+  };
>+
>+  // Add your own custom functions to the Underscore object.
>+  _.mixin = function(obj) {
>+    each(_.functions(obj), function(name){
>+      var func = _[name] = obj[name];
>+      _.prototype[name] = function() {
>+        var args = [this._wrapped];
>+        push.apply(args, arguments);
>+        return result.call(this, func.apply(_, args));
>+      };
>+    });
>+  };
>+
>+  // Generate a unique integer id (unique within the entire client 
>session).
>+  // Useful for temporary DOM ids.
>+  var idCounter = 0;
>+  _.uniqueId = function(prefix) {
>+    var id = '' + ++idCounter;
>+    return prefix ? prefix + id : id;
>+  };
>+
>+  // By default, Underscore uses ERB-style template delimiters, change 
>the
>+  // following template settings to use alternative delimiters.
>+  _.templateSettings = {
>+    evaluate    : /<%([\s\S]+?)%>/g,
>+    interpolate : /<%=([\s\S]+?)%>/g,
>+    escape      : /<%-([\s\S]+?)%>/g
>+  };
>+
>+  // When customizing `templateSettings`, if you don't want to define an
>+  // interpolation, evaluation or escaping regex, we need one that is
>+  // guaranteed not to match.
>+  var noMatch = /(.)^/;
>+
>+  // Certain characters need to be escaped so that they can be put into a
>+  // string literal.
>+  var escapes = {
>+    "'":      "'",
>+    '\\':     '\\',
>+    '\r':     'r',
>+    '\n':     'n',
>+    '\t':     't',
>+    '\u2028': 'u2028',
>+    '\u2029': 'u2029'
>+  };
>+
>+  var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
>+
>+  // JavaScript micro-templating, similar to John Resig's implementation.
>+  // Underscore templating handles arbitrary delimiters, preserves 
>whitespace,
>+  // and correctly escapes quotes within interpolated code.
>+  _.template = function(text, data, settings) {
>+    settings = _.defaults({}, settings, _.templateSettings);
>+
>+    // Combine delimiters into one regular expression via alternation.
>+    var matcher = new RegExp([
>+      (settings.escape || noMatch).source,
>+      (settings.interpolate || noMatch).source,
>+      (settings.evaluate || noMatch).source
>+    ].join('|') + '|$', 'g');
>+
>+    // Compile the template source, escaping string literals 
>appropriately.
>+    var index = 0;
>+    var source = "__p+='";
>+    text.replace(matcher, function(match, escape, interpolate, evaluate, 
>offset) {
>+      source += text.slice(index, offset)
>+        .replace(escaper, function(match) { return '\\' + 
>escapes[match]; });
>+
>+      if (escape) {
>+        source += "'+\n((__t=(" + escape + 
>"))==null?'':_.escape(__t))+\n'";
>+      }
>+      if (interpolate) {
>+        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
>+      }
>+      if (evaluate) {
>+        source += "';\n" + evaluate + "\n__p+='";
>+      }
>+      index = offset + match.length;
>+      return match;
>+    });
>+    source += "';\n";
>+
>+    // If a variable is not specified, place data values in local scope.
>+    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
>+
>+    source = "var __t,__p='',__j=Array.prototype.join," +
>+      "print=function(){__p+=__j.call(arguments,'');};\n" +
>+      source + "return __p;\n";
>+
>+    try {
>+      var render = new Function(settings.variable || 'obj', '_', source);
>+    } catch (e) {
>+      e.source = source;
>+      throw e;
>+    }
>+
>+    if (data) return render(data, _);
>+    var template = function(data) {
>+      return render.call(this, data, _);
>+    };
>+
>+    // Provide the compiled function source as a convenience for 
>precompilation.
>+    template.source = 'function(' + (settings.variable || 'obj') + 
>'){\n' + source + '}';
>+
>+    return template;
>+  };
>+
>+  // Add a "chain" function, which will delegate to the wrapper.
>+  _.chain = function(obj) {
>+    return _(obj).chain();
>+  };
>+
>+  // OOP
>+  // ---------------
>+  // If Underscore is called as a function, it returns a wrapped object 
>that
>+  // can be used OO-style. This wrapper holds altered versions of all the
>+  // underscore functions. Wrapped objects may be chained.
>+
>+  // Helper function to continue chaining intermediate results.
>+  var result = function(obj) {
>+    return this._chain ? _(obj).chain() : obj;
>+  };
>+
>+  // Add all of the Underscore functions to the wrapper object.
>+  _.mixin(_);
>+
>+  // Add all mutator Array functions to the wrapper.
>+  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], 
>function(name) {
>+    var method = ArrayProto[name];
>+    _.prototype[name] = function() {
>+      var obj = this._wrapped;
>+      method.apply(obj, arguments);
>+      if ((name == 'shift' || name == 'splice') && obj.length === 0) 
>delete obj[0];
>+      return result.call(this, obj);
>+    };
>+  });
>+
>+  // Add all accessor Array functions to the wrapper.
>+  each(['concat', 'join', 'slice'], function(name) {
>+    var method = ArrayProto[name];
>+    _.prototype[name] = function() {
>+      return result.call(this, method.apply(this._wrapped, arguments));
>+    };
>+  });
>+
>+  _.extend(_.prototype, {
>+
>+    // Start chaining a wrapped Underscore object.
>+    chain: function() {
>+      this._chain = true;
>+      return this;
>+    },
>+
>+    // Extracts the result from a wrapped and chained object.
>+    value: function() {
>+      return this._wrapped;
>+    }
>+
>+  });
>+
>+}).call(this);
>
>Added: 
>incubator/mesos/trunk/src/webui/master/static/underscore-1.4.3.min.js
>URL: 
>http://svn.apache.org/viewvc/incubator/mesos/trunk/src/webui/master/static
>/underscore-1.4.3.min.js?rev=1449845&view=auto
>==========================================================================
>====
>--- incubator/mesos/trunk/src/webui/master/static/underscore-1.4.3.min.js 
>(added)
>+++ incubator/mesos/trunk/src/webui/master/static/underscore-1.4.3.min.js 
>Mon Feb 25 19:45:45 2013
>@@ -0,0 +1 @@
>+(function(){var 
>n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototyp
>e,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEac
>h,p=e.map,v=e.reduce,h=e.reduceRight,g=e.filter,d=e.every,m=e.some,y=e.ind
>exOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,j=i.bind,w=function(n){
>return n instanceof w?n:this instanceof w?(this._wrapped=n,void 0):new 
>w(n)};"undefined"!=typeof exports?("undefined"!=typeof 
>module&&module.exports&&(exports=module.exports=w),exports._=w):n._=w,w.VE
>RSION="1.4.3";var 
>A=w.each=w.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEac
>h(t,e);else if(n.length===+n.length){for(var 
>u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in 
>n)if(w.has(n,a)&&t.call(e,n[a],a,n)===r)return};w.map=w.collect=function(n
>,t,r){var e=[];return 
>null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e[e.length]=t.call(
>r,n,u,i)}),e)};var O="Reduce of empty array with no initial 
>value";w.reduce=w.foldl=w.inject=fun
> ction(n,t,r,e){var 
>u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduce===v)return 
>e&&(t=w.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=
>t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return 
>r},w.reduceRight=w.foldr=function(n,t,r,e){var 
>u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduceRight===h)return 
>e&&(t=w.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var 
>i=n.length;if(i!==+i){var 
>a=w.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,
>r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return 
>r},w.find=w.detect=function(n,t,r){var e;return 
>E(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 
>0}),e},w.filter=w.select=function(n,t,r){var e=[];return 
>null==n?e:g&&n.filter===g?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,
>i)&&(e[e.length]=n)}),e)},w.reject=function(n,t,r){return 
>w.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},w.every=w.all=funct
>ion(n,t,e){t||(t=w.identity);var u=!0;return null==n?u:d&&n.ever
> 
>y===d?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 
>0:r}),!!u)};var E=w.some=w.any=function(n,t,e){t||(t=w.identity);var 
>u=!1;return 
>null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return 
>u||(u=t.call(e,n,i,a))?r:void 
>0}),!!u)};w.contains=w.include=function(n,t){return 
>null==n?!1:y&&n.indexOf===y?-1!=n.indexOf(t):E(n,function(n){return 
>n===t})},w.invoke=function(n,t){var r=o.call(arguments,2);return 
>w.map(n,function(n){return(w.isFunction(t)?t:n[t]).apply(n,r)})},w.pluck=f
>unction(n,t){return w.map(n,function(n){return 
>n[t]})},w.where=function(n,t){return 
>w.isEmpty(t)?[]:w.filter(n,function(n){for(var r in 
>t)if(t[r]!==n[r])return!1;return!0})},w.max=function(n,t,r){if(!t&&w.isArr
>ay(n)&&n[0]===+n[0]&&65535>n.length)return 
>Math.max.apply(Math,n);if(!t&&w.isEmpty(n))return-1/0;var 
>e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var 
>a=t?t.call(r,n,u,i):n;a>=e.computed&&(e={value:n,computed:a})}),e.value},w
>.min=function(n,t,r){if(!t&&w.isArra
> y(n)&&n[0]===+n[0]&&65535>n.length)return 
>Math.min.apply(Math,n);if(!t&&w.isEmpty(n))return 1/0;var 
>e={computed:1/0,value:1/0};return A(n,function(n,u,i){var 
>a=t?t.call(r,n,u,i):n;e.computed>a&&(e={value:n,computed:a})}),e.value},w.
>shuffle=function(n){var t,r=0,e=[];return 
>A(n,function(n){t=w.random(r++),e[r-1]=e[t],e[t]=n}),e};var 
>F=function(n){return w.isFunction(n)?n:function(t){return 
>t[n]}};w.sortBy=function(n,t,r){var e=F(t);return 
>w.pluck(w.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n
>,t,u)}}).sort(function(n,t){var 
>r=n.criteria,e=t.criteria;if(r!==e){if(r>e||void 0===r)return 
>1;if(e>r||void 0===e)return-1}return n.index<t.index?-1:1}),"value")};var 
>k=function(n,t,r,e){var u={},i=F(t||w.identity);return 
>A(n,function(t,a){var 
>o=i.call(r,t,a,n);e(u,o,t)}),u};w.groupBy=function(n,t,r){return 
>k(n,t,r,function(n,t,r){(w.has(n,t)?n[t]:n[t]=[]).push(r)})},w.countBy=fun
>ction(n,t,r){return 
>k(n,t,r,function(n,t){w.has(n,t)||(n[t]=0),n[t]++})},w.sortedIndex=fu
> nction(n,t,r,e){r=null==r?w.identity:F(r);for(var 
>u=r.call(e,t),i=0,a=n.length;a>i;){var 
>o=i+a>>>1;u>r.call(e,n[o])?i=o+1:a=o}return 
>i},w.toArray=function(n){return 
>n?w.isArray(n)?o.call(n):n.length===+n.length?w.map(n,w.identity):w.values
>(n):[]},w.size=function(n){return 
>null==n?0:n.length===+n.length?n.length:w.keys(n).length},w.first=w.head=w
>.take=function(n,t,r){return null==n?void 
>0:null==t||r?n[0]:o.call(n,0,t)},w.initial=function(n,t,r){return 
>o.call(n,0,n.length-(null==t||r?1:t))},w.last=function(n,t,r){return 
>null==n?void 
>0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},w.rest=w.tail
>=w.drop=function(n,t,r){return 
>o.call(n,null==t||r?1:t)},w.compact=function(n){return 
>w.filter(n,w.identity)};var R=function(n,t,r){return 
>A(n,function(n){w.isArray(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r};w.flat
>ten=function(n,t){return R(n,t,[])},w.without=function(n){return 
>w.difference(n,o.call(arguments,1))},w.uniq=w.unique=function(n,t,r,e){w.i
>sFunction(t)&&(e=r,r=t,t=!
> 1);var u=r?w.map(n,r,e):n,i=[],a=[];return 
>A(u,function(r,e){(t?e&&a[a.length-1]===r:w.contains(a,r))||(a.push(r),i.p
>ush(n[e]))}),i},w.union=function(){return 
>w.uniq(c.apply(e,arguments))},w.intersection=function(n){var 
>t=o.call(arguments,1);return w.filter(w.uniq(n),function(n){return 
>w.every(t,function(t){return 
>w.indexOf(t,n)>=0})})},w.difference=function(n){var 
>t=c.apply(e,o.call(arguments,1));return 
>w.filter(n,function(n){return!w.contains(t,n)})},w.zip=function(){for(var 
>n=o.call(arguments),t=w.max(w.pluck(n,"length")),r=Array(t),e=0;t>e;e++)r[
>e]=w.pluck(n,""+e);return 
>r},w.object=function(n,t){if(null==n)return{};for(var 
>r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return 
>r},w.indexOf=function(n,t,r){if(null==n)return-1;var 
>e=0,u=n.length;if(r){if("number"!=typeof r)return 
>e=w.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf
>===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return 
>e;return-1},w.lastIndexOf=function(n,t,r){if(nul
> l==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return 
>e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var 
>u=e?r:n.length;u--;)if(n[u]===t)return 
>u;return-1},w.range=function(n,t,r){1>=arguments.length&&(t=n||0,n=0),r=ar
>guments[2]||1;for(var 
>e=Math.max(Math.ceil((t-n)/r),0),u=0,i=Array(e);e>u;)i[u++]=n,n+=r;return 
>i};var I=function(){};w.bind=function(n,t){var 
>r,e;if(n.bind===j&&j)return 
>j.apply(n,o.call(arguments,1));if(!w.isFunction(n))throw new 
>TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof 
>e))return 
>n.apply(t,r.concat(o.call(arguments)));I.prototype=n.prototype;var u=new 
>I;I.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return 
>Object(i)===i?i:u}},w.bindAll=function(n){var 
>t=o.call(arguments,1);return 
>0==t.length&&(t=w.functions(n)),A(t,function(t){n[t]=w.bind(n[t],n)}),n},w
>.memoize=function(n,t){var r={};return t||(t=w.identity),function(){var 
>e=t.apply(this,arguments);return 
>w.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},w.delay=fun
> ction(n,t){var r=o.call(arguments,2);return setTimeout(function(){return 
>n.apply(null,r)},t)},w.defer=function(n){return 
>w.delay.apply(w,[n,1].concat(o.call(arguments,1)))},w.throttle=function(n,
>t){var r,e,u,i,a=0,o=function(){a=new Date,u=null,i=n.apply(r,e)};return 
>function(){var c=new Date,l=t-(c-a);return 
>r=this,e=arguments,0>=l?(clearTimeout(u),u=null,a=c,i=n.apply(r,e)):u||(u=
>setTimeout(o,l)),i}},w.debounce=function(n,t,r){var e,u;return 
>function(){var 
>i=this,a=arguments,o=function(){e=null,r||(u=n.apply(i,a))},c=r&&!e;return
> 
>clearTimeout(e),e=setTimeout(o,t),c&&(u=n.apply(i,a)),u}},w.once=function(
>n){var t,r=!1;return function(){return 
>r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},w.wrap=function(n,t){retur
>n function(){var r=[n];return 
>a.apply(r,arguments),t.apply(this,r)}},w.compose=function(){var 
>n=arguments;return function(){for(var 
>t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return 
>t[0]}},w.after=function(n,t){return 0>=n?t():function(){return 1>--n
> ?t.apply(this,arguments):void 
>0}},w.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid 
>object");var t=[];for(var r in n)w.has(n,r)&&(t[t.length]=r);return 
>t},w.values=function(n){var t=[];for(var r in 
>n)w.has(n,r)&&t.push(n[r]);return t},w.pairs=function(n){var t=[];for(var 
>r in n)w.has(n,r)&&t.push([r,n[r]]);return t},w.invert=function(n){var 
>t={};for(var r in n)w.has(n,r)&&(t[n[r]]=r);return 
>t},w.functions=w.methods=function(n){var t=[];for(var r in 
>n)w.isFunction(n[r])&&t.push(r);return 
>t.sort()},w.extend=function(n){return 
>A(o.call(arguments,1),function(t){if(t)for(var r in 
>t)n[r]=t[r]}),n},w.pick=function(n){var 
>t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in 
>n&&(t[r]=n[r])}),t},w.omit=function(n){var 
>t={},r=c.apply(e,o.call(arguments,1));for(var u in 
>n)w.contains(r,u)||(t[u]=n[u]);return t},w.defaults=function(n){return 
>A(o.call(arguments,1),function(t){if(t)for(var r in 
>t)null==n[r]&&(n[r]=t[r])}),n},w.clone=function(n){return w.isObje
> 
>ct(n)?w.isArray(n)?n.slice():w.extend({},n):n},w.tap=function(n,t){return 
>t(n),n};var S=function(n,t,r,e){if(n===t)return 
>0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof 
>w&&(n=n._wrapped),t instanceof w&&(t=t._wrapped);var 
>u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object 
>String]":return n==t+"";case"[object Number]":return 
>n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object 
>Boolean]":return+n==+t;case"[object RegExp]":return 
>n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignore
>Case==t.ignoreCase}if("object"!=typeof n||"object"!=typeof 
>t)return!1;for(var i=r.length;i--;)if(r[i]==n)return 
>e[i]==t;r.push(n),e.push(t);var a=0,o=!0;if("[object 
>Array]"==u){if(a=n.length,o=a==t.length)for(;a--&&(o=S(n[a],t[a],r,e)););}
>else{var c=n.constructor,f=t.constructor;if(c!==f&&!(w.isFunction(c)&&c 
>instanceof c&&w.isFunction(f)&&f instanceof f))return!1;for(var s in 
>n)if(w.has(n,s)&&(a++,!(o=w.has(t,s)&&S(n[s],t[s],r,e))))break;if(o)
> {for(s in t)if(w.has(t,s)&&!a--)break;o=!a}}return 
>r.pop(),e.pop(),o};w.isEqual=function(n,t){return 
>S(n,t,[],[])},w.isEmpty=function(n){if(null==n)return!0;if(w.isArray(n)||w
>.isString(n))return 0===n.length;for(var t in 
>n)if(w.has(n,t))return!1;return!0},w.isElement=function(n){return!(!n||1!=
>=n.nodeType)},w.isArray=x||function(n){return"[object 
>Array]"==l.call(n)},w.isObject=function(n){return 
>n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"
>],function(n){w["is"+n]=function(t){return l.call(t)=="[object 
>"+n+"]"}}),w.isArguments(arguments)||(w.isArguments=function(n){return!(!n
>||!w.has(n,"callee"))}),w.isFunction=function(n){return"function"==typeof 
>n},w.isFinite=function(n){return 
>isFinite(n)&&!isNaN(parseFloat(n))},w.isNaN=function(n){return 
>w.isNumber(n)&&n!=+n},w.isBoolean=function(n){return 
>n===!0||n===!1||"[object 
>Boolean]"==l.call(n)},w.isNull=function(n){return 
>null===n},w.isUndefined=function(n){return void 
>0===n},w.has=function(n,t){return
>  f.call(n,t)},w.noConflict=function(){return 
>n._=t,this},w.identity=function(n){return 
>n},w.times=function(n,t,r){for(var 
>e=Array(n),u=0;n>u;u++)e[u]=t.call(r,u);return 
>e},w.random=function(n,t){return 
>null==t&&(t=n,n=0),n+(0|Math.random()*(t-n+1))};var 
>T={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/"
>:"&#x2F;"}};T.unescape=w.invert(T.escape);var 
>M={escape:RegExp("["+w.keys(T.escape).join("")+"]","g"),unescape:RegExp("(
>"+w.keys(T.unescape).join("|")+")","g")};w.each(["escape","unescape"],func
>tion(n){w[n]=function(t){return 
>null==t?"":(""+t).replace(M[n],function(t){return 
>T[n][t]})}}),w.result=function(n,t){if(null==n)return null;var 
>r=n[t];return 
>w.isFunction(r)?r.call(n):r},w.mixin=function(n){A(w.functions(n),function
>(t){var r=w[t]=n[t];w.prototype[t]=function(){var 
>n=[this._wrapped];return 
>a.apply(n,arguments),z.call(this,r.apply(w,n))}})};var 
>N=0;w.uniqueId=function(n){var t=""+ ++N;return 
>n?n+t:t},w.templateSettings={evaluate:/<%([\s\S]+?)%>/g,
> interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var 
>q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n","	":"t","\u2028":"u2028","
>\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;w.template=function(n,t,
>r){r=w.defaults({},r,w.templateSettings);var 
>e=RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).s
>ource].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,a,o){
>return 
>i+=n.slice(u,o).replace(D,function(n){return"\\"+B[n]}),r&&(i+="'+\n((__t=
>("+r+"))==null?'':_.escape(__t))+\n'"),e&&(i+="'+\n((__t=("+e+"))==null?''
>:__t)+\n'"),a&&(i+="';\n"+a+"\n__p+='"),u=o+t.length,t}),i+="';\n",r.varia
>ble||(i="with(obj||{}){\n"+i+"}\n"),i="var 
>__t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(argumen
>ts,'');};\n"+i+"return __p;\n";try{var 
>a=Function(r.variable||"obj","_",i)}catch(o){throw 
>o.source=i,o}if(t)return a(t,w);var c=function(n){return 
>a.call(this,n,w)};return 
>c.source="function("+(r.variable||"obj")+"){\n"+i+"}",c},w.chain=fun
> ction(n){return w(n).chain()};var z=function(n){return 
>this._chain?w(n).chain():n};w.mixin(w),A(["pop","push","reverse","shift","
>sort","splice","unshift"],function(n){var 
>t=e[n];w.prototype[n]=function(){var r=this._wrapped;return 
>t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete 
>r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var 
>t=e[n];w.prototype[n]=function(){return 
>z.call(this,t.apply(this._wrapped,arguments))}}),w.extend(w.prototype,{cha
>in:function(){return this._chain=!0,this},value:function(){return 
>this._wrapped}})}).call(this);
>\ No newline at end of file
>
>