Underscore.js 1.2.2
-(c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
+ underscore.js
underscore.js Underscore.js 1.2.3
+(c) 2009-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
Baseline setup Establish the root object, window in the browser, or global on the server.
Save the previous value of the _ variable.
var previousUnderscore = root . _ ; Establish the object that gets returned to break out of a loop iteration.
Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array . prototype , ObjProto = Object . prototype , FuncProto = Function . prototype ; Create quick reference variables for speed access to core prototypes.
var slice = ArrayProto . slice ,
+ concat = ArrayProto . concat ,
unshift = ArrayProto . unshift ,
toString = ObjProto . toString ,
hasOwnProperty = ObjProto . hasOwnProperty ; All ECMAScript 5 native function implementations that we hope to use
@@ -32,7 +33,7 @@ CommonJS, add _ to the global object.
return _ ;
});
} else { Exported as a string, for Closure Compiler "advanced" mode.
Current version.
Collection Functions The cornerstone, an each implementation, aka forEach.
+ }
Current version.
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 ;
@@ -60,7 +61,7 @@ Delegates to ECMAScript 5 's native map if availabl
return results ;
}; Reduce builds up a single result from a list of values, aka inject,
or foldl. Delegates to ECMAScript 5 's native reduce if available.
_ . reduce = _ . foldl = _ . inject = function ( obj , iterator , memo , context ) {
- var initial = memo !== void 0 ;
+ var initial = arguments . length > 2 ;
if ( obj == null ) obj = [];
if ( nativeReduce && obj . reduce === nativeReduce ) {
if ( context ) iterator = _ . bind ( iterator , context );
@@ -74,17 +75,19 @@ or foldl. Delegates to ECMAScript 5 's native memo = iterator . call ( context , memo , value , index , list );
}
});
- if ( ! initial ) throw new TypeError ( "Reduce of empty array with no initial value" );
+ if ( ! initial ) throw new TypeError ( 'Reduce of empty array with no initial value' );
return memo ;
}; The right-associative version of reduce, also known as foldr.
Delegates to ECMAScript 5 's native reduceRight if available.
_ . reduceRight = _ . foldr = function ( obj , iterator , memo , context ) {
+ var initial = arguments . length > 2 ;
if ( obj == null ) obj = [];
if ( nativeReduceRight && obj . reduceRight === nativeReduceRight ) {
if ( context ) iterator = _ . bind ( iterator , context );
- return memo !== void 0 ? obj . reduceRight ( iterator , memo ) : obj . reduceRight ( iterator );
+ return initial ? obj . reduceRight ( iterator , memo ) : obj . reduceRight ( iterator );
}
- var reversed = ( _ . isArray ( obj ) ? obj . slice () : _ . toArray ( obj )). reverse ();
- return _ . reduce ( reversed , iterator , memo , context );
+ var reversed = _ . toArray ( obj ). reverse ();
+ if ( context && ! initial ) iterator = _ . bind ( iterator , context );
+ return initial ? _ . reduce ( reversed , iterator , memo , context ) : _ . reduce ( reversed , iterator );
}; Return the first value which passes a truth test. Aliased as detect.
_ . find = _ . detect = function ( obj , iterator , context ) {
var result ;
any ( obj , function ( value , index , list ) {
@@ -124,7 +127,7 @@ Aliased as all.
}; Determine if at least one element in the object matches a truth test.
Delegates to ECMAScript 5 's native some if available.
Aliased as any.
var any = _ . some = _ . any = function ( obj , iterator , context ) {
- iterator = iterator || _ . identity ;
+ iterator || ( iterator = _ . identity );
var result = false ;
if ( obj == null ) return result ;
if ( nativeSome && obj . some === nativeSome ) return obj . some ( iterator , context );
@@ -269,9 +272,10 @@ passed-in arrays. (Aliased as "intersect" for back-compat.) return _ . indexOf ( other , item ) >= 0 ;
});
});
- }; Take the difference between one array and another.
-Only the elements present in just the first array will remain.
_ . difference = function ( array , other ) {
- return _ . filter ( array , function ( value ){ return ! _ . include ( other , value ); });
+ }; Take the difference between one array and a number of other arrays.
+Only the elements present in just the first array will remain.
_ . difference = function ( array ) {
+ var rest = _ . flatten ( slice . call ( arguments , 1 ));
+ return _ . filter ( array , function ( value ){ return ! _ . include ( rest , value ); });
}; Zip together multiple lists into a single array -- elements that share
an index go together.
_ . zip = function () {
var args = slice . call ( arguments );
@@ -292,13 +296,13 @@ for isSorted to use binary search.
return array [ i ] === item ? i : - 1 ;
}
if ( nativeIndexOf && array . indexOf === nativeIndexOf ) return array . indexOf ( item );
- for ( i = 0 , l = array . length ; i < l ; i ++ ) if ( array [ i ] === item ) return i ;
+ for ( i = 0 , l = array . length ; i < l ; i ++ ) if ( i in array && array [ i ] === item ) return i ;
return - 1 ;
}; Delegates to ECMAScript 5 's native lastIndexOf if available.
_ . lastIndexOf = function ( array , item ) {
if ( array == null ) return - 1 ;
if ( nativeLastIndexOf && array . lastIndexOf === nativeLastIndexOf ) return array . lastIndexOf ( item );
var i = array . length ;
- while ( i -- ) if ( array [ i ] === item ) return i ;
+ while ( i -- ) if ( i in array && array [ i ] === item ) return i ;
return - 1 ;
}; Generate an integer Array containing an arithmetic progression. A port of
the native Python range() function. See
@@ -400,14 +404,14 @@ often you call it. Useful for lazy initialization.
allowing you to adjust arguments, run code before and after, and
conditionally execute the original function. _ . wrap = function ( func , wrapper ) {
return function () {
- var args = [ func ]. concat ( slice . call ( arguments ));
+ var args = concat . apply ([ func ], arguments );
return wrapper . apply ( this , args );
};
}; Returns a function that is the composition of a list of functions, each
consuming the return value of the function that follows.
_ . compose = function () {
- var funcs = slice . call ( arguments );
+ var funcs = arguments ;
return function () {
- var args = slice . call ( arguments );
+ var args = arguments ;
for ( var i = funcs . length - 1 ; i >= 0 ; i -- ) {
args = [ funcs [ i ]. apply ( this , args )];
}
@@ -457,15 +461,13 @@ order to perform operations on intermediate results within the chain.
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 ;
- 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 [[Class]] names.
var className = toString . call ( a );
+ if ( b . _chain ) b = b . _wrapped ; Invoke a custom isEqual method if one is provided.
if ( a . isEqual && _ . isFunction ( a . isEqual )) return a . isEqual ( b );
+ if ( b . isEqual && _ . 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.
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 );
+equivalent to new String("5"). return a == String ( b );
+ case '[object Number]' : 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
@@ -485,7 +487,7 @@ unique nested structures.
if ( result ) { Deep compare the contents, ignoring non-numeric properties.
Ensure commutative equality for sparse arrays.
if ( ! ( result = size in a == size in b && eq ( a [ size ], b [ size ], stack ))) 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 ) {
+ } 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.
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 ) {
@@ -510,11 +512,10 @@ Delegates to ECMA5's native Array.isArray return toString . call ( obj ) == '[object Array]' ;
}; 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]' ) {
- _ . isArguments = function ( obj ) {
- return toString . call ( obj ) == '[object Arguments]' ;
- };
- } else {
+ }; Is a given variable an arguments object?
_ . isArguments = function ( obj ) {
+ return toString . call ( obj ) == '[object Arguments]' ;
+ };
+ if ( ! _ . isArguments ( arguments )) {
_ . isArguments = function ( obj ) {
return !! ( obj && hasOwnProperty . call ( obj , 'callee' ));
};
@@ -583,7 +584,10 @@ and correctly escapes quotes within interpolated code.
. replace ( /\t/g , '\\t' )
+ "');}return __p.join('');" ;
var func = new Function ( 'obj' , '_' , tmpl );
- return data ? func ( data , _ ) : function ( data ) { return func ( data , _ ) };
+ if ( data ) return func ( data , _ );
+ return function ( data ) {
+ return func . call ( this , 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 ) {
diff --git a/index.html b/index.html
index fd00cec9e..745311283 100644
--- a/index.html
+++ b/index.html
@@ -126,11 +126,11 @@
@@ -159,7 +159,7 @@
first , initial , last , rest ,
compact , flatten , without ,
- union , intersection , difference ,
+ union , intersection , difference ,
uniq , zip , indexOf ,
lastIndexOf , range
@@ -620,10 +620,10 @@ _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
- _.difference(array, other)
+ _.difference(array, *others)
Similar to without , but returns the values from array that
- are not present in other .
+ are not present in the other arrays.
_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
@@ -1338,6 +1338,24 @@ _([1, 2, 3]).value();
Change Log
+
+ — Dec. 7, 2011
+
+
+ Dynamic scope is now preserved for compiled _.template functions,
+ so you can use the value of this if you like.
+
+
+ Sparse array support of _.indexOf , _.lastIndexOf .
+
+
+ Both _.reduce and _.reduceRight can now be passed an
+ explicitly undefined value. (There's no reason why you'd
+ want to do this.)
+
+
+
+
— Nov. 14, 2011
diff --git a/package.json b/package.json
index 8481b773a..eda11ad52 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.2"
+ "version" : "1.2.3"
}
diff --git a/test/arrays.js b/test/arrays.js
index 1c910355f..b3b1ce15e 100644
--- a/test/arrays.js
+++ b/test/arrays.js
@@ -115,11 +115,6 @@ $(document).ready(function() {
equals(result.join(' '), '3 4', 'takes the difference of three arrays');
});
- test("arrays: symDifference", function() {
- var result = _.symDifference([1, 2, 3], [2, 22, 222], [3, 33, 333], [222, 333, 444], [5]);
- equals(result.join(' '), '1 22 33 444 5', 'takes the symmetric difference');
- });
-
test('arrays: zip', function() {
var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true];
var stooges = _.zip(names, ages, leaders);
diff --git a/underscore-min.js b/underscore-min.js
index fadc96eca..a2a40e4c0 100644
--- a/underscore-min.js
+++ b/underscore-min.js
@@ -1,30 +1,30 @@
-// Underscore.js 1.2.2
-// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore.js 1.2.3
+// (c) 2009-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 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==
+(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(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&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 a==String(c);case "[object Number]":return 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);
+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.concat,H=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,I=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.3";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;e2;a==null&&(a=[]);if(x&&a.reduce===x)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(y&&a.reduceRight===y)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,
+c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,c,b){var e;D(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(z&&a.filter===z)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(A&&a.every===A)return a.every(c,
+b);j(a,function(a,g,h){if(!(e=e&&c.call(b,a,g,h)))return o});return e};var D=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(B&&a.some===B)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return q&&a.indexOf===q?a.indexOf(c)!=-1:b=D(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a,
+d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.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;b>=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,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));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=I||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=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=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){J(c,
+b[c]=a[c])})};var K=0;b.uniqueId=function(a){var b=K++;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.call(this,a,b)}};var n=function(a){this._wrapped=a};b.prototype=n.prototype;var u=function(a,c){return c?b(a).chain():a},J=function(a,c){n.prototype[a]=function(){var a=i.call(arguments);H.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 22446234d..b6b28137d 100644
--- a/underscore.js
+++ b/underscore.js
@@ -1,5 +1,5 @@
-// Underscore.js 1.2.2
-// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore.js 1.2.3
+// (c) 2009-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.
@@ -68,7 +68,7 @@
}
// Current version.
- _.VERSION = '1.2.2';
+ _.VERSION = '1.2.3';
// Collection Functions
// --------------------
@@ -412,14 +412,6 @@
return _.filter(array, function(value){ return !_.include(rest, value); });
};
- // Take the symmetric difference between a list of arrays. Only the elements
- // present in one of the input arrays will remain.
- _.symDifference = function() {
- return _.reduce(arguments, function(memo, array) {
- return _.union(_.difference(memo, array), _.difference(array, memo));
- });
- };
-
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {