backbonejs-rails 0.0.7 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/backbonejs-rails.gemspec +3 -4
- data/lib/backbonejs-rails/version.rb +1 -1
- data/vendor/assets/javascripts/backbone.js +1003 -722
- data/vendor/assets/javascripts/underscore.js +532 -274
- metadata +5 -24
- data/vendor/assets/javascripts/backbone.min.js +0 -37
- data/vendor/assets/javascripts/icanhaz.min.js +0 -11
- data/vendor/assets/javascripts/underscore.min.js +0 -31
| @@ -1,10 +1,8 @@ | |
| 1 | 
            -
            //     Underscore.js 1. | 
| 2 | 
            -
            //      | 
| 3 | 
            -
            //      | 
| 4 | 
            -
            //      | 
| 5 | 
            -
            //      | 
| 6 | 
            -
            //     For all details and documentation:
         | 
| 7 | 
            -
            //     http://documentcloud.github.com/underscore
         | 
| 1 | 
            +
            //     Underscore.js 1.5.0
         | 
| 2 | 
            +
            //     http://underscorejs.org
         | 
| 3 | 
            +
            //     (c) 2009-2011 Jeremy Ashkenas, DocumentCloud Inc.
         | 
| 4 | 
            +
            //     (c) 2011-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
         | 
| 5 | 
            +
            //     Underscore may be freely distributed under the MIT license.
         | 
| 8 6 |  | 
| 9 7 | 
             
            (function() {
         | 
| 10 8 |  | 
| @@ -24,10 +22,12 @@ | |
| 24 22 | 
             
              var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
         | 
| 25 23 |  | 
| 26 24 | 
             
              // Create quick reference variables for speed access to core prototypes.
         | 
| 27 | 
            -
              var | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 25 | 
            +
              var
         | 
| 26 | 
            +
                push             = ArrayProto.push,
         | 
| 27 | 
            +
                slice            = ArrayProto.slice,
         | 
| 28 | 
            +
                concat           = ArrayProto.concat,
         | 
| 29 | 
            +
                toString         = ObjProto.toString,
         | 
| 30 | 
            +
                hasOwnProperty   = ObjProto.hasOwnProperty;
         | 
| 31 31 |  | 
| 32 32 | 
             
              // All **ECMAScript 5** native function implementations that we hope to use
         | 
| 33 33 | 
             
              // are declared here.
         | 
| @@ -46,7 +46,11 @@ | |
| 46 46 | 
             
                nativeBind         = FuncProto.bind;
         | 
| 47 47 |  | 
| 48 48 | 
             
              // Create a safe reference to the Underscore object for use below.
         | 
| 49 | 
            -
              var _ = function(obj) { | 
| 49 | 
            +
              var _ = function(obj) {
         | 
| 50 | 
            +
                if (obj instanceof _) return obj;
         | 
| 51 | 
            +
                if (!(this instanceof _)) return new _(obj);
         | 
| 52 | 
            +
                this._wrapped = obj;
         | 
| 53 | 
            +
              };
         | 
| 50 54 |  | 
| 51 55 | 
             
              // Export the Underscore object for **Node.js**, with
         | 
| 52 56 | 
             
              // backwards-compatibility for the old `require()` API. If we're in
         | 
| @@ -58,11 +62,11 @@ | |
| 58 62 | 
             
                }
         | 
| 59 63 | 
             
                exports._ = _;
         | 
| 60 64 | 
             
              } else {
         | 
| 61 | 
            -
                root | 
| 65 | 
            +
                root._ = _;
         | 
| 62 66 | 
             
              }
         | 
| 63 67 |  | 
| 64 68 | 
             
              // Current version.
         | 
| 65 | 
            -
              _.VERSION = '1. | 
| 69 | 
            +
              _.VERSION = '1.5.0';
         | 
| 66 70 |  | 
| 67 71 | 
             
              // Collection Functions
         | 
| 68 72 | 
             
              // --------------------
         | 
| @@ -76,7 +80,7 @@ | |
| 76 80 | 
             
                  obj.forEach(iterator, context);
         | 
| 77 81 | 
             
                } else if (obj.length === +obj.length) {
         | 
| 78 82 | 
             
                  for (var i = 0, l = obj.length; i < l; i++) {
         | 
| 79 | 
            -
                    if ( | 
| 83 | 
            +
                    if (iterator.call(context, obj[i], i, obj) === breaker) return;
         | 
| 80 84 | 
             
                  }
         | 
| 81 85 | 
             
                } else {
         | 
| 82 86 | 
             
                  for (var key in obj) {
         | 
| @@ -94,12 +98,13 @@ | |
| 94 98 | 
             
                if (obj == null) return results;
         | 
| 95 99 | 
             
                if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
         | 
| 96 100 | 
             
                each(obj, function(value, index, list) {
         | 
| 97 | 
            -
                  results | 
| 101 | 
            +
                  results.push(iterator.call(context, value, index, list));
         | 
| 98 102 | 
             
                });
         | 
| 99 | 
            -
                if (obj.length === +obj.length) results.length = obj.length;
         | 
| 100 103 | 
             
                return results;
         | 
| 101 104 | 
             
              };
         | 
| 102 105 |  | 
| 106 | 
            +
              var reduceError = 'Reduce of empty array with no initial value';
         | 
| 107 | 
            +
             | 
| 103 108 | 
             
              // **Reduce** builds up a single result from a list of values, aka `inject`,
         | 
| 104 109 | 
             
              // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
         | 
| 105 110 | 
             
              _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
         | 
| @@ -117,7 +122,7 @@ | |
| 117 122 | 
             
                    memo = iterator.call(context, memo, value, index, list);
         | 
| 118 123 | 
             
                  }
         | 
| 119 124 | 
             
                });
         | 
| 120 | 
            -
                if (!initial) throw new TypeError( | 
| 125 | 
            +
                if (!initial) throw new TypeError(reduceError);
         | 
| 121 126 | 
             
                return memo;
         | 
| 122 127 | 
             
              };
         | 
| 123 128 |  | 
| @@ -130,9 +135,22 @@ | |
| 130 135 | 
             
                  if (context) iterator = _.bind(iterator, context);
         | 
| 131 136 | 
             
                  return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
         | 
| 132 137 | 
             
                }
         | 
| 133 | 
            -
                var  | 
| 134 | 
            -
                if ( | 
| 135 | 
            -
             | 
| 138 | 
            +
                var length = obj.length;
         | 
| 139 | 
            +
                if (length !== +length) {
         | 
| 140 | 
            +
                  var keys = _.keys(obj);
         | 
| 141 | 
            +
                  length = keys.length;
         | 
| 142 | 
            +
                }
         | 
| 143 | 
            +
                each(obj, function(value, index, list) {
         | 
| 144 | 
            +
                  index = keys ? keys[--length] : --length;
         | 
| 145 | 
            +
                  if (!initial) {
         | 
| 146 | 
            +
                    memo = obj[index];
         | 
| 147 | 
            +
                    initial = true;
         | 
| 148 | 
            +
                  } else {
         | 
| 149 | 
            +
                    memo = iterator.call(context, memo, obj[index], index, list);
         | 
| 150 | 
            +
                  }
         | 
| 151 | 
            +
                });
         | 
| 152 | 
            +
                if (!initial) throw new TypeError(reduceError);
         | 
| 153 | 
            +
                return memo;
         | 
| 136 154 | 
             
              };
         | 
| 137 155 |  | 
| 138 156 | 
             
              // Return the first value which passes a truth test. Aliased as `detect`.
         | 
| @@ -155,32 +173,30 @@ | |
| 155 173 | 
             
                if (obj == null) return results;
         | 
| 156 174 | 
             
                if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
         | 
| 157 175 | 
             
                each(obj, function(value, index, list) {
         | 
| 158 | 
            -
                  if (iterator.call(context, value, index, list)) results | 
| 176 | 
            +
                  if (iterator.call(context, value, index, list)) results.push(value);
         | 
| 159 177 | 
             
                });
         | 
| 160 178 | 
             
                return results;
         | 
| 161 179 | 
             
              };
         | 
| 162 180 |  | 
| 163 181 | 
             
              // Return all the elements for which a truth test fails.
         | 
| 164 182 | 
             
              _.reject = function(obj, iterator, context) {
         | 
| 165 | 
            -
                 | 
| 166 | 
            -
             | 
| 167 | 
            -
                 | 
| 168 | 
            -
                  if (!iterator.call(context, value, index, list)) results[results.length] = value;
         | 
| 169 | 
            -
                });
         | 
| 170 | 
            -
                return results;
         | 
| 183 | 
            +
                return _.filter(obj, function(value, index, list) {
         | 
| 184 | 
            +
                  return !iterator.call(context, value, index, list);
         | 
| 185 | 
            +
                }, context);
         | 
| 171 186 | 
             
              };
         | 
| 172 187 |  | 
| 173 188 | 
             
              // Determine whether all of the elements match a truth test.
         | 
| 174 189 | 
             
              // Delegates to **ECMAScript 5**'s native `every` if available.
         | 
| 175 190 | 
             
              // Aliased as `all`.
         | 
| 176 191 | 
             
              _.every = _.all = function(obj, iterator, context) {
         | 
| 192 | 
            +
                iterator || (iterator = _.identity);
         | 
| 177 193 | 
             
                var result = true;
         | 
| 178 194 | 
             
                if (obj == null) return result;
         | 
| 179 195 | 
             
                if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
         | 
| 180 196 | 
             
                each(obj, function(value, index, list) {
         | 
| 181 197 | 
             
                  if (!(result = result && iterator.call(context, value, index, list))) return breaker;
         | 
| 182 198 | 
             
                });
         | 
| 183 | 
            -
                return result;
         | 
| 199 | 
            +
                return !!result;
         | 
| 184 200 | 
             
              };
         | 
