From 8c346141dc9687c5952991195eefe1988cf92124 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Mon, 14 Nov 2011 15:28:19 -0500 Subject: [PATCH] Underscore.js 1.2.2 --- docs/underscore.html | 165 ++++++++++++++++++++++++------------------- index.html | 29 +++++++- package.json | 2 +- underscore-min.js | 48 ++++++------- underscore.js | 4 +- 5 files changed, 146 insertions(+), 102 deletions(-) diff --git a/docs/underscore.html b/docs/underscore.html index 6e44f0cf8..d2dafbd59 100644 --- a/docs/underscore.html +++ b/docs/underscore.html @@ -1,4 +1,4 @@ - underscore.js

underscore.js

Underscore.js 1.2.1
+      underscore.js           
return_;});}else{returnargs[0];};};}).replace(c.evaluate||null,function(match,code){return"');"+code.replace(/\\'/g,"'") - .replace(/[\r\n\t]/g,' ')+"__p.push('"; + .replace(/[\r\n\t]/g,' ')+";__p.push('";}).replace(/\r/g,'\\r').replace(/\n/g,'\\n').replace(/\t/g,'\\t')+"');}return __p.join('');"; - varfunc=newFunction('obj',tmpl); - returndata?func(data):func; - };

underscore.js

Underscore.js 1.2.2
 (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
 Underscore is freely distributable under the MIT license.
 Portions of Underscore are inspired or borrowed from Prototype,
@@ -32,7 +32,7 @@ CommonJS, add _ to the global object.

Exported as a string, for Closure Compiler "advanced" mode.

    root['_'] = _;
-  }

Current version.

  _.VERSION = '1.2.1';

Collection Functions

The cornerstone, an each implementation, aka forEach. + }

Current version.

  _.VERSION = '1.2.2';

Collection Functions

The cornerstone, an each implementation, aka forEach. Handles objects with the built-in forEach, arrays, and raw objects. Delegates to ECMAScript 5's native forEach if available.

  var each = _.each = _.forEach = function(obj, iterator, context) {
     if (obj == null) return;
@@ -129,7 +129,7 @@ Aliased as any.

if (obj == null) return result; if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); each(obj, function(value, index, list) { - if (result |= iterator.call(context, value, index, list)) return breaker; + if (result || (result = iterator.call(context, value, index, list))) return breaker; }); return !!result; };

Determine if a given value is included in the array or object using ===. @@ -138,7 +138,7 @@ Aliased as contains.

if (obj == null) return found; if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; found = any(obj, function(value) { - if (value === target) return true; + return value === target; }); return found; };

Invoke a method (with arguments) on every item in a collection.

  _.invoke = function(obj, method) {
@@ -225,7 +225,11 @@ the array, excluding the last N. The guard check allows it to w
     return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
   };

Get the last element of an array. Passing n will return the last N values in the array. The guard check allows it to work with _.map.

  _.last = function(array, n, guard) {
-    return (n != null) && !guard ? slice.call(array, array.length - n) : array[array.length - 1];
+    if ((n != null) && !guard) {
+      return slice.call(array, Math.max(array.length - n, 0));
+    } else {
+      return array[array.length - 1];
+    }
   };

Returns everything but the first entry of the array. Aliased as tail. Especially useful on the arguments object. Passing an index will return the rest of the values in the array from that index onward. The guard @@ -353,18 +357,22 @@ cleared.

return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); };

Returns a function, that, when invoked, will only be triggered at most once during a given window of time.

  _.throttle = function(func, wait) {
-    var timeout, context, args, throttling, finishThrottle;
-    finishThrottle = _.debounce(function(){ throttling = false; }, wait);
+    var context, args, timeout, throttling, more;
+    var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
     return function() {
       context = this; args = arguments;
-      var throttler = function() {
+      var later = function() {
         timeout = null;
-        func.apply(context, args);
-        finishThrottle();
+        if (more) func.apply(context, args);
+        whenDone();
       };
-      if (!timeout) timeout = setTimeout(throttler, wait);
-      if (!throttling) func.apply(context, args);
-      if (finishThrottle) finishThrottle();
+      if (!timeout) timeout = setTimeout(later, wait);
+      if (throttling) {
+        more = true;
+      } else {
+        func.apply(context, args);
+      }
+      whenDone();
       throttling = true;
     };
   };

Returns a function, that, as long as it continues to be invoked, will not @@ -373,12 +381,12 @@ N milliseconds.

var timeout; return function() { var context = this, args = arguments; - var throttler = function() { + var later = function() { timeout = null; func.apply(context, args); }; clearTimeout(timeout); - timeout = setTimeout(throttler, wait); + timeout = setTimeout(later, wait); }; };

Returns a function that will be executed at most one time, no matter how often you call it. Useful for lazy initialization.

  _.once = function(func) {
@@ -406,6 +414,7 @@ consuming the return value of the function that follows.

Returns a function that will only be executed after being called N times.

  _.after = function(times, func) {
+    if (times <= 0) return func();
     return function() {
       if (--times < 1) { return func.apply(this, arguments); }
     };
@@ -447,49 +456,61 @@ order to perform operations on intermediate results within the chain.

interceptor(obj); return obj; };

Internal recursive comparison function.

  function eq(a, b, stack) {

Identical objects are equal. 0 === -0, but they aren't identical. -See the Harmony egal proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.

    if (a === b) return a !== 0 || 1 / a == 1 / b;

A strict comparison is necessary because null == undefined.

    if ((a == null) || (b == null)) return a === b;

Unwrap any wrapped objects.

    if (a._chain) a = a._wrapped;
+See the Harmony egal proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.

    if (a === b) return a !== 0 || 1 / a == 1 / b;

A strict comparison is necessary because null == undefined.

    if (a == null || b == null) return a === b;

Unwrap any wrapped objects.

    if (a._chain) a = a._wrapped;
     if (b._chain) b = b._wrapped;

Invoke a custom isEqual method if one is provided.

    if (_.isFunction(a.isEqual)) return a.isEqual(b);
-    if (_.isFunction(b.isEqual)) return b.isEqual(a);

Compare object types.

    var typeA = typeof a;
-    if (typeA != typeof b) return false;

Optimization; ensure that both values are truthy or falsy.

    if (!a != !b) return false;

NaN values are equal.

    if (_.isNaN(a)) return _.isNaN(b);

Compare string objects by value.

    var isStringA = _.isString(a), isStringB = _.isString(b);
-    if (isStringA || isStringB) return isStringA && isStringB && String(a) == String(b);

Compare number objects by value.

    var isNumberA = _.isNumber(a), isNumberB = _.isNumber(b);
-    if (isNumberA || isNumberB) return isNumberA && isNumberB && +a == +b;

Compare boolean objects by value. The value of true is 1; the value of false is 0.

    var isBooleanA = _.isBoolean(a), isBooleanB = _.isBoolean(b);
-    if (isBooleanA || isBooleanB) return isBooleanA && isBooleanB && +a == +b;

Compare dates by their millisecond values.

    var isDateA = _.isDate(a), isDateB = _.isDate(b);
-    if (isDateA || isDateB) return isDateA && isDateB && a.getTime() == b.getTime();

Compare RegExps by their source patterns and flags.

    var isRegExpA = _.isRegExp(a), isRegExpB = _.isRegExp(b);
-    if (isRegExpA || isRegExpB) {

Ensure commutative equality for RegExps.

      return isRegExpA && isRegExpB &&
-             a.source == b.source &&
-             a.global == b.global &&
-             a.multiline == b.multiline &&
-             a.ignoreCase == b.ignoreCase;
-    }

Ensure that both values are objects.

    if (typeA != 'object') return false;

Arrays or Arraylikes with different lengths are not equal.

    if (a.length !== b.length) return false;

Objects with different constructors are not equal.

    if (a.constructor !== b.constructor) return false;

Assume equality for cyclic structures. The algorithm for detecting cyclic + if (_.isFunction(b.isEqual)) return b.isEqual(a);

Compare [[Class]] names.

    var className = toString.call(a);
+    if (className != toString.call(b)) return false;
+    switch (className) {

Strings, numbers, dates, and booleans are compared by value.

      case '[object String]':

Primitives and their corresponding object wrappers are equivalent; thus, "5" is +equivalent to new String("5").

        return String(a) == String(b);
+      case '[object Number]':
+        a = +a;
+        b = +b;

NaNs are equivalent, but non-reflexive. An egal comparison is performed for +other numeric values.

        return a != a ? b != b : (a == 0 ? 1 / a == 1 / b : a == b);
+      case '[object Date]':
+      case '[object Boolean]':

Coerce dates and booleans to numeric primitive values. Dates are compared by their +millisecond representations. Note that invalid dates with millisecond representations +of NaN are not equivalent.

        return +a == +b;

RegExps are compared by their source patterns and flags.

      case '[object RegExp]':
+        return a.source == b.source &&
+               a.global == b.global &&
+               a.multiline == b.multiline &&
+               a.ignoreCase == b.ignoreCase;
+    }
+    if (typeof a != 'object' || typeof b != 'object') return false;

Assume equality for cyclic structures. The algorithm for detecting cyclic structures is adapted from ES 5.1 section 15.12.3, abstract operation JO.

    var length = stack.length;
-    while (length--) {

Linear search. Performance is inversely proportional to the number of + while (length--) {

Linear search. Performance is inversely proportional to the number of unique nested structures.

      if (stack[length] == a) return true;
-    }

Add the first object to the stack of traversed objects.

    stack.push(a);
-    var size = 0, result = true;

Deep compare objects.

    for (var key in a) {
-      if (hasOwnProperty.call(a, key)) {

Count the expected number of properties.

        size++;

Deep compare each member.

        if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
+    }

Add the first object to the stack of traversed objects.

    stack.push(a);
+    var size = 0, result = true;

Recursively compare objects and arrays.

    if (className == '[object Array]') {

Compare array lengths to determine if a deep comparison is necessary.

      size = a.length;
+      result = size == b.length;
+      if (result) {

Deep compare the contents, ignoring non-numeric properties.

        while (size--) {

Ensure commutative equality for sparse arrays.

          if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
+        }
       }
-    }

Ensure that both objects contain the same number of properties.

    if (result) {
-      for (key in b) {
-        if (hasOwnProperty.call(b, key) && !size--) break;
+    } else {

Objects with different constructors are not equivalent.

      if ("constructor" in a != "constructor" in b || a.constructor != b.constructor) return false;

Deep compare objects.

      for (var key in a) {
+        if (hasOwnProperty.call(a, key)) {

Count the expected number of properties.

          size++;

Deep compare each member.

          if (!(result = hasOwnProperty.call(b, key) && eq(a[key], b[key], stack))) break;
+        }
+      }

Ensure that both objects contain the same number of properties.

      if (result) {
+        for (key in b) {
+          if (hasOwnProperty.call(b, key) && !(size--)) break;
+        }
+        result = !size;
       }
-      result = !size;
-    }

Remove the first object from the stack of traversed objects.

    stack.pop();
+    }

Remove the first object from the stack of traversed objects.

    stack.pop();
     return result;
-  }

Perform a deep comparison to check if two objects are equal.

  _.isEqual = function(a, b) {
+  }

Perform a deep comparison to check if two objects are equal.

  _.isEqual = function(a, b) {
     return eq(a, b, []);
-  };

Is a given array, string, or object empty? + };

Is a given array, string, or object empty? An "empty" object has no enumerable own-properties.

  _.isEmpty = function(obj) {
     if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
     for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
     return true;
-  };

Is a given value a DOM element?

  _.isElement = function(obj) {
+  };

Is a given value a DOM element?

  _.isElement = function(obj) {
     return !!(obj && obj.nodeType == 1);
-  };

Is a given value an array? + };

Is a given value an array? Delegates to ECMA5's native Array.isArray

  _.isArray = nativeIsArray || function(obj) {
     return toString.call(obj) == '[object Array]';
-  };

Is a given variable an object?

  _.isObject = function(obj) {
+  };

Is a given variable an object?

  _.isObject = function(obj) {
     return obj === Object(obj);
-  };

Is a given variable an arguments object?

  if (toString.call(arguments) == '[object Arguments]') {
+  };

Is a given variable an arguments object?

  if (toString.call(arguments) == '[object Arguments]') {
     _.isArguments = function(obj) {
       return toString.call(obj) == '[object Arguments]';
     };
@@ -497,49 +518,49 @@ Delegates to ECMA5's native Array.isArray

_.isArguments = function(obj) { return !!(obj && hasOwnProperty.call(obj, 'callee')); }; - }

Is a given value a function?

  _.isFunction = function(obj) {
+  }

Is a given value a function?

  _.isFunction = function(obj) {
     return toString.call(obj) == '[object Function]';
-  };

Is a given value a string?

  _.isString = function(obj) {
+  };

Is a given value a string?

  _.isString = function(obj) {
     return toString.call(obj) == '[object String]';
-  };

Is a given value a number?

  _.isNumber = function(obj) {
+  };

Is a given value a number?

  _.isNumber = function(obj) {
     return toString.call(obj) == '[object Number]';
-  };

Is the given value NaN?

  _.isNaN = function(obj) {

NaN is the only value for which === is not reflexive.

    return obj !== obj;
-  };

Is a given value a boolean?

  _.isBoolean = function(obj) {
+  };

Is the given value NaN?

  _.isNaN = function(obj) {

NaN is the only value for which === is not reflexive.

    return obj !== obj;
+  };

Is a given value a boolean?

  _.isBoolean = function(obj) {
     return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
-  };

Is a given value a date?

  _.isDate = function(obj) {
+  };

Is a given value a date?

  _.isDate = function(obj) {
     return toString.call(obj) == '[object Date]';
-  };

Is the given value a regular expression?

  _.isRegExp = function(obj) {
+  };

Is the given value a regular expression?

  _.isRegExp = function(obj) {
     return toString.call(obj) == '[object RegExp]';
-  };

Is a given value equal to null?

  _.isNull = function(obj) {
+  };

Is a given value equal to null?

  _.isNull = function(obj) {
     return obj === null;
-  };

Is a given variable undefined?

  _.isUndefined = function(obj) {
+  };

Is a given variable undefined?

  _.isUndefined = function(obj) {
     return obj === void 0;
-  };

Utility Functions

Run Underscore.js in noConflict mode, returning the _ variable to its + };

Utility Functions

Run Underscore.js in noConflict mode, returning the _ variable to its previous owner. Returns a reference to the Underscore object.

  _.noConflict = function() {
     root._ = previousUnderscore;
     return this;
-  };

Keep the identity function around for default iterators.

  _.identity = function(value) {
+  };

Keep the identity function around for default iterators.

  _.identity = function(value) {
     return value;
-  };

Run a function n times.

  _.times = function (n, iterator, context) {
+  };

Run a function n times.

  _.times = function (n, iterator, context) {
     for (var i = 0; i < n; i++) iterator.call(context, i);
-  };

Escape a string for HTML interpolation.

  _.escape = function(string) {
-    return (''+string).replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
-  };

Add your own custom functions to the Underscore object, ensuring that + };

Escape a string for HTML interpolation.

  _.escape = function(string) {
+    return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
+  };

Add your own custom functions to the Underscore object, ensuring that they're correctly added to the OOP wrapper as well.

  _.mixin = function(obj) {
     each(_.functions(obj), function(name){
       addToWrapper(name, _[name] = obj[name]);
     });
-  };

Generate a unique integer id (unique within the entire client session). + };

Generate a unique integer id (unique within the entire client session). Useful for temporary DOM ids.

  var idCounter = 0;
   _.uniqueId = function(prefix) {
     var id = idCounter++;
     return prefix ? prefix + id : id;
-  };

By default, Underscore uses ERB-style template delimiters, change the + };

By default, Underscore uses ERB-style template delimiters, change the following template settings to use alternative delimiters.

  _.templateSettings = {
     evaluate    : /<%([\s\S]+?)%>/g,
     interpolate : /<%=([\s\S]+?)%>/g,
     escape      : /<%-([\s\S]+?)%>/g
-  };

JavaScript micro-templating, similar to John Resig's implementation. + };

JavaScript micro-templating, similar to John Resig's implementation. Underscore templating handles arbitrary delimiters, preserves whitespace, and correctly escapes quotes within interpolated code.

  _.template = function(str, data) {
     var c  = _.templateSettings;
@@ -555,42 +576,42 @@ and correctly escapes quotes within interpolated code.

The OOP Wrapper

If Underscore is called as a function, it returns a wrapped object that + var func = new Function('obj', '_', tmpl); + return data ? func(data, _) : function(data) { return func(data, _) }; + };

The OOP Wrapper

If Underscore is called as a function, it returns a wrapped object that can be used OO-style. This wrapper holds altered versions of all the -underscore functions. Wrapped objects may be chained.

  var wrapper = function(obj) { this._wrapped = obj; };

Expose wrapper.prototype as _.prototype

  _.prototype = wrapper.prototype;

Helper function to continue chaining intermediate results.

  var result = function(obj, chain) {
+underscore functions. Wrapped objects may be chained.

  var wrapper = function(obj) { this._wrapped = obj; };

Expose wrapper.prototype as _.prototype

  _.prototype = wrapper.prototype;

Helper function to continue chaining intermediate results.

  var result = function(obj, chain) {
     return chain ? _(obj).chain() : obj;
-  };

A method to easily add functions to the OOP wrapper.

  var addToWrapper = function(name, func) {
+  };

A method to easily add functions to the OOP wrapper.

  var addToWrapper = function(name, func) {
     wrapper.prototype[name] = function() {
       var args = slice.call(arguments);
       unshift.call(args, this._wrapped);
       return result(func.apply(_, args), this._chain);
     };
-  };

Add all of the Underscore functions to the wrapper object.

  _.mixin(_);

Add all mutator Array functions to the wrapper.

  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+  };

Add all of the Underscore functions to the wrapper object.

  _.mixin(_);