| 185 201 |  | 
| 186 202 | 
             
              // Determine if at least one element in the object matches a truth test.
         | 
| @@ -197,23 +213,22 @@ | |
| 197 213 | 
             
                return !!result;
         | 
| 198 214 | 
             
              };
         | 
| 199 215 |  | 
| 200 | 
            -
              // Determine if  | 
| 201 | 
            -
              // Aliased as ` | 
| 202 | 
            -
              _. | 
| 203 | 
            -
                 | 
| 204 | 
            -
                if (obj == null) return found;
         | 
| 216 | 
            +
              // Determine if the array or object contains a given value (using `===`).
         | 
| 217 | 
            +
              // Aliased as `include`.
         | 
| 218 | 
            +
              _.contains = _.include = function(obj, target) {
         | 
| 219 | 
            +
                if (obj == null) return false;
         | 
| 205 220 | 
             
                if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
         | 
| 206 | 
            -
                 | 
| 221 | 
            +
                return any(obj, function(value) {
         | 
| 207 222 | 
             
                  return value === target;
         | 
| 208 223 | 
             
                });
         | 
| 209 | 
            -
                return found;
         | 
| 210 224 | 
             
              };
         | 
| 211 225 |  | 
| 212 226 | 
             
              // Invoke a method (with arguments) on every item in a collection.
         | 
| 213 227 | 
             
              _.invoke = function(obj, method) {
         | 
| 214 228 | 
             
                var args = slice.call(arguments, 2);
         | 
| 229 | 
            +
                var isFunc = _.isFunction(method);
         | 
| 215 230 | 
             
                return _.map(obj, function(value) {
         | 
| 216 | 
            -
                  return ( | 
| 231 | 
            +
                  return (isFunc ? method : value[method]).apply(value, args);
         | 
| 217 232 | 
             
                });
         | 
| 218 233 | 
             
              };
         | 
| 219 234 |  | 
| @@ -222,23 +237,47 @@ | |
| 222 237 | 
             
                return _.map(obj, function(value){ return value[key]; });
         | 
| 223 238 | 
             
              };
         | 
| 224 239 |  | 
| 240 | 
            +
              // Convenience version of a common use case of `filter`: selecting only objects
         | 
| 241 | 
            +
              // containing specific `key:value` pairs.
         | 
| 242 | 
            +
              _.where = function(obj, attrs, first) {
         | 
| 243 | 
            +
                if (_.isEmpty(attrs)) return first ? void 0 : [];
         | 
| 244 | 
            +
                return _[first ? 'find' : 'filter'](obj, function(value) {
         | 
| 245 | 
            +
                  for (var key in attrs) {
         | 
| 246 | 
            +
                    if (attrs[key] !== value[key]) return false;
         | 
| 247 | 
            +
                  }
         | 
| 248 | 
            +
                  return true;
         | 
| 249 | 
            +
                });
         | 
| 250 | 
            +
              };
         | 
| 251 | 
            +
             | 
| 252 | 
            +
              // Convenience version of a common use case of `find`: getting the first object
         | 
| 253 | 
            +
              // containing specific `key:value` pairs.
         | 
| 254 | 
            +
              _.findWhere = function(obj, attrs) {
         | 
| 255 | 
            +
                return _.where(obj, attrs, true);
         | 
| 256 | 
            +
              };
         | 
| 257 | 
            +
             | 
| 225 258 | 
             
              // Return the maximum element or (element-based computation).
         | 
| 259 | 
            +
              // Can't optimize arrays of integers longer than 65,535 elements.
         | 
| 260 | 
            +
              // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
         | 
| 226 261 | 
             
              _.max = function(obj, iterator, context) {
         | 
| 227 | 
            -
                if (!iterator && _.isArray(obj) | 
| 262 | 
            +
                if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
         | 
| 263 | 
            +
                  return Math.max.apply(Math, obj);
         | 
| 264 | 
            +
                }
         | 
| 228 265 | 
             
                if (!iterator && _.isEmpty(obj)) return -Infinity;
         | 
| 229 | 
            -
                var result = {computed : -Infinity};
         | 
| 266 | 
            +
                var result = {computed : -Infinity, value: -Infinity};
         | 
| 230 267 | 
             
                each(obj, function(value, index, list) {
         | 
| 231 268 | 
             
                  var computed = iterator ? iterator.call(context, value, index, list) : value;
         | 
| 232 | 
            -
                  computed  | 
| 269 | 
            +
                  computed > result.computed && (result = {value : value, computed : computed});
         | 
| 233 270 | 
             
                });
         | 
| 234 271 | 
             
                return result.value;
         | 
| 235 272 | 
             
              };
         | 
| 236 273 |  | 
| 237 274 | 
             
              // Return the minimum element (or element-based computation).
         | 
| 238 275 | 
             
              _.min = function(obj, iterator, context) {
         | 
| 239 | 
            -
                if (!iterator && _.isArray(obj) | 
| 276 | 
            +
                if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
         | 
| 277 | 
            +
                  return Math.min.apply(Math, obj);
         | 
| 278 | 
            +
                }
         | 
| 240 279 | 
             
                if (!iterator && _.isEmpty(obj)) return Infinity;
         | 
| 241 | 
            -
                var result = {computed : Infinity};
         | 
| 280 | 
            +
                var result = {computed : Infinity, value: Infinity};
         | 
| 242 281 | 
             
                each(obj, function(value, index, list) {
         | 
| 243 282 | 
             
                  var computed = iterator ? iterator.call(context, value, index, list) : value;
         | 
| 244 283 | 
             
                  computed < result.computed && (result = {value : value, computed : computed});
         | 
| @@ -248,81 +287,110 @@ | |
| 248 287 |  | 
| 249 288 | 
             
              // Shuffle an array.
         | 
| 250 289 | 
             
              _.shuffle = function(obj) {
         | 
| 251 | 
            -
                var  | 
| 252 | 
            -
                 | 
| 253 | 
            -
             | 
| 254 | 
            -
             | 
| 255 | 
            -
                   | 
| 256 | 
            -
             | 
| 257 | 
            -
             | 
| 258 | 
            -
                    shuffled[rand] = value;
         | 
| 259 | 
            -
                  }
         | 
| 290 | 
            +
                var rand;
         | 
| 291 | 
            +
                var index = 0;
         | 
| 292 | 
            +
                var shuffled = [];
         | 
| 293 | 
            +
                each(obj, function(value) {
         | 
| 294 | 
            +
                  rand = _.random(index++);
         | 
| 295 | 
            +
                  shuffled[index - 1] = shuffled[rand];
         | 
| 296 | 
            +
                  shuffled[rand] = value;
         | 
| 260 297 | 
             
                });
         | 
| 261 298 | 
             
                return shuffled;
         | 
| 262 299 | 
             
              };
         | 
| 263 300 |  | 
| 301 | 
            +
              // An internal function to generate lookup iterators.
         | 
| 302 | 
            +
              var lookupIterator = function(value) {
         | 
| 303 | 
            +
                return _.isFunction(value) ? value : function(obj){ return obj[value]; };
         | 
| 304 | 
            +
              };
         | 
| 305 | 
            +
             | 
| 264 306 | 
             
              // Sort the object's values by a criterion produced by an iterator.
         | 
| 265 | 
            -
              _.sortBy = function(obj,  | 
| 307 | 
            +
              _.sortBy = function(obj, value, context) {
         | 
| 308 | 
            +
                var iterator = lookupIterator(value);
         | 
| 266 309 | 
             
                return _.pluck(_.map(obj, function(value, index, list) {
         | 
| 267 310 | 
             
                  return {
         | 
| 268 311 | 
             
                    value : value,
         | 
| 312 | 
            +
                    index : index,
         | 
| 269 313 | 
             
                    criteria : iterator.call(context, value, index, list)
         | 
| 270 314 | 
             
                  };
         | 
| 271 315 | 
             
                }).sort(function(left, right) {
         | 
| 272 | 
            -
                  var a = left.criteria | 
| 273 | 
            -
                   | 
| 316 | 
            +
                  var a = left.criteria;
         | 
| 317 | 
            +
                  var b = right.criteria;
         | 
| 318 | 
            +
                  if (a !== b) {
         | 
| 319 | 
            +
                    if (a > b || a === void 0) return 1;
         | 
| 320 | 
            +
                    if (a < b || b === void 0) return -1;
         | 
| 321 | 
            +
                  }
         | 
| 322 | 
            +
                  return left.index < right.index ? -1 : 1;
         | 
| 274 323 | 
             
                }), 'value');
         | 
| 275 324 | 
             
              };
         | 
| 276 325 |  | 
| 277 | 
            -
              //  | 
| 278 | 
            -
               | 
| 279 | 
            -
              _.groupBy = function(obj, val) {
         | 
| 326 | 
            +
              // An internal function used for aggregate "group by" operations.
         | 
| 327 | 
            +
              var group = function(obj, value, context, behavior) {
         | 
| 280 328 | 
             
                var result = {};
         | 
| 281 | 
            -
                var iterator =  | 
| 329 | 
            +
                var iterator = lookupIterator(value == null ? _.identity : value);
         | 
| 282 330 | 
             
                each(obj, function(value, index) {
         | 
| 283 | 
            -
                  var key = iterator(value, index);
         | 
| 284 | 
            -
                  (result | 
| 331 | 
            +
                  var key = iterator.call(context, value, index, obj);
         | 
| 332 | 
            +
                  behavior(result, key, value);
         | 
| 285 333 | 
             
                });
         | 
| 286 334 | 
             
                return result;
         | 
| 287 335 | 
             
              };
         | 
| 288 336 |  | 
| 289 | 
            -
              //  | 
| 290 | 
            -
              //  | 
| 291 | 
            -
              _. | 
| 292 | 
            -
                 | 
| 337 | 
            +
              // Groups the object's values by a criterion. Pass either a string attribute
         | 
| 338 | 
            +
              // to group by, or a function that returns the criterion.
         | 
| 339 | 
            +
              _.groupBy = function(obj, value, context) {
         | 
| 340 | 
            +
                return group(obj, value, context, function(result, key, value) {
         | 
| 341 | 
            +
                  (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
         | 
| 342 | 
            +
                });
         | 
| 343 | 
            +
              };
         | 
| 344 | 
            +
             | 
| 345 | 
            +
              // Counts instances of an object that group by a certain criterion. Pass
         | 
| 346 | 
            +
              // either a string attribute to count by, or a function that returns the
         | 
| 347 | 
            +
              // criterion.
         | 
| 348 | 
            +
              _.countBy = function(obj, value, context) {
         | 
| 349 | 
            +
                return group(obj, value, context, function(result, key) {
         | 
| 350 | 
            +
                  if (!_.has(result, key)) result[key] = 0;
         | 
| 351 | 
            +
                  result[key]++;
         | 
| 352 | 
            +
                });
         | 
| 353 | 
            +
              };
         | 
| 354 | 
            +
             | 
| 355 | 
            +
              // Use a comparator function to figure out the smallest index at which
         | 
| 356 | 
            +
              // an object should be inserted so as to maintain order. Uses binary search.
         | 
| 357 | 
            +
              _.sortedIndex = function(array, obj, iterator, context) {
         | 
| 358 | 
            +
                iterator = iterator == null ? _.identity : lookupIterator(iterator);
         | 
| 359 | 
            +
                var value = iterator.call(context, obj);
         | 
| 293 360 | 
             
                var low = 0, high = array.length;
         | 
| 294 361 | 
             
                while (low < high) {
         | 
| 295 | 
            -
                  var mid = (low + high)  | 
| 296 | 
            -
                  iterator(array[mid]) <  | 
| 362 | 
            +
                  var mid = (low + high) >>> 1;
         | 
| 363 | 
            +
                  iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
         | 
| 297 364 | 
             
                }
         | 
| 298 365 | 
             
                return low;
         | 
| 299 366 | 
             
              };
         | 
| 300 367 |  | 
| 301 | 
            -
              // Safely  | 
| 302 | 
            -
              _.toArray = function( | 
| 303 | 
            -
                if (! | 
| 304 | 
            -
                if ( | 
| 305 | 
            -
                if ( | 
| 306 | 
            -
                 | 
| 307 | 
            -
                return _.values(iterable);
         | 
| 368 | 
            +
              // Safely create a real, live array from anything iterable.
         | 
| 369 | 
            +
              _.toArray = function(obj) {
         | 
| 370 | 
            +
                if (!obj) return [];
         | 
| 371 | 
            +
                if (_.isArray(obj)) return slice.call(obj);
         | 
| 372 | 
            +
                if (obj.length === +obj.length) return _.map(obj, _.identity);
         | 
| 373 | 
            +
                return _.values(obj);
         | 
| 308 374 | 
             
              };
         | 
| 309 375 |  | 
| 310 376 | 
             
              // Return the number of elements in an object.
         | 
| 311 377 | 
             
              _.size = function(obj) {
         | 
| 312 | 
            -
                 | 
| 378 | 
            +
                if (obj == null) return 0;
         | 
| 379 | 
            +
                return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
         | 
| 313 380 | 
             
              };
         | 
| 314 381 |  | 
| 315 382 | 
             
              // Array Functions
         | 
| 316 383 | 
             
              // ---------------
         | 
| 317 384 |  | 
| 318 385 | 
             
              // Get the first element of an array. Passing **n** will return the first N
         | 
| 319 | 
            -
              // values in the array. Aliased as `head`. The **guard** check | 
| 320 | 
            -
              // with `_.map`.
         | 
| 321 | 
            -
              _.first = _.head = function(array, n, guard) {
         | 
| 386 | 
            +
              // values in the array. Aliased as `head` and `take`. The **guard** check
         | 
| 387 | 
            +
              // allows it to work with `_.map`.
         | 
| 388 | 
            +
              _.first = _.head = _.take = function(array, n, guard) {
         | 
| 389 | 
            +
                if (array == null) return void 0;
         | 
| 322 390 | 
             
                return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
         | 
| 323 391 | 
             
              };
         | 
| 324 392 |  | 
| 325 | 
            -
              // Returns everything but the last entry of the array.  | 
| 393 | 
            +
              // Returns everything but the last entry of the array. Especially useful on
         | 
| 326 394 | 
             
              // the arguments object. Passing **n** will return all the values in
         | 
| 327 395 | 
             
              // the array, excluding the last N. The **guard** check allows it to work with
         | 
| 328 396 | 
             
              // `_.map`.
         | 
| @@ -333,6 +401,7 @@ | |
| 333 401 | 
             
              // Get the last element of an array. Passing **n** will return the last N
         | 
| 334 402 | 
             
              // values in the array. The **guard** check allows it to work with `_.map`.
         | 
| 335 403 | 
             
              _.last = function(array, n, guard) {
         | 
| 404 | 
            +
                if (array == null) return void 0;
         | 
| 336 405 | 
             
                if ((n != null) && !guard) {
         | 
| 337 406 | 
             
                  return slice.call(array, Math.max(array.length - n, 0));
         | 
| 338 407 | 
             
                } else {
         | 
| @@ -340,26 +409,37 @@ | |
| 340 409 | 
             
                }
         | 
| 341 410 | 
             
              };
         | 
| 342 411 |  | 
| 343 | 
            -
              // Returns everything but the first entry of the array. Aliased as `tail`.
         | 
| 344 | 
            -
              // Especially useful on the arguments object. Passing an ** | 
| 345 | 
            -
              // the rest  | 
| 412 | 
            +
              // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
         | 
| 413 | 
            +
              // Especially useful on the arguments object. Passing an **n** will return
         | 
| 414 | 
            +
              // the rest N values in the array. The **guard**
         | 
| 346 415 | 
             
              // check allows it to work with `_.map`.
         | 
| 347 | 
            -
              _.rest = _.tail = function(array,  | 
| 348 | 
            -
                return slice.call(array, ( | 
| 416 | 
            +
              _.rest = _.tail = _.drop = function(array, n, guard) {
         | 
| 417 | 
            +
                return slice.call(array, (n == null) || guard ? 1 : n);
         | 
| 349 418 | 
             
              };
         | 
| 350 419 |  | 
| 351 420 | 
             
              // Trim out all falsy values from an array.
         | 
| 352 421 | 
             
              _.compact = function(array) {
         | 
| 353 | 
            -
                return _.filter(array,  | 
| 422 | 
            +
                return _.filter(array, _.identity);
         | 
| 423 | 
            +
              };
         | 
| 424 | 
            +
             | 
| 425 | 
            +
              // Internal implementation of a recursive `flatten` function.
         | 
| 426 | 
            +
              var flatten = function(input, shallow, output) {
         | 
| 427 | 
            +
                if (shallow && _.every(input, _.isArray)) {
         | 
| 428 | 
            +
                  return concat.apply(output, input);
         | 
| 429 | 
            +
                }
         | 
| 430 | 
            +
                each(input, function(value) {
         | 
| 431 | 
            +
                  if (_.isArray(value) || _.isArguments(value)) {
         | 
| 432 | 
            +
                    shallow ? push.apply(output, value) : flatten(value, shallow, output);
         | 
| 433 | 
            +
                  } else {
         | 
| 434 | 
            +
                    output.push(value);
         | 
| 435 | 
            +
                  }
         | 
| 436 | 
            +
                });
         | 
| 437 | 
            +
                return output;
         | 
| 354 438 | 
             
              };
         | 
| 355 439 |  | 
| 356 440 | 
             
              // Return a completely flattened version of an array.
         | 
| 357 441 | 
             
              _.flatten = function(array, shallow) {
         | 
| 358 | 
            -
                return  | 
| 359 | 
            -
                  if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
         | 
| 360 | 
            -
                  memo[memo.length] = value;
         | 
| 361 | 
            -
                  return memo;
         | 
| 362 | 
            -
                }, []);
         | 
| 442 | 
            +
                return flatten(array, shallow, []);
         | 
| 363 443 | 
             
              };
         | 
| 364 444 |  | 
| 365 445 | 
             
              // Return a version of the array that does not contain the specified value(s).
         | 
| @@ -370,17 +450,22 @@ | |
| 370 450 | 
             
              // Produce a duplicate-free version of the array. If the array has already
         | 
| 371 451 | 
             
              // been sorted, you have the option of using a faster algorithm.
         | 
| 372 452 | 
             
              // Aliased as `unique`.
         | 
| 373 | 
            -
              _.uniq = _.unique = function(array, isSorted, iterator) {
         | 
| 374 | 
            -
                 | 
| 375 | 
            -
             | 
| 376 | 
            -
             | 
| 377 | 
            -
                   | 
| 378 | 
            -
             | 
| 379 | 
            -
             | 
| 453 | 
            +
              _.uniq = _.unique = function(array, isSorted, iterator, context) {
         | 
| 454 | 
            +
                if (_.isFunction(isSorted)) {
         | 
| 455 | 
            +
                  context = iterator;
         | 
| 456 | 
            +
                  iterator = isSorted;
         | 
| 457 | 
            +
                  isSorted = false;
         | 
| 458 | 
            +
                }
         | 
| 459 | 
            +
                var initial = iterator ? _.map(array, iterator, context) : array;
         | 
| 460 | 
            +
                var results = [];
         | 
| 461 | 
            +
                var seen = [];
         | 
| 462 | 
            +
                each(initial, function(value, index) {
         | 
| 463 | 
            +
                  if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
         | 
| 464 | 
            +
                    seen.push(value);
         | 
| 465 | 
            +
                    results.push(array[index]);
         | 
| 380 466 | 
             
                  }
         | 
| 381 | 
            -
             | 
| 382 | 
            -
                 | 
| 383 | 
            -
                return result;
         | 
| 467 | 
            +
                });
         | 
| 468 | 
            +
                return results;
         | 
| 384 469 | 
             
              };
         | 
| 385 470 |  | 
| 386 471 | 
             
              // Produce an array that contains the union: each distinct element from all of
         | 
| @@ -390,8 +475,8 @@ | |
| 390 475 | 
             
              };
         | 
| 391 476 |  | 
| 392 477 | 
             
              // Produce an array that contains every item shared between all the
         | 
| 393 | 
            -
              // passed-in arrays. | 
| 394 | 
            -
              _.intersection =  | 
| 478 | 
            +
              // passed-in arrays.
         | 
| 479 | 
            +
              _.intersection = function(array) {
         | 
| 395 480 | 
             
                var rest = slice.call(arguments, 1);
         | 
| 396 481 | 
             
                return _.filter(_.uniq(array), function(item) {
         | 
| 397 482 | 
             
                  return _.every(rest, function(other) {
         | 
| @@ -403,20 +488,47 @@ | |
| 403 488 | 
             
              // Take the difference between one array and a number of other arrays.
         | 
| 404 489 | 
             
              // Only the elements present in just the first array will remain.
         | 
| 405 490 | 
             
              _.difference = function(array) {
         | 
| 406 | 
            -
                var rest =  | 
| 407 | 
            -
                return _.filter(array, function(value){ return !_. | 
| 491 | 
            +
                var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
         | 
| 492 | 
            +
                return _.filter(array, function(value){ return !_.contains(rest, value); });
         | 
| 408 493 | 
             
              };
         | 
| 409 494 |  | 
| 410 495 | 
             
              // Zip together multiple lists into a single array -- elements that share
         | 
| 411 496 | 
             
              // an index go together.
         | 
| 412 497 | 
             
              _.zip = function() {
         | 
| 413 | 
            -
                 | 
| 414 | 
            -
             | 
| 498 | 
            +
                return _.unzip.apply(_, slice.call(arguments));
         | 
| 499 | 
            +
              };
         | 
| 500 | 
            +
             | 
| 501 | 
            +
              // The inverse operation to `_.zip`. If given an array of pairs it
         | 
| 502 | 
            +
              // returns an array of the paired elements split into two left and
         | 
| 503 | 
            +
              // right element arrays, if given an array of triples it returns a
         | 
| 504 | 
            +
              // three element array and so on. For example, `_.unzip` given
         | 
| 505 | 
            +
              // `[['a',1],['b',2],['c',3]]` returns the array
         | 
| 506 | 
            +
              // [['a','b','c'],[1,2,3]].
         | 
| 507 | 
            +
              _.unzip = function() {
         | 
| 508 | 
            +
                var length = _.max(_.pluck(arguments, "length").concat(0));
         | 
| 415 509 | 
             
                var results = new Array(length);
         | 
| 416 | 
            -
                for (var i = 0; i < length; i++)  | 
| 510 | 
            +
                for (var i = 0; i < length; i++) {
         | 
| 511 | 
            +
                  results[i] = _.pluck(arguments, '' + i);
         | 
| 512 | 
            +
                }
         | 
| 417 513 | 
             
                return results;
         | 
| 418 514 | 
             
              };
         | 
| 419 515 |  | 
| 516 | 
            +
              // Converts lists into objects. Pass either a single array of `[key, value]`
         | 
| 517 | 
            +
              // pairs, or two parallel arrays of the same length -- one of keys, and one of
         | 
| 518 | 
            +
              // the corresponding values.
         | 
| 519 | 
            +
              _.object = function(list, values) {
         | 
| 520 | 
            +
                if (list == null) return {};
         | 
| 521 | 
            +
                var result = {};
         | 
| 522 | 
            +
                for (var i = 0, l = list.length; i < l; i++) {
         | 
| 523 | 
            +
                  if (values) {
         | 
| 524 | 
            +
                    result[list[i]] = values[i];
         | 
| 525 | 
            +
                  } else {
         | 
| 526 | 
            +
                    result[list[i][0]] = list[i][1];
         | 
| 527 | 
            +
                  }
         | 
| 528 | 
            +
                }
         | 
| 529 | 
            +
                return result;
         | 
| 530 | 
            +
              };
         | 
| 531 | 
            +
             | 
| 420 532 | 
             
              // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
         | 
| 421 533 | 
             
              // we need this function. Return the position of the first occurrence of an
         | 
| 422 534 | 
             
              // item in an array, or -1 if the item is not included in the array.
         | 
| @@ -425,22 +537,29 @@ | |
| 425 537 | 
             
              // for **isSorted** to use binary search.
         | 
| 426 538 | 
             
              _.indexOf = function(array, item, isSorted) {
         | 
| 427 539 | 
             
                if (array == null) return -1;
         | 
| 428 | 
            -
                var i, l;
         | 
| 540 | 
            +
                var i = 0, l = array.length;
         | 
| 429 541 | 
             
                if (isSorted) {
         | 
| 430 | 
            -
                   | 
| 431 | 
            -
             | 
| 542 | 
            +
                  if (typeof isSorted == 'number') {
         | 
| 543 | 
            +
                    i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
         | 
| 544 | 
            +
                  } else {
         | 
| 545 | 
            +
                    i = _.sortedIndex(array, item);
         | 
| 546 | 
            +
                    return array[i] === item ? i : -1;
         | 
| 547 | 
            +
                  }
         | 
| 432 548 | 
             
                }
         | 
| 433 | 
            -
                if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
         | 
| 434 | 
            -
                for ( | 
| 549 | 
            +
                if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
         | 
| 550 | 
            +
                for (; i < l; i++) if (array[i] === item) return i;
         | 
| 435 551 | 
             
                return -1;
         | 
| 436 552 | 
             
              };
         | 
| 437 553 |  | 
| 438 554 | 
             
              // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
         | 
| 439 | 
            -
              _.lastIndexOf = function(array, item) {
         | 
| 555 | 
            +
              _.lastIndexOf = function(array, item, from) {
         | 
| 440 556 | 
             
                if (array == null) return -1;
         | 
| 441 | 
            -
                 | 
| 442 | 
            -
                 | 
| 443 | 
            -
             | 
| 557 | 
            +
                var hasIndex = from != null;
         | 
| 558 | 
            +
                if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
         | 
| 559 | 
            +
                  return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
         | 
| 560 | 
            +
                }
         | 
| 561 | 
            +
                var i = (hasIndex ? from : array.length);
         | 
| 562 | 
            +
                while (i--) if (array[i] === item) return i;
         | 
| 444 563 | 
             
                return -1;
         | 
| 445 564 | 
             
              };
         | 
| 446 565 |  | 
| @@ -473,29 +592,38 @@ | |
| 473 592 | 
             
              var ctor = function(){};
         | 
| 474 593 |  | 
| 475 594 | 
             
              // Create a function bound to a given object (assigning `this`, and arguments,
         | 
| 476 | 
            -
              // optionally).  | 
| 477 | 
            -
              //  | 
| 478 | 
            -
               | 
| 479 | 
            -
             | 
| 480 | 
            -
                 | 
| 481 | 
            -
                if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
         | 
| 595 | 
            +
              // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
         | 
| 596 | 
            +
              // available.
         | 
| 597 | 
            +
              _.bind = function(func, context) {
         | 
| 598 | 
            +
                var args, bound;
         | 
| 599 | 
            +
                if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
         | 
| 482 600 | 
             
                if (!_.isFunction(func)) throw new TypeError;
         | 
| 483 601 | 
             
                args = slice.call(arguments, 2);
         | 
| 484 602 | 
             
                return bound = function() {
         | 
| 485 603 | 
             
                  if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
         | 
| 486 604 | 
             
                  ctor.prototype = func.prototype;
         | 
| 487 605 | 
             
                  var self = new ctor;
         | 
| 606 | 
            +
                  ctor.prototype = null;
         | 
| 488 607 | 
             
                  var result = func.apply(self, args.concat(slice.call(arguments)));
         | 
| 489 608 | 
             
                  if (Object(result) === result) return result;
         | 
| 490 609 | 
             
                  return self;
         | 
| 491 610 | 
             
                };
         | 
| 492 611 | 
             
              };
         | 
| 493 612 |  | 
| 613 | 
            +
              // Partially apply a function by creating a version that has had some of its
         | 
| 614 | 
            +
              // arguments pre-filled, without changing its dynamic `this` context.
         | 
| 615 | 
            +
              _.partial = function(func) {
         | 
| 616 | 
            +
                var args = slice.call(arguments, 1);
         | 
| 617 | 
            +
                return function() {
         | 
| 618 | 
            +
                  return func.apply(this, args.concat(slice.call(arguments)));
         | 
| 619 | 
            +
                };
         | 
| 620 | 
            +
              };
         | 
| 621 | 
            +
             | 
| 494 622 | 
             
              // Bind all of an object's methods to that object. Useful for ensuring that
         | 
| 495 623 | 
             
              // all callbacks defined on an object belong to it.
         | 
| 496 624 | 
             
              _.bindAll = function(obj) {
         | 
| 497 625 | 
             
                var funcs = slice.call(arguments, 1);
         | 
| 498 | 
            -
                if (funcs.length  | 
| 626 | 
            +
                if (funcs.length === 0) throw new Error("bindAll must be passed function names");
         | 
| 499 627 | 
             
                each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
         | 
| 500 628 | 
             
                return obj;
         | 
| 501 629 | 
             
              };
         | 
| @@ -514,7 +642,7 @@ | |
| 514 642 | 
             
              // it with the arguments supplied.
         | 
| 515 643 | 
             
              _.delay = function(func, wait) {
         | 
| 516 644 | 
             
                var args = slice.call(arguments, 2);
         | 
| 517 | 
            -
                return setTimeout(function(){ return func.apply( | 
| 645 | 
            +
                return setTimeout(function(){ return func.apply(null, args); }, wait);
         | 
| 518 646 | 
             
              };
         | 
| 519 647 |  | 
| 520 648 | 
             
              // Defers a function, scheduling it to run after the current call stack has
         | 
| @@ -524,41 +652,56 @@ | |
| 524 652 | 
             
              };
         | 
| 525 653 |  | 
| 526 654 | 
             
              // Returns a function, that, when invoked, will only be triggered at most once
         | 
| 527 | 
            -
              // during a given window of time.
         | 
| 528 | 
            -
               | 
| 529 | 
            -
             | 
| 530 | 
            -
             | 
| 655 | 
            +
              // during a given window of time. Normally, the throttled function will run
         | 
| 656 | 
            +
              // as much as it can, without ever going more than once per `wait` duration;
         | 
| 657 | 
            +
              // but if you'd like to disable the execution on the leading edge, pass
         | 
| 658 | 
            +
              // `{leading: false}`. To disable execution on the trailing edge, ditto.
         | 
| 659 | 
            +
              _.throttle = function(func, wait, options) {
         | 
| 660 | 
            +
                var context, args, result;
         | 
| 661 | 
            +
                var timeout = null;
         | 
| 662 | 
            +
                var previous = 0;
         | 
| 663 | 
            +
                options || (options = {});
         | 
| 664 | 
            +
                var later = function() {
         | 
| 665 | 
            +
                  previous = new Date;
         | 
| 666 | 
            +
                  timeout = null;
         | 
| 667 | 
            +
                  result = func.apply(context, args);
         | 
| 668 | 
            +
                };
         | 
| 531 669 | 
             
                return function() {
         | 
| 532 | 
            -
                   | 
| 533 | 
            -
                   | 
| 670 | 
            +
                  var now = new Date;
         | 
| 671 | 
            +
                  if (!previous && options.leading === false) previous = now;
         | 
| 672 | 
            +
                  var remaining = wait - (now - previous);
         | 
| 673 | 
            +
                  context = this;
         | 
| 674 | 
            +
                  args = arguments;
         | 
| 675 | 
            +
                  if (remaining <= 0) {
         | 
| 676 | 
            +
                    clearTimeout(timeout);
         | 
| 534 677 | 
             
                    timeout = null;
         | 
| 535 | 
            -
                     | 
| 536 | 
            -
                     | 
| 537 | 
            -
                  } | 
| 538 | 
            -
             | 
| 539 | 
            -
                  if (throttling) {
         | 
| 540 | 
            -
                    more = true;
         | 
| 541 | 
            -
                  } else {
         | 
| 542 | 
            -
                    func.apply(context, args);
         | 
| 678 | 
            +
                    previous = now;
         | 
| 679 | 
            +
                    result = func.apply(context, args);
         | 
| 680 | 
            +
                  } else if (!timeout && options.trailing !== false) {
         | 
| 681 | 
            +
                    timeout = setTimeout(later, remaining);
         | 
| 543 682 | 
             
                  }
         | 
| 544 | 
            -
                   | 
| 545 | 
            -
                  throttling = true;
         | 
| 683 | 
            +
                  return result;
         | 
| 546 684 | 
             
                };
         | 
| 547 685 | 
             
              };
         | 
| 548 686 |  | 
| 549 687 | 
             
              // Returns a function, that, as long as it continues to be invoked, will not
         | 
| 550 688 | 
             
              // be triggered. The function will be called after it stops being called for
         | 
| 551 | 
            -
              // N milliseconds.
         | 
| 552 | 
            -
               | 
| 553 | 
            -
             | 
| 689 | 
            +
              // N milliseconds. If `immediate` is passed, trigger the function on the
         | 
| 690 | 
            +
              // leading edge, instead of the trailing.
         | 
| 691 | 
            +
              _.debounce = function(func, wait, immediate) {
         | 
| 692 | 
            +
                var result;
         | 
| 693 | 
            +
                var timeout = null;
         | 
| 554 694 | 
             
                return function() {
         | 
| 555 695 | 
             
                  var context = this, args = arguments;
         | 
| 556 696 | 
             
                  var later = function() {
         | 
| 557 697 | 
             
                    timeout = null;
         | 
| 558 | 
            -
                    func.apply(context, args);
         | 
| 698 | 
            +
                    if (!immediate) result = func.apply(context, args);
         | 
| 559 699 | 
             
                  };
         | 
| 700 | 
            +
                  var callNow = immediate && !timeout;
         | 
| 560 701 | 
             
                  clearTimeout(timeout);
         | 
| 561 702 | 
             
                  timeout = setTimeout(later, wait);
         | 
| 703 | 
            +
                  if (callNow) result = func.apply(context, args);
         | 
| 704 | 
            +
                  return result;
         | 
| 562 705 | 
             
                };
         | 
| 563 706 | 
             
              };
         | 
| 564 707 |  | 
| @@ -569,7 +712,9 @@ | |
| 569 712 | 
             
                return function() {
         | 
| 570 713 | 
             
                  if (ran) return memo;
         | 
| 571 714 | 
             
                  ran = true;
         | 
| 572 | 
            -
                   | 
| 715 | 
            +
                  memo = func.apply(this, arguments);
         | 
| 716 | 
            +
                  func = null;
         | 
| 717 | 
            +
                  return memo;
         | 
| 573 718 | 
             
                };
         | 
| 574 719 | 
             
              };
         | 
| 575 720 |  | 
| @@ -578,7 +723,8 @@ | |
| 578 723 | 
             
              // conditionally execute the original function.
         | 
| 579 724 | 
             
              _.wrap = function(func, wrapper) {
         | 
| 580 725 | 
             
                return function() {
         | 
| 581 | 
            -
                  var args = [func] | 
| 726 | 
            +
                  var args = [func];
         | 
| 727 | 
            +
                  push.apply(args, arguments);
         | 
| 582 728 | 
             
                  return wrapper.apply(this, args);
         | 
| 583 729 | 
             
                };
         | 
| 584 730 | 
             
              };
         | 
| @@ -598,9 +744,10 @@ | |
| 598 744 |  | 
| 599 745 | 
             
              // Returns a function that will only be executed after being called N times.
         | 
| 600 746 | 
             
              _.after = function(times, func) {
         | 
| 601 | 
            -
                if (times <= 0) return func();
         | 
| 602 747 | 
             
                return function() {
         | 
| 603 | 
            -
                  if (--times < 1) { | 
| 748 | 
            +
                  if (--times < 1) {
         | 
| 749 | 
            +
                    return func.apply(this, arguments);
         | 
| 750 | 
            +
                  }
         | 
| 604 751 | 
             
                };
         | 
| 605 752 | 
             
              };
         | 
| 606 753 |  | 
| @@ -612,13 +759,29 @@ | |
| 612 759 | 
             
              _.keys = nativeKeys || function(obj) {
         | 
| 613 760 | 
             
                if (obj !== Object(obj)) throw new TypeError('Invalid object');
         | 
| 614 761 | 
             
                var keys = [];
         | 
| 615 | 
            -
                for (var key in obj) if (_.has(obj, key)) keys | 
| 762 | 
            +
                for (var key in obj) if (_.has(obj, key)) keys.push(key);
         | 
| 616 763 | 
             
                return keys;
         | 
| 617 764 | 
             
              };
         | 
| 618 765 |  | 
| 619 766 | 
             
              // Retrieve the values of an object's properties.
         | 
| 620 767 | 
             
              _.values = function(obj) {
         | 
| 621 | 
            -
                 | 
| 768 | 
            +
                var values = [];
         | 
| 769 | 
            +
                for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
         | 
| 770 | 
            +
                return values;
         | 
| 771 | 
            +
              };
         | 
| 772 | 
            +
             | 
| 773 | 
            +
              // Convert an object into a list of `[key, value]` pairs.
         | 
| 774 | 
            +
              _.pairs = function(obj) {
         | 
| 775 | 
            +
                var pairs = [];
         | 
| 776 | 
            +
                for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
         | 
| 777 | 
            +
                return pairs;
         | 
| 778 | 
            +
              };
         | 
| 779 | 
            +
             | 
| 780 | 
            +
              // Invert the keys and values of an object. The values must be serializable.
         | 
| 781 | 
            +
              _.invert = function(obj) {
         | 
| 782 | 
            +
                var result = {};
         | 
| 783 | 
            +
                for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
         | 
| 784 | 
            +
                return result;
         | 
| 622 785 | 
             
              };
         | 
| 623 786 |  | 
| 624 787 | 
             
              // Return a sorted list of the function names available on the object.
         | 
| @@ -634,18 +797,42 @@ | |
| 634 797 | 
             
              // Extend a given object with all the properties in passed-in object(s).
         | 
| 635 798 | 
             
              _.extend = function(obj) {
         | 
| 636 799 | 
             
                each(slice.call(arguments, 1), function(source) {
         | 
| 637 | 
            -
                   | 
| 638 | 
            -
                     | 
| 800 | 
            +
                  if (source) {
         | 
| 801 | 
            +
                    for (var prop in source) {
         | 
| 802 | 
            +
                      obj[prop] = source[prop];
         | 
| 803 | 
            +
                    }
         | 
| 639 804 | 
             
                  }
         | 
| 640 805 | 
             
                });
         | 
| 641 806 | 
             
                return obj;
         | 
| 642 807 | 
             
              };
         | 
| 643 808 |  | 
| 809 | 
            +
              // Return a copy of the object only containing the whitelisted properties.
         | 
| 810 | 
            +
              _.pick = function(obj) {
         | 
| 811 | 
            +
                var copy = {};
         | 
| 812 | 
            +
                var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
         | 
| 813 | 
            +
                each(keys, function(key) {
         | 
| 814 | 
            +
                  if (key in obj) copy[key] = obj[key];
         | 
| 815 | 
            +
                });
         | 
| 816 | 
            +
                return copy;
         | 
| 817 | 
            +
              };
         | 
| 818 | 
            +
             | 
| 819 | 
            +
               // Return a copy of the object without the blacklisted properties.
         | 
| 820 | 
            +
              _.omit = function(obj) {
         | 
| 821 | 
            +
                var copy = {};
         | 
| 822 | 
            +
                var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
         | 
| 823 | 
            +
                for (var key in obj) {
         | 
| 824 | 
            +
                  if (!_.contains(keys, key)) copy[key] = obj[key];
         | 
| 825 | 
            +
                }
         | 
| 826 | 
            +
                return copy;
         | 
| 827 | 
            +
              };
         | 
| 828 | 
            +
             | 
| 644 829 | 
             
              // Fill in a given object with default properties.
         | 
| 645 830 | 
             
              _.defaults = function(obj) {
         | 
| 646 831 | 
             
                each(slice.call(arguments, 1), function(source) {
         | 
| 647 | 
            -
                   | 
| 648 | 
            -
                     | 
| 832 | 
            +
                  if (source) {
         | 
| 833 | 
            +
                    for (var prop in source) {
         | 
| 834 | 
            +
                      if (obj[prop] === void 0) obj[prop] = source[prop];
         | 
| 835 | 
            +
                    }
         | 
| 649 836 | 
             
                  }
         | 
| 650 837 | 
             
                });
         | 
| 651 838 | 
             
                return obj;
         | 
| @@ -665,19 +852,16 @@ | |
| 665 852 | 
             
                return obj;
         | 
| 666 853 | 
             
              };
         | 
| 667 854 |  | 
| 668 | 
            -
              // Internal recursive comparison function | 
| 669 | 
            -
               | 
| 855 | 
            +
              // Internal recursive comparison function for `isEqual`.
         | 
| 856 | 
            +
              var eq = function(a, b, aStack, bStack) {
         | 
| 670 857 | 
             
                // Identical objects are equal. `0 === -0`, but they aren't identical.
         | 
| 671 | 
            -
                // See the Harmony `egal` proposal | 
| 858 | 
            +
                // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
         | 
| 672 859 | 
             
                if (a === b) return a !== 0 || 1 / a == 1 / b;
         | 
| 673 860 | 
             
                // A strict comparison is necessary because `null == undefined`.
         | 
| 674 861 | 
             
                if (a == null || b == null) return a === b;
         | 
| 675 862 | 
             
                // Unwrap any wrapped objects.
         | 
| 676 | 
            -
                if (a | 
| 677 | 
            -
                if (b | 
| 678 | 
            -
                // Invoke a custom `isEqual` method if one is provided.
         | 
| 679 | 
            -
                if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
         | 
| 680 | 
            -
                if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
         | 
| 863 | 
            +
                if (a instanceof _) a = a._wrapped;
         | 
| 864 | 
            +
                if (b instanceof _) b = b._wrapped;
         | 
| 681 865 | 
             
                // Compare `[[Class]]` names.
         | 
| 682 866 | 
             
                var className = toString.call(a);
         | 
| 683 867 | 
             
                if (className != toString.call(b)) return false;
         | 
| @@ -707,14 +891,22 @@ | |
| 707 891 | 
             
                if (typeof a != 'object' || typeof b != 'object') return false;
         | 
| 708 892 | 
             
                // Assume equality for cyclic structures. The algorithm for detecting cyclic
         | 
| 709 893 | 
             
                // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
         | 
| 710 | 
            -
                var length =  | 
| 894 | 
            +
                var length = aStack.length;
         | 
| 711 895 | 
             
                while (length--) {
         | 
| 712 896 | 
             
                  // Linear search. Performance is inversely proportional to the number of
         | 
| 713 897 | 
             
                  // unique nested structures.
         | 
| 714 | 
            -
                  if ( | 
| 898 | 
            +
                  if (aStack[length] == a) return bStack[length] == b;
         | 
| 899 | 
            +
                }
         | 
| 900 | 
            +
                // Objects with different constructors are not equivalent, but `Object`s
         | 
| 901 | 
            +
                // from different frames are.
         | 
| 902 | 
            +
                var aCtor = a.constructor, bCtor = b.constructor;
         | 
| 903 | 
            +
                if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
         | 
| 904 | 
            +
                                         _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
         | 
| 905 | 
            +
                  return false;
         | 
| 715 906 | 
             
                }
         | 
| 716 907 | 
             
                // Add the first object to the stack of traversed objects.
         | 
| 717 | 
            -
                 | 
| 908 | 
            +
                aStack.push(a);
         | 
| 909 | 
            +
                bStack.push(b);
         | 
| 718 910 | 
             
                var size = 0, result = true;
         | 
| 719 911 | 
             
                // Recursively compare objects and arrays.
         | 
| 720 912 | 
             
                if (className == '[object Array]') {
         | 
| @@ -724,20 +916,17 @@ | |
| 724 916 | 
             
                  if (result) {
         | 
| 725 917 | 
             
                    // Deep compare the contents, ignoring non-numeric properties.
         | 
| 726 918 | 
             
                    while (size--) {
         | 
| 727 | 
            -
                       | 
| 728 | 
            -
                      if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
         | 
| 919 | 
            +
                      if (!(result = eq(a[size], b[size], aStack, bStack))) break;
         | 
| 729 920 | 
             
                    }
         | 
| 730 921 | 
             
                  }
         | 
| 731 922 | 
             
                } else {
         | 
| 732 | 
            -
                  // Objects with different constructors are not equivalent.
         | 
| 733 | 
            -
                  if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
         | 
| 734 923 | 
             
                  // Deep compare objects.
         | 
| 735 924 | 
             
                  for (var key in a) {
         | 
| 736 925 | 
             
                    if (_.has(a, key)) {
         | 
| 737 926 | 
             
                      // Count the expected number of properties.
         | 
| 738 927 | 
             
                      size++;
         | 
| 739 928 | 
             
                      // Deep compare each member.
         | 
| 740 | 
            -
                      if (!(result = _.has(b, key) && eq(a[key], b[key],  | 
| 929 | 
            +
                      if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
         | 
| 741 930 | 
             
                    }
         | 
| 742 931 | 
             
                  }
         | 
| 743 932 | 
             
                  // Ensure that both objects contain the same number of properties.
         | 
| @@ -749,18 +938,20 @@ | |
| 749 938 | 
             
                  }
         | 
| 750 939 | 
             
                }
         | 
| 751 940 | 
             
                // Remove the first object from the stack of traversed objects.
         | 
| 752 | 
            -
                 | 
| 941 | 
            +
                aStack.pop();
         | 
| 942 | 
            +
                bStack.pop();
         | 
| 753 943 | 
             
                return result;
         | 
| 754 | 
            -
              }
         | 
| 944 | 
            +
              };
         | 
| 755 945 |  | 
| 756 946 | 
             
              // Perform a deep comparison to check if two objects are equal.
         | 
| 757 947 | 
             
              _.isEqual = function(a, b) {
         | 
| 758 | 
            -
                return eq(a, b, []);
         | 
| 948 | 
            +
                return eq(a, b, [], []);
         | 
| 759 949 | 
             
              };
         | 
| 760 950 |  | 
| 761 951 | 
             
              // Is a given array, string, or object empty?
         | 
| 762 952 | 
             
              // An "empty" object has no enumerable own-properties.
         | 
| 763 953 | 
             
              _.isEmpty = function(obj) {
         | 
| 954 | 
            +
                if (obj == null) return true;
         | 
| 764 955 | 
             
                if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
         | 
| 765 956 | 
             
                for (var key in obj) if (_.has(obj, key)) return false;
         | 
| 766 957 | 
             
                return true;
         | 
| @@ -768,7 +959,7 @@ | |
| 768 959 |  | 
| 769 960 | 
             
              // Is a given value a DOM element?
         | 
| 770 961 | 
             
              _.isElement = function(obj) {
         | 
| 771 | 
            -
                return !!(obj && obj.nodeType  | 
| 962 | 
            +
                return !!(obj && obj.nodeType === 1);
         | 
| 772 963 | 
             
              };
         | 
| 773 964 |  | 
| 774 965 | 
             
              // Is a given value an array?
         | 
| @@ -782,35 +973,36 @@ | |
| 782 973 | 
             
                return obj === Object(obj);
         | 
| 783 974 | 
             
              };
         | 
| 784 975 |  | 
| 785 | 
            -
              //  | 
| 786 | 
            -
               | 
| 787 | 
            -
                 | 
| 788 | 
            -
             | 
| 976 | 
            +
              // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
         | 
| 977 | 
            +
              each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
         | 
| 978 | 
            +
                _['is' + name] = function(obj) {
         | 
| 979 | 
            +
                  return toString.call(obj) == '[object ' + name + ']';
         | 
| 980 | 
            +
                };
         | 
| 981 | 
            +
              });
         | 
| 982 | 
            +
             | 
| 983 | 
            +
              // Define a fallback version of the method in browsers (ahem, IE), where
         | 
| 984 | 
            +
              // there isn't any inspectable "Arguments" type.
         | 
| 789 985 | 
             
              if (!_.isArguments(arguments)) {
         | 
| 790 986 | 
             
                _.isArguments = function(obj) {
         | 
| 791 987 | 
             
                  return !!(obj && _.has(obj, 'callee'));
         | 
| 792 988 | 
             
                };
         | 
| 793 989 | 
             
              }
         | 
| 794 990 |  | 
| 795 | 
            -
              //  | 
| 796 | 
            -
               | 
| 797 | 
            -
                 | 
| 798 | 
            -
             | 
| 799 | 
            -
             | 
| 800 | 
            -
               | 
| 801 | 
            -
              _.isString = function(obj) {
         | 
| 802 | 
            -
                return toString.call(obj) == '[object String]';
         | 
| 803 | 
            -
              };
         | 
| 991 | 
            +
              // Optimize `isFunction` if appropriate.
         | 
| 992 | 
            +
              if (typeof (/./) !== 'function') {
         | 
| 993 | 
            +
                _.isFunction = function(obj) {
         | 
| 994 | 
            +
                  return typeof obj === 'function';
         | 
| 995 | 
            +
                };
         | 
| 996 | 
            +
              }
         | 
| 804 997 |  | 
| 805 | 
            -
              // Is a given  | 
| 806 | 
            -
              _. | 
| 807 | 
            -
                return  | 
| 998 | 
            +
              // Is a given object a finite number?
         | 
| 999 | 
            +
              _.isFinite = function(obj) {
         | 
| 1000 | 
            +
                return isFinite(obj) && !isNaN(parseFloat(obj));
         | 
| 808 1001 | 
             
              };
         | 
| 809 1002 |  | 
| 810 | 
            -
              // Is the given value `NaN`?
         | 
| 1003 | 
            +
              // Is the given value `NaN`? (NaN is the only number which does not equal itself).
         | 
| 811 1004 | 
             
              _.isNaN = function(obj) {
         | 
| 812 | 
            -
                 | 
| 813 | 
            -
                return obj !== obj;
         | 
| 1005 | 
            +
                return _.isNumber(obj) && obj != +obj;
         | 
| 814 1006 | 
             
              };
         | 
| 815 1007 |  | 
| 816 1008 | 
             
              // Is a given value a boolean?
         | 
| @@ -818,16 +1010,6 @@ | |
| 818 1010 | 
             
                return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
         | 
| 819 1011 | 
             
              };
         | 
| 820 1012 |  | 
| 821 | 
            -
              // Is a given value a date?
         | 
| 822 | 
            -
              _.isDate = function(obj) {
         | 
| 823 | 
            -
                return toString.call(obj) == '[object Date]';
         | 
| 824 | 
            -
              };
         | 
| 825 | 
            -
             | 
| 826 | 
            -
              // Is the given value a regular expression?
         | 
| 827 | 
            -
              _.isRegExp = function(obj) {
         | 
| 828 | 
            -
                return toString.call(obj) == '[object RegExp]';
         | 
| 829 | 
            -
              };
         | 
| 830 | 
            -
             | 
| 831 1013 | 
             
              // Is a given value equal to null?
         | 
| 832 1014 | 
             
              _.isNull = function(obj) {
         | 
| 833 1015 | 
             
                return obj === null;
         | 
| @@ -838,7 +1020,8 @@ | |
| 838 1020 | 
             
                return obj === void 0;
         | 
| 839 1021 | 
             
              };
         | 
| 840 1022 |  | 
| 841 | 
            -
              //  | 
| 1023 | 
            +
              // Shortcut function for checking if an object has a given property directly
         | 
| 1024 | 
            +
              // on itself (in other words, not on a prototype).
         | 
| 842 1025 | 
             
              _.has = function(obj, key) {
         | 
| 843 1026 | 
             
                return hasOwnProperty.call(obj, key);
         | 
| 844 1027 | 
             
              };
         | 
| @@ -859,20 +1042,67 @@ | |
| 859 1042 | 
             
              };
         | 
| 860 1043 |  | 
| 861 1044 | 
             
              // Run a function **n** times.
         | 
| 862 | 
            -
              _.times = function | 
| 863 | 
            -
                 | 
| 1045 | 
            +
              _.times = function(n, iterator, context) {
         | 
| 1046 | 
            +
                var accum = Array(Math.max(0, n));
         | 
| 1047 | 
            +
                for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
         | 
| 1048 | 
            +
                return accum;
         | 
| 1049 | 
            +
              };
         | 
| 1050 | 
            +
             | 
| 1051 | 
            +
              // Return a random integer between min and max (inclusive).
         | 
| 1052 | 
            +
              _.random = function(min, max) {
         | 
| 1053 | 
            +
                if (max == null) {
         | 
| 1054 | 
            +
                  max = min;
         | 
| 1055 | 
            +
                  min = 0;
         | 
| 1056 | 
            +
                }
         | 
| 1057 | 
            +
                return min + Math.floor(Math.random() * (max - min + 1));
         | 
| 1058 | 
            +
              };
         | 
| 1059 | 
            +
             | 
| 1060 | 
            +
              // List of HTML entities for escaping.
         | 
| 1061 | 
            +
              var entityMap = {
         | 
| 1062 | 
            +
                escape: {
         | 
| 1063 | 
            +
                  '&': '&',
         | 
| 1064 | 
            +
                  '<': '<',
         | 
| 1065 | 
            +
                  '>': '>',
         | 
| 1066 | 
            +
                  '"': '"',
         | 
| 1067 | 
            +
                  "'": ''',
         | 
| 1068 | 
            +
                  '/': '/'
         | 
| 1069 | 
            +
                }
         | 
| 864 1070 | 
             
              };
         | 
| 1071 | 
            +
              entityMap.unescape = _.invert(entityMap.escape);
         | 
| 1072 | 
            +
             | 
| 1073 | 
            +
              // Regexes containing the keys and values listed immediately above.
         | 
| 1074 | 
            +
              var entityRegexes = {
         | 
| 1075 | 
            +
                escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
         | 
| 1076 | 
            +
                unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
         | 
| 1077 | 
            +
              };
         | 
| 1078 | 
            +
             | 
| 1079 | 
            +
              // Functions for escaping and unescaping strings to/from HTML interpolation.
         | 
| 1080 | 
            +
              _.each(['escape', 'unescape'], function(method) {
         | 
| 1081 | 
            +
                _[method] = function(string) {
         | 
| 1082 | 
            +
                  if (string == null) return '';
         | 
| 1083 | 
            +
                  return ('' + string).replace(entityRegexes[method], function(match) {
         | 
| 1084 | 
            +
                    return entityMap[method][match];
         | 
| 1085 | 
            +
                  });
         | 
| 1086 | 
            +
                };
         | 
| 1087 | 
            +
              });
         | 
| 865 1088 |  | 
| 866 | 
            -
              //  | 
| 867 | 
            -
               | 
| 868 | 
            -
             | 
| 1089 | 
            +
              // If the value of the named `property` is a function then invoke it with the
         | 
| 1090 | 
            +
              // `object` as context; otherwise, return it.
         | 
| 1091 | 
            +
              _.result = function(object, property) {
         | 
| 1092 | 
            +
                if (object == null) return void 0;
         | 
| 1093 | 
            +
                var value = object[property];
         | 
| 1094 | 
            +
                return _.isFunction(value) ? value.call(object) : value;
         | 
| 869 1095 | 
             
              };
         | 
| 870 1096 |  | 
| 871 | 
            -
              // Add your own custom functions to the Underscore object | 
| 872 | 
            -
              // they're correctly added to the OOP wrapper as well.
         | 
| 1097 | 
            +
              // Add your own custom functions to the Underscore object.
         | 
| 873 1098 | 
             
              _.mixin = function(obj) {
         | 
| 874 1099 | 
             
                each(_.functions(obj), function(name){
         | 
| 875 | 
            -
                   | 
| 1100 | 
            +
                  var func = _[name] = obj[name];
         | 
| 1101 | 
            +
                  _.prototype[name] = function() {
         | 
| 1102 | 
            +
                    var args = [this._wrapped];
         | 
| 1103 | 
            +
                    push.apply(args, arguments);
         | 
| 1104 | 
            +
                    return result.call(this, func.apply(_, args));
         | 
| 1105 | 
            +
                  };
         | 
| 876 1106 | 
             
                });
         | 
| 877 1107 | 
             
              };
         | 
| 878 1108 |  | 
| @@ -880,7 +1110,7 @@ | |
| 880 1110 | 
             
              // Useful for temporary DOM ids.
         | 
| 881 1111 | 
             
              var idCounter = 0;
         | 
| 882 1112 | 
             
              _.uniqueId = function(prefix) {
         | 
| 883 | 
            -
                var id = idCounter | 
| 1113 | 
            +
                var id = ++idCounter + '';
         | 
| 884 1114 | 
             
                return prefix ? prefix + id : id;
         | 
| 885 1115 | 
             
              };
         | 
| 886 1116 |  | 
| @@ -895,41 +1125,80 @@ | |
| 895 1125 | 
             
              // When customizing `templateSettings`, if you don't want to define an
         | 
| 896 1126 | 
             
              // interpolation, evaluation or escaping regex, we need one that is
         | 
| 897 1127 | 
             
              // guaranteed not to match.
         | 
| 898 | 
            -
              var noMatch =  | 
| 1128 | 
            +
              var noMatch = /(.)^/;
         | 
| 899 1129 |  | 
| 900 | 
            -
              //  | 
| 901 | 
            -
              //  | 
| 902 | 
            -
              var  | 
| 903 | 
            -
                 | 
| 1130 | 
            +
              // Certain characters need to be escaped so that they can be put into a
         | 
| 1131 | 
            +
              // string literal.
         | 
| 1132 | 
            +
              var escapes = {
         | 
| 1133 | 
            +
                "'":      "'",
         | 
| 1134 | 
            +
                '\\':     '\\',
         | 
| 1135 | 
            +
                '\r':     'r',
         | 
| 1136 | 
            +
                '\n':     'n',
         | 
| 1137 | 
            +
                '\t':     't',
         | 
| 1138 | 
            +
                '\u2028': 'u2028',
         | 
| 1139 | 
            +
                '\u2029': 'u2029'
         | 
| 904 1140 | 
             
              };
         | 
| 905 1141 |  | 
| 1142 | 
            +
              var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
         | 
| 1143 | 
            +
             | 
| 906 1144 | 
             
              // JavaScript micro-templating, similar to John Resig's implementation.
         | 
| 907 1145 | 
             
              // Underscore templating handles arbitrary delimiters, preserves whitespace,
         | 
| 908 1146 | 
             
              // and correctly escapes quotes within interpolated code.
         | 
| 909 | 
            -
              _.template = function( | 
| 910 | 
            -
                var  | 
| 911 | 
            -
                 | 
| 912 | 
            -
             | 
| 913 | 
            -
             | 
| 914 | 
            -
             | 
| 915 | 
            -
             | 
| 916 | 
            -
             | 
| 917 | 
            -
             | 
| 918 | 
            -
             | 
| 919 | 
            -
             | 
| 920 | 
            -
             | 
| 921 | 
            -
             | 
| 922 | 
            -
             | 
| 923 | 
            -
             | 
| 924 | 
            -
             | 
| 925 | 
            -
             | 
| 926 | 
            -
             | 
| 927 | 
            -
             | 
| 928 | 
            -
             | 
| 929 | 
            -
             | 
| 930 | 
            -
             | 
| 931 | 
            -
             | 
| 1147 | 
            +
              _.template = function(text, data, settings) {
         | 
| 1148 | 
            +
                var render;
         | 
| 1149 | 
            +
                settings = _.defaults({}, settings, _.templateSettings);
         | 
| 1150 | 
            +
             | 
| 1151 | 
            +
                // Combine delimiters into one regular expression via alternation.
         | 
| 1152 | 
            +
                var matcher = new RegExp([
         | 
| 1153 | 
            +
                  (settings.escape || noMatch).source,
         | 
| 1154 | 
            +
                  (settings.interpolate || noMatch).source,
         | 
| 1155 | 
            +
                  (settings.evaluate || noMatch).source
         | 
| 1156 | 
            +
                ].join('|') + '|$', 'g');
         | 
| 1157 | 
            +
             | 
| 1158 | 
            +
                // Compile the template source, escaping string literals appropriately.
         | 
| 1159 | 
            +
                var index = 0;
         | 
| 1160 | 
            +
                var source = "__p+='";
         | 
| 1161 | 
            +
                text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
         | 
| 1162 | 
            +
                  source += text.slice(index, offset)
         | 
| 1163 | 
            +
                    .replace(escaper, function(match) { return '\\' + escapes[match]; });
         | 
| 1164 | 
            +
             | 
| 1165 | 
            +
                  if (escape) {
         | 
| 1166 | 
            +
                    source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
         | 
| 1167 | 
            +
                  }
         | 
| 1168 | 
            +
                  if (interpolate) {
         | 
| 1169 | 
            +
                    source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
         | 
| 1170 | 
            +
                  }
         | 
| 1171 | 
            +
                  if (evaluate) {
         | 
| 1172 | 
            +
                    source += "';\n" + evaluate + "\n__p+='";
         | 
| 1173 | 
            +
                  }
         | 
| 1174 | 
            +
                  index = offset + match.length;
         | 
| 1175 | 
            +
                  return match;
         | 
| 1176 | 
            +
                });
         | 
| 1177 | 
            +
                source += "';\n";
         | 
| 1178 | 
            +
             | 
| 1179 | 
            +
                // If a variable is not specified, place data values in local scope.
         | 
| 1180 | 
            +
                if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
         | 
| 1181 | 
            +
             | 
| 1182 | 
            +
                source = "var __t,__p='',__j=Array.prototype.join," +
         | 
| 1183 | 
            +
                  "print=function(){__p+=__j.call(arguments,'');};\n" +
         | 
| 1184 | 
            +
                  source + "return __p;\n";
         | 
| 1185 | 
            +
             | 
| 1186 | 
            +
                try {
         | 
| 1187 | 
            +
                  render = new Function(settings.variable || 'obj', '_', source);
         | 
| 1188 | 
            +
                } catch (e) {
         | 
| 1189 | 
            +
                  e.source = source;
         | 
| 1190 | 
            +
                  throw e;
         | 
| 1191 | 
            +
                }
         | 
| 1192 | 
            +
             | 
| 1193 | 
            +
                if (data) return render(data, _);
         | 
| 1194 | 
            +
                var template = function(data) {
         | 
| 1195 | 
            +
                  return render.call(this, data, _);
         | 
| 932 1196 | 
             
                };
         | 
| 1197 | 
            +
             | 
| 1198 | 
            +
                // Provide the compiled function source as a convenience for precompilation.
         | 
| 1199 | 
            +
                template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
         | 
| 1200 | 
            +
             | 
| 1201 | 
            +
                return template;
         | 
| 933 1202 | 
             
              };
         | 
| 934 1203 |  | 
| 935 1204 | 
             
              // Add a "chain" function, which will delegate to the wrapper.
         | 
| @@ -937,29 +1206,15 @@ | |
| 937 1206 | 
             
                return _(obj).chain();
         | 
| 938 1207 | 
             
              };
         | 
| 939 1208 |  | 
| 940 | 
            -
              //  | 
| 1209 | 
            +
              // OOP
         | 
| 941 1210 | 
             
              // ---------------
         | 
| 942 | 
            -
             | 
| 943 1211 | 
             
              // If Underscore is called as a function, it returns a wrapped object that
         | 
| 944 1212 | 
             
              // can be used OO-style. This wrapper holds altered versions of all the
         | 
| 945 1213 | 
             
              // underscore functions. Wrapped objects may be chained.
         | 
| 946 | 
            -
              var wrapper = function(obj) { this._wrapped = obj; };
         | 
| 947 | 
            -
             | 
| 948 | 
            -
              // Expose `wrapper.prototype` as `_.prototype`
         | 
| 949 | 
            -
              _.prototype = wrapper.prototype;
         | 
| 950 1214 |  | 
| 951 1215 | 
             
              // Helper function to continue chaining intermediate results.
         | 
| 952 | 
            -
              var result = function(obj | 
| 953 | 
            -
                return  | 
| 954 | 
            -
              };
         | 
| 955 | 
            -
             | 
| 956 | 
            -
              // A method to easily add functions to the OOP wrapper.
         | 
| 957 | 
            -
              var addToWrapper = function(name, func) {
         | 
| 958 | 
            -
                wrapper.prototype[name] = function() {
         | 
| 959 | 
            -
                  var args = slice.call(arguments);
         | 
| 960 | 
            -
                  unshift.call(args, this._wrapped);
         | 
| 961 | 
            -
                  return result(func.apply(_, args), this._chain);
         | 
| 962 | 
            -
                };
         | 
| 1216 | 
            +
              var result = function(obj) {
         | 
| 1217 | 
            +
                return this._chain ? _(obj).chain() : obj;
         | 
| 963 1218 | 
             
              };
         | 
| 964 1219 |  | 
| 965 1220 | 
             
              // Add all of the Underscore functions to the wrapper object.
         | 
| @@ -968,32 +1223,35 @@ | |
| 968 1223 | 
             
              // Add all mutator Array functions to the wrapper.
         | 
| 969 1224 | 
             
              each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
         | 
| 970 1225 | 
             
                var method = ArrayProto[name];
         | 
| 971 | 
            -
                 | 
| 972 | 
            -
                  var  | 
| 973 | 
            -
                  method.apply( | 
| 974 | 
            -
                   | 
| 975 | 
            -
                   | 
| 976 | 
            -
                  return result(wrapped, this._chain);
         | 
| 1226 | 
            +
                _.prototype[name] = function() {
         | 
| 1227 | 
            +
                  var obj = this._wrapped;
         | 
| 1228 | 
            +
                  method.apply(obj, arguments);
         | 
| 1229 | 
            +
                  if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
         | 
| 1230 | 
            +
                  return result.call(this, obj);
         | 
| 977 1231 | 
             
                };
         | 
| 978 1232 | 
             
              });
         | 
| 979 1233 |  | 
| 980 1234 | 
             
              // Add all accessor Array functions to the wrapper.
         | 
| 981 1235 | 
             
              each(['concat', 'join', 'slice'], function(name) {
         | 
| 982 1236 | 
             
                var method = ArrayProto[name];
         | 
| 983 | 
            -
                 | 
| 984 | 
            -
                  return result(method.apply(this._wrapped, arguments) | 
| 1237 | 
            +
                _.prototype[name] = function() {
         | 
| 1238 | 
            +
                  return result.call(this, method.apply(this._wrapped, arguments));
         | 
| 985 1239 | 
             
                };
         | 
| 986 1240 | 
             
              });
         | 
| 987 1241 |  | 
| 988 | 
            -
               | 
| 989 | 
            -
              wrapper.prototype.chain = function() {
         | 
| 990 | 
            -
                this._chain = true;
         | 
| 991 | 
            -
                return this;
         | 
| 992 | 
            -
              };
         | 
| 1242 | 
            +
              _.extend(_.prototype, {
         | 
| 993 1243 |  | 
| 994 | 
            -
             | 
| 995 | 
            -
             | 
| 996 | 
            -
             | 
| 997 | 
            -
             | 
| 1244 | 
            +
                // Start chaining a wrapped Underscore object.
         | 
| 1245 | 
            +
                chain: function() {
         | 
| 1246 | 
            +
                  this._chain = true;
         | 
| 1247 | 
            +
                  return this;
         | 
| 1248 | 
            +
                },
         | 
| 1249 | 
            +
             | 
| 1250 | 
            +
                // Extracts the result from a wrapped and chained object.
         | 
| 1251 | 
            +
                value: function() {
         | 
| 1252 | 
            +
                  return this._wrapped;
         | 
| 1253 | 
            +
                }
         | 
| 1254 | 
            +
             | 
| 1255 | 
            +
              });
         | 
| 998 1256 |  | 
| 999 1257 | 
             
            }).call(this);
         |