Add all mutator Array functions to the wrapper.

  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
     var method = ArrayProto[name];
     wrapper.prototype[name] = function() {
       method.apply(this._wrapped, arguments);
       return result(this._wrapped, this._chain);
     };
-  });

Add all accessor Array functions to the wrapper.

  each(['concat', 'join', 'slice'], function(name) {
+  });

Add all accessor Array functions to the wrapper.

  each(['concat', 'join', 'slice'], function(name) {
     var method = ArrayProto[name];
     wrapper.prototype[name] = function() {
       return result(method.apply(this._wrapped, arguments), this._chain);
     };
-  });

Start chaining a wrapped Underscore object.

  wrapper.prototype.chain = function() {
+  });

Start chaining a wrapped Underscore object.

  wrapper.prototype.chain = function() {
     this._chain = true;
     return this;
-  };

Extracts the result from a wrapped and chained object.

  wrapper.prototype.value = function() {
+  };

Extracts the result from a wrapped and chained object.

  wrapper.prototype.value = function() {
     return this._wrapped;
   };
 
-})();
+}).call(this);
 
 
\ No newline at end of file diff --git a/index.html b/index.html index b2d4a850b..fe8321aef 100644 --- a/index.html +++ b/index.html @@ -126,11 +126,11 @@ - - + + - +
Development Version (1.2.1)33kb, Uncompressed with CommentsDevelopment Version (1.2.2)34kb, Uncompressed with Comments
Production Version (1.2.1)Production Version (1.2.2) < 4kb, Minified and Gzipped
@@ -1338,6 +1338,29 @@ _([1, 2, 3]).value();

Change Log

+

+ 1.2.2Nov. 14, 2011
+

    +
  • + Continued tweaks to _.isEqual semantics. Now JS primitives are + considered equivalent to their wrapped versions, and arrays are compared + by their numeric properties only (#351). +
  • +
  • + _.escape no longer tries to be smart about not double-escaping + already-escaped HTML entities. Now it just escapes regardless (#350). +
  • +
  • + In _.template, you may now leave semicolons out of evaluated + statements if you wish: <% }) %> (#369). +
  • +
  • + _.after(callback, 0) will now trigger the callback immediately, + making "after" easier to use with asynchronous APIs (#366). +
  • +
+

+

1.2.1Oct. 24, 2011

    diff --git a/package.json b/package.json index 54f839863..8481b773a 100644 --- a/package.json +++ b/package.json @@ -8,5 +8,5 @@ "dependencies" : [], "repository" : {"type": "git", "url": "git://github.com/documentcloud/underscore.git"}, "main" : "underscore.js", - "version" : "1.2.1" + "version" : "1.2.2" } diff --git a/underscore-min.js b/underscore-min.js index ad3756028..fadc96eca 100644 --- a/underscore-min.js +++ b/underscore-min.js @@ -1,30 +1,30 @@ -// Underscore.js 1.2.1 +// Underscore.js 1.2.2 // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. // Underscore is freely distributable under the MIT license. // Portions of Underscore are inspired or borrowed from Prototype, // Oliver Steele's Functional, and John Resig's Micro-Templating. // For all details and documentation: // http://documentcloud.github.com/underscore -(function(){function u(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(b.isFunction(a.isEqual))return a.isEqual(c);if(b.isFunction(c.isEqual))return c.isEqual(a);var e=typeof a;if(e!=typeof c)return false;if(!a!=!c)return false;if(b.isNaN(a))return b.isNaN(c);var g=b.isString(a),f=b.isString(c);if(g||f)return g&&f&&String(a)==String(c);g=b.isNumber(a);f=b.isNumber(c);if(g||f)return g&&f&&+a==+c;g=b.isBoolean(a);f=b.isBoolean(c); -if(g||f)return g&&f&&+a==+c;g=b.isDate(a);f=b.isDate(c);if(g||f)return g&&f&&a.getTime()==c.getTime();g=b.isRegExp(a);f=b.isRegExp(c);if(g||f)return g&&f&&a.source==c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase;if(e!="object")return false;if(a.length!==c.length)return false;if(a.constructor!==c.constructor)return false;for(e=d.length;e--;)if(d[e]==a)return true;d.push(a);var e=0,g=true,h;for(h in a)if(m.call(a,h)&&(e++,!(g=m.call(c,h)&&u(a[h],c[h],d))))break;if(g){for(h in c)if(m.call(c, -h)&&!e--)break;g=!e}d.pop();return g}var r=this,F=r._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,G=k.unshift,l=p.toString,m=p.hasOwnProperty,v=k.forEach,w=k.map,x=k.reduce,y=k.reduceRight,z=k.filter,A=k.every,B=k.some,q=k.indexOf,C=k.lastIndexOf,p=Array.isArray,H=Object.keys,s=Function.prototype.bind,b=function(a){return new n(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else typeof define==="function"&&define.amd? -define("underscore",function(){return b}):r._=b;b.VERSION="1.2.1";var j=b.each=b.forEach=function(a,c,b){if(a!=null)if(v&&a.forEach===v)a.forEach(c,b);else if(a.length===+a.length)for(var e=0,g=a.length;e=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,g=a.length;e< -g;){var f=e+g>>1;d(a[f])=0})})};b.difference=function(a,c){return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return function(){if(--a<1)return b.apply(this,arguments)}};b.keys=H||function(a){if(a!==Object(a))throw new TypeError("Invalid object"); -var b=[],d;for(d in a)m.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({}, -a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return u(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(m.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=l.call(arguments)=="[object Arguments]"?function(a){return l.call(a)=="[object Arguments]"}:function(a){return!(!a||!m.call(a, -"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a=== -void 0};b.noConflict=function(){r._=F;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),function(c){I(c,b[c]=a[c])})};var J=0;b.uniqueId=function(a){var b=J++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g, -interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape,function(a,b){return"',_.escape("+b.replace(/\\'/g,"'")+"),'"}).replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g, -"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",d=new Function("obj",d);return c?d(c):d};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var t=function(a,c){return c?b(a).chain():a},I=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);G.call(a,this._wrapped);return t(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];n.prototype[a]=function(){b.apply(this._wrapped,arguments);return t(this._wrapped, -this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];n.prototype[a]=function(){return t(b.apply(this._wrapped,arguments),this._chain)}});n.prototype.chain=function(){this._chain=true;return this};n.prototype.value=function(){return this._wrapped}})(); +(function(){function r(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(b.isFunction(a.isEqual))return a.isEqual(c);if(b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return String(a)==String(c);case "[object Number]":return a=+a,c=+c,a!=a?c!=c:a==0?1/a==1/c:a==c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== +c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&r(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(m.call(a,h)&&(f++,!(g=m.call(c,h)&&r(a[h],c[h],d))))break;if(g){for(h in c)if(m.call(c, +h)&&!f--)break;g=!f}}d.pop();return g}var s=this,F=s._,o={},k=Array.prototype,p=Object.prototype,i=k.slice,G=k.unshift,l=p.toString,m=p.hasOwnProperty,v=k.forEach,w=k.map,x=k.reduce,y=k.reduceRight,z=k.filter,A=k.every,B=k.some,q=k.indexOf,C=k.lastIndexOf,p=Array.isArray,H=Object.keys,t=Function.prototype.bind,b=function(a){return new n(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else typeof define==="function"&&define.amd? +define("underscore",function(){return b}):s._=b;b.VERSION="1.2.2";var j=b.each=b.forEach=function(a,c,b){if(a!=null)if(v&&a.forEach===v)a.forEach(c,b);else if(a.length===+a.length)for(var e=0,f=a.length;e=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,c){var b=e(a,c);(d[b]||(d[b]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var e=0,f=a.length;e< +f;){var g=e+f>>1;d(a[g])=0})})};b.difference=function(a,c){return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=H||function(a){if(a!== +Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)m.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)? +a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return r(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(m.call(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=l.call(arguments)=="[object Arguments]"?function(a){return l.call(a)=="[object Arguments]"}: +function(a){return!(!a||!m.call(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null}; +b.isUndefined=function(a){return a===void 0};b.noConflict=function(){s._=F;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),function(c){I(c,b[c]=a[c])})};var J=0;b.uniqueId=function(a){var b=J++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g, +interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape,function(a,b){return"',_.escape("+b.replace(/\\'/g,"'")+"),'"}).replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g, +"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e(a,b)}};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var u=function(a,c){return c?b(a).chain():a},I=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);G.call(a,this._wrapped);return u(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];n.prototype[a]=function(){b.apply(this._wrapped, +arguments);return u(this._wrapped,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];n.prototype[a]=function(){return u(b.apply(this._wrapped,arguments),this._chain)}});n.prototype.chain=function(){this._chain=true;return this};n.prototype.value=function(){return this._wrapped}}).call(this); diff --git a/underscore.js b/underscore.js index b6a6e104f..5579c07d3 100644 --- a/underscore.js +++ b/underscore.js @@ -1,4 +1,4 @@ -// Underscore.js 1.2.1 +// Underscore.js 1.2.2 // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. // Underscore is freely distributable under the MIT license. // Portions of Underscore are inspired or borrowed from Prototype, @@ -67,7 +67,7 @@ } // Current version. - _.VERSION = '1.2.1'; + _.VERSION = '1.2.2'; // Collection Functions // --------------------