New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

sugar

Package Overview
Dependencies
Maintainers
1
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sugar - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

lib/externs.js

31

CHANGELOG.md

@@ -0,1 +1,32 @@

v1.1
=====
### API Changes ###
- Array#unique can now unique on a function, giving a shortcut to uniquify deep objects
- Object.equals renamed to Object.equal in its class method only
- Object.equal now much more robust, can handle cyclic references, etc
- Number#format now accepts a parameter <place> for the decimal. "thousands", and "decimal" are pushed to 2nd and 3rd params
- Date#format now accepts different format tokens. A few counterintuitive ones removed, and others were added to match moment.js including fff, ddd, mmm, etc
- Function#lazy now executes immediately and locks instead of setting a delay
- Added RegExp#getFlags
- Added Function#fill, which allows arguments to be intelligently curried
- Fixed broken support for SpiderMonkey under CouchDB
- Fixed sortBy is unintentionally destructive
- Full Asian date number formats now accepted
- Array#map/min/max/most/least/groupBy/sortBy no longer errors on undefined, null, etc
- Fixed a bug with locking on Number#format when passing digits
### Internal Changes ###
- Optimized for Google closure compilers max compression level
- Minified script dropped about 5kb
- Intelligently determining if cloned objects are extended
- transformArgument now just accepts <map> not the arguments object
- refactored asian digits to be globally replaced
- Date#toJSON and Date#toISOString now properly fall back to native methods
- Significantly wrote asynchronous function tests to be more reliable
v1.0

@@ -2,0 +33,0 @@ =====

242

lib/analyzer.js

@@ -21,5 +21,6 @@ (function() {

name: '$A',
message: '$A casts objects into arrays. It does not exist in Sugar, but Object#merge can achieve something similar:',
recommend_before: "$A({ 0: 'a', 1: 'b', 2: 'c' })",
recommend_after: "Object.merge([], { 0: 'a', 1: 'b', 2: 'c' })",
message: '$A exists in Sugar as Array.create.\nBe aware, however, that when a Javascript primitive is passed, it will simply be added to the array.\nIf, for example, you need a string to be split into the array, then use the standard String#split instead. The most common use of this method, converting an arguments object into an actual array, will work, however:',
recommend_before: '$A(arguments)',
recommend_after: 'Array.create(arguments)',
ref: 'Array/create'
},

@@ -31,2 +32,3 @@ {

recommend_after: "Object.extended({ 0: 'a', 1: 'b', 2: 'c' })",
ref: 'Object/extended'
},

@@ -38,8 +40,9 @@ {

recommend_after: "(0).upto(10)",
ref: 'Number/upto'
},
{
name: '$w',
message: '$w does not exist in Sugar.\nUse String#split instead:',
message: '$w does not exist in Sugar.\nUse native String#split instead:',
recommend_before: "$w('apples and oranges')",
recommend_after: "'apples and oranges'.split(' ')",
recommend_after: "'apples and oranges'.split(' ')"
}

@@ -66,8 +69,10 @@ ]

recommend_after: "(8).times(function(){}.bind('barf'))",
ref: 'Function/bind'
},
{
name: 'toColorPart',
message: 'Number#toColorPart does not exist in Sugar.\nUse Number#hex and pad to 2 places instead:',
message: 'Number#toColorPart does not exist in Sugar.\nUse Number#hex can pad to 2 places, however:',
recommend_before: "(255).toColorPart()",
recommend_after: "(255).hex(2)",
ref: 'Number/hex'
},

@@ -79,2 +84,3 @@ {

recommend_after: "(20).pad(4, false, 2)",
ref: 'Number/pad'
}

@@ -106,3 +112,4 @@ ]

recommend_before: "'hello'.blank()",
recommend_after: "'hello'.isBlank()"
recommend_after: "'hello'.isBlank()",
ref: 'String/isBlank'
},

@@ -114,3 +121,4 @@ {

},
message: 'String#camelize found white space or underscores!\nNote that #camelize in Sugar will remove whitespace and operate on underscores the same as dashes.'
message: 'String#camelize found white space or underscores!\nNote that #camelize in Sugar will remove whitespace and operate on underscores the same as dashes.',
ref: 'String/camelize'
},

@@ -122,3 +130,4 @@ {

},
message: 'String#dasherize found white space or capital letters!\nNote that #dasherize in Sugar will remove whitespace and operate on capital letters the same as underscores.'
message: 'String#dasherize found white space or capital letters!\nNote that #dasherize in Sugar will remove whitespace and operate on capital letters the same as underscores.',
ref: 'String/dasherize'
},

@@ -139,3 +148,3 @@ {

name: 'evalScripts',
message: "String#evalScripts does not exist in Sugar.\nIt's highly unlikely that you should be doing something like this anyway,\nbut if you really need to in a pinch, something like this may work:",
message: "String#evalScripts does not exist in Sugar.\nIt's highly unlikely that you should be doing something like this anyway, (and even if you are, libraries like jQuery should perform this automatically),\nbut if you really need to in a pinch, something like this may work:",
recommend_before: "str.evalScripts()",

@@ -160,3 +169,4 @@ recommend_after: "str.match(/<script.*?>.+?<\/script>/g).map(function(m){ return eval(m.replace(/<\/?script.*?>/g, '')); })",

recommend_before: "'foobar'.include('bar')",
recommend_after: "'foobar'.has('bar')"
recommend_after: "'foobar'.has('bar')",
ref: 'String/has'
},

@@ -169,8 +179,8 @@ {

},
// TODO: ADD THIS??
{
name: 'interpolate',
message: 'String#interpolate does not exist in Sugar.\nThis may be added in at a later date.\nFor now, String#replace can serve as a (primitive) alternative:',
message: 'String#interpolate exists in Sugar as String#assign, with a slightly different syntax:',
recommend_before: "'i like #{fruit}'.interpolate({ fruit: 'peaches' })",
recommend_after: "'i like #{fruit}'.replace(/#{fruit}/, 'peaches')"
recommend_after: "'i like {fruit}'.assign({ fruit: 'peaches' })",
ref: 'String/assign'
},

@@ -187,3 +197,4 @@ {

recommend_before: "'apple, pear & orange'.scan(/\w+/, console.log)",
recommend_after: "'apple, pear & orange'.each(/\w+/, console.log)"
recommend_after: "'apple, pear & orange'.each(/\w+/, console.log)",
ref: 'String/each'
},

@@ -194,3 +205,4 @@ {

recommend_before: "' howdy '.strip()",
recommend_after: "' howdy '.trim()"
recommend_after: "' howdy '.trim()",
ref: 'String/trim'
},

@@ -201,3 +213,4 @@ {

recommend_before: "'<script>doEvilStuff();</script>'.stripScripts()",
recommend_after: "'<script>doEvilStuff();</script>'.removeTags('script')"
recommend_after: "'<script>doEvilStuff();</script>'.removeTags('script')",
ref: 'String/removeTags'
},

@@ -209,3 +222,4 @@ {

},
message: 'String#stripTags found namespaced tags such as <xsl:template>. Be aware that Sugar will strip these tags too!'
message: 'String#stripTags found namespaced tags such as <xsl:template>. Be aware that Sugar will strip these tags too!',
ref: 'String/stripTags'
},

@@ -222,3 +236,4 @@ {

recommend_before: "'a'.succ()",
recommend_after: "'a'.shift(1);"
recommend_after: "'a'.shift(1);",
ref: 'String/shift'
},

@@ -229,3 +244,4 @@ {

recommend_before: "'echo '.times(3)",
recommend_after: "'echo '.repeat(3);"
recommend_after: "'echo '.repeat(3);",
ref: 'String/repeat'
},

@@ -236,15 +252,21 @@ {

recommend_before: "'howdy'.toArray()",
recommend_after: "'howdy'.chars();"
recommend_after: "'howdy'.chars();",
ref: 'String/chars'
},
{
name: 'toQueryParams',
message: 'String#toQueryParams exists in Sugar as String#toObject.\nThis method allows two tokens to turn a string into a key/value hash.\nThe default tokens are exactly those for parsing out a URL string, so no parameters are required.',
message: 'String#toQueryParams exists in Sugar but from an inverted perspective as Object.fromQueryString.\nNote that by default this will also parse out nested params with the non-standard "[]" syntax, however this can be turned off.',
recommend_before: "'section=blog&id=45'.toQueryParams()",
recommend_after: "'section=blog&id=45'.toObject()"
recommend_after: "Object.fromQueryString('section=blog&id=45')",
ref: 'Object/fromQueryString'
},
{
name: 'truncate',
condition: function() {
//not surereturn arguments.length == 0 && /<.*?:.*?>/.test(this);
},
message: 'String#truncate does not exist in Sugar.\nUse String#slice instead:',
recommend_before: "longString.truncate(10, '...')",
recommend_after: "longString.slice(0, 10) + '...'"
recommend_after: "longString.slice(0, 10) + '...'",
ref: 'String/truncate'
},

@@ -256,3 +278,4 @@ {

},
message: 'String#underscore found white space!\nNote that underscore in Sugar will remove all whitespace.'
message: 'String#underscore found white space!\nNote that underscore in Sugar will remove all whitespace.',
ref: 'String/underscore'
},

@@ -286,2 +309,3 @@ {

recommend_after: "Object.extended().each(function(){}.bind('context'))",
ref: 'Object/each'
},

@@ -293,2 +317,3 @@ {

recommend_after: "var h = Object.extended({ foo: 'bar' }); h['foo']",
ref: 'Object/extended'
},

@@ -299,3 +324,3 @@ {

recommend_before: "var key = new Hash({ foo: 'bar' }).index('bar')",
recommend_after: "Object.extended({ foo: 'bar' }).each(function(k, v){ if(v == 'bar') var key = k; })",
recommend_after: "Object.extended({ foo: 'bar' }).each(function(k, v){ if(v == 'bar') var key = k; })"
},

@@ -312,3 +337,4 @@ {

recommend_before: "new Hash({ foo: 'bar' }).merge({ moo: 'car' })",
recommend_after: "Object.extended({ foo: 'bar' }).clone().merge({ moo: 'car' })"
recommend_after: "Object.extended({ foo: 'bar' }).clone().merge({ moo: 'car' })",
ref: 'Object/merge'
},

@@ -320,2 +346,3 @@ {

recommend_after: "var h = Object.extended({ foo: 'bar' }); h['moo'] = 'car'",
ref: 'Object/extended'
},

@@ -330,7 +357,9 @@ {

name: 'toObject',
message: 'Sugar extended objects do not have a "toObject" method, as they already behave like vanilla objects.'
message: 'Sugar extended objects do not have a "toObject" method, as they already behave like vanilla objects.',
ref: 'Object/extended'
},
{
name: 'toTemplateReplacements',
message: 'Sugar extended objects do not have a "toTemplateReplacements" method.\nThis method is not necessary as extended objects already behave like vanilla objects.'
message: 'Sugar extended objects do not have a "toTemplateReplacements" method.\nThis method is not necessary as extended objects already behave like vanilla objects.',
ref: 'Object/extended'
},

@@ -342,2 +371,3 @@ {

recommend_after: "var h = Object.extended({ foo: 'bar' }); delete h.foo",
ref: 'Object/extended'
},

@@ -348,3 +378,4 @@ {

recommend_before: "new Hash({ foo: 'bar' }).merge({ moo: 'car' })",
recommend_after: "Object.extended({ foo: 'bar' }).merge({ moo: 'car' })"
recommend_after: "Object.extended({ foo: 'bar' }).merge({ moo: 'car' })",
ref: 'Object/merge'
},

@@ -365,2 +396,3 @@ /***

class_methods: [
/* Not true anymore... deep is false by default
{

@@ -380,7 +412,9 @@ name: 'clone',

},
*/
{
name: 'extend',
message: 'Object.extend does not exist in Sugar. Use Object.merge instead:',
recommend_before: "Object.extend( { a: 1 }, { b: 2 })",
recommend_after: "Object.merge( { a: 1 }, { b: 2 })",
message: 'Object.extend exists in Sugar as Object.merge instead:',
recommend_before: "Object.extend({ a: 1 }, { b: 2 })",
recommend_after: "Object.merge({ a: 1 }, { b: 2 })",
ref: 'Object/merge'
},

@@ -397,3 +431,4 @@ {

recommend_before: "Object.isHash({ a: 1 })",
recommend_after: "Object.isObject({ a: 1 })"
recommend_after: "Object.isObject({ a: 1 })",
ref: 'Object/isObject'
},

@@ -421,2 +456,3 @@ {

* Object.values exists and is identical
* Object.clone exists and will not break
*

@@ -435,5 +471,6 @@ * Object.isElement is for DOM

name: 'from',
message: 'Array.from does not exist in Sugar. Object.merge can accomplish similar functionality:',
recommend_before: "Array.from({ 0: 'a', 1: 'b', 2: 'c' })",
recommend_after: "Object.merge([], { 0: 'a', 1: 'b', 2: 'c' })",
message: 'Array.from exists in Sugar as Array.create.\nBe aware, however, that when a Javascript primitive is passed, it will simply be added to the array.\nIf, for example, you need a string to be split into the array, then use the standard String#split instead. The most common use of this method, converting an arguments object into an actual array, will work, however:',
recommend_before: "Array.from(arguments)",
recommend_after: "Array.create(arguments)",
ref: 'Array.create'
}

@@ -447,2 +484,3 @@ ],

recommend_after: "[1,2,3].map(function(n){ return n * 2; })",
ref: 'Array/map'
},

@@ -454,2 +492,3 @@ {

recommend_after: "[1,2,3].find(function(n){ return n > 1; })",
ref: 'Array/find'
},

@@ -465,3 +504,4 @@ {

recommend_after: "['a','b','c'].each(function(){}.bind('context'))",
one_time_warning: 'Caution: If a callback passed to Array#each returns false, it will break out of the loop.'
one_time_warning: 'Caution: If a callback passed to Array#each returns false, it will break out of the loop.',
ref: 'Function/bind'
},

@@ -472,3 +512,4 @@ {

recommend_before: "[1,2,3,4].eachSlice(2, function(){})",
recommend_after: "[1,2,3,4].inGroupsOf(2).each(function(){})"
recommend_after: "[1,2,3,4].inGroupsOf(2).each(function(){})",
ref: 'Array/inGroupsOf'
},

@@ -479,3 +520,4 @@ {

recommend_before: "[1,2,3].entries()",
recommend_after: "[1,2,3].clone()"
recommend_after: "[1,2,3].clone()",
ref: 'Array/clone'
},

@@ -490,3 +532,4 @@ {

recommend_before: "['a','b','c'].find(function(){}, 'context')",
recommend_after: "['a','b','c'].find(function(){}.bind('context'))"
recommend_after: "['a','b','c'].find(function(){}.bind('context'))",
ref: 'Function/bind'
},

@@ -501,3 +544,4 @@ {

recommend_before: "['a','b','c'].findAll(function(){}, 'context')",
recommend_after: "['a','b','c'].findAll(function(){}.bind('context'))"
recommend_after: "['a','b','c'].findAll(function(){}.bind('context'))",
ref: 'Function/bind'
},

@@ -508,3 +552,4 @@ {

recommend_before: "['a','b','c'].grep(/[ab]/)",
recommend_after: "['a','b','c'].findAll(/[ab]/)"
recommend_after: "['a','b','c'].findAll(/[ab]/)",
ref: 'Array/findAll'
},

@@ -518,3 +563,4 @@ {

recommend_before: "[1,2,3].include(1)",
recommend_after: "[1,2,3].has(1)"
recommend_after: "[1,2,3].has(1)",
ref: 'Array/has'
},

@@ -531,12 +577,11 @@ {

recommend_before: "['hello','world'].invoke('toUpperCase')",
recommend_after: "['hello','world'].map('toUpperCase')"
recommend_after: "['hello','world'].map('toUpperCase')",
ref: 'Array/map'
},
{
name: 'max',
condition: function(f) {
return arguments.length > 0;
},
message: 'Use caution when using Enumerable#max:\n\n(1) Sugar will return an array of maximum values (as there can be more than one), where Prototype only returns the first value.\n(2) When using iterators, Prototype will return the value compared, where Sugar will return the actual array element itself.\n(3) Finally, Sugar does not allow a context to be passed.',
message: 'Use caution when using Enumerable#max:\n\n(1) Sugar will return an array of maximum values (as there can be more than one), where Prototype only returns the first value.\n(2) When using iterators, Prototype will return the value compared, where Sugar will return the actual array element itself.\n(3) Finally, Sugar does not allow a context to be passed. Use Function#bind instead to bind context.',
recommend_before: "[{ a: 5 },{ a: 10 }].max(function(el){ return el['a']; }, 'context')",
recommend_after: "[{ a: 5 },{ a: 10 }].max(function(el){ return el['a']; }.bind('context')).first().a"
recommend_after: "[{ a: 5 },{ a: 10 }].max(function(el){ return el['a']; }.bind('context')).first().a",
ref: 'Array/max'
},

@@ -547,18 +592,18 @@ {

recommend_before: "[1,2,3].member(1)",
recommend_after: "[1,2,3].has(1)"
recommend_after: "[1,2,3].has(1)",
ref: 'Array/has'
},
{
name: 'min',
condition: function(f) {
return arguments.length > 0;
},
message: 'Use caution when using Enumerable#min:\n\n(1) Sugar will return an array of minimum values (as there can be more than one), where Prototype only returns the first value.\n(2) When using iterators, Prototype will return the value compared, where Sugar will return the actual array element itself.\n(3) Finally, Sugar does not allow a context to be passed.',
recommend_before: "[{ a: 5 },{ a: 10 }].min(function(el){ return el['a']; }, 'context')",
recommend_after: "[{ a: 5 },{ a: 10 }].min(function(el){ return el['a']; }.bind('context')).first().a"
recommend_after: "[{ a: 5 },{ a: 10 }].min(function(el){ return el['a']; }.bind('context')).first().a",
ref: 'Array/min'
},
{
name: 'partition',
message: "Enumerable#partition does not exist in Sugar.\nArray#group however has similar functionality, and may be a suitable alternative.\nIt will create a hash with keys based on the return values of the iterator, with each grouping as the value.\nInstead of accessing the split array, you can access the hash by these keys.\nThis method has the added advantage that it can also split into more than two groups.",
message: "Enumerable#partition does not exist in Sugar.\nArray#groupBy however has similar functionality, and may be a suitable alternative.\nIt will create a hash with keys based on the return values of the iterator, with each grouping as the value.\nInstead of accessing the split array, you can access the hash by these keys.\nThis method has the added advantage that it can also split into more than two groups.",
recommend_before: "[1,2,3,4,5,6].partition(function(n){ return n % 2 === 0; })",
recommend_after: "[1,2,3,4,5,6].group(function(n){ return n % 2 === 0 ? 'even' : 'odd'; })"
recommend_after: "[1,2,3,4,5,6].group(function(n){ return n % 2 === 0 ? 'even' : 'odd'; })",
ref: 'Array/groupBy'
},

@@ -569,3 +614,4 @@ {

recommend_before: "['hello','world'].pluck('length')",
recommend_after: "['hello','world'].map('length')"
recommend_after: "['hello','world'].map('length')",
ref: 'Array/map'
},

@@ -576,3 +622,4 @@ {

recommend_before: "[1,2,3].reject(function(n){ n < 3; })",
recommend_after: "[1,2,3].exclude(function(n){ n < 3; })"
recommend_after: "[1,2,3].exclude(function(n){ n < 3; })",
ref: 'Array/exclude'
},

@@ -583,3 +630,4 @@ {

recommend_before: "[1,2,3].select(function(n){ n < 3; })",
recommend_after: "[1,2,3].findAll(function(n){ n < 3; })"
recommend_after: "[1,2,3].findAll(function(n){ n < 3; })",
ref: 'Array/findAll'
},

@@ -594,3 +642,4 @@ {

recommend_before: "[{ a: 5 },{ a: 10 }].sortBy(function(el){ return el['a']; })",
recommend_after: "[{ a: 5 },{ a: 10 }].sortBy(function(el){ return el['a']; }.bind('context'))"
recommend_after: "[{ a: 5 },{ a: 10 }].sortBy(function(el){ return el['a']; }.bind('context'))",
ref: 'Function/bind'
},

@@ -607,3 +656,4 @@ {

recommend_before: "[1,2,3].toArray()",
recommend_after: "[1,2,3].clone()"
recommend_after: "[1,2,3].clone()",
ref: 'Array/clone'
},

@@ -614,3 +664,4 @@ {

recommend_before: "firstNames.zip(lastNames)",
recommend_after: "firstNames.map(function(name, index){ return [name, lastNames[index]]; })"
recommend_after: "firstNames.map(function(name, index){ return [name, lastNames[index]]; })",
ref: 'Array/map'
},

@@ -625,3 +676,4 @@ {

},
message: 'Caution: Array#compact was called on an array that contains NaN values. Sugar will remove these from the array while Prototype leaves them alone:'
message: 'Caution: Array#compact was called on an array that contains NaN values. Sugar will remove these from the array while Prototype leaves them alone:',
ref: 'Array/compact'
},

@@ -647,3 +699,4 @@ {

recommend_before: "array.reverse(false)",
recommend_after: "array.clone().reverse()"
recommend_after: "array.clone().reverse()",
ref: 'Array.clone'
},

@@ -654,3 +707,4 @@ {

recommend_before: "[1,1,1].uniq()",
recommend_after: "[1,1,1].unique()"
recommend_after: "[1,1,1].unique()",
ref: 'Array/unique'
},

@@ -661,3 +715,4 @@ {

recommend_before: "[1,2,3].without(3)",
recommend_after: "[1,2,3].exclude(3)"
recommend_after: "[1,2,3].exclude(3)",
ref: 'Array/exclude'
}

@@ -702,2 +757,3 @@ /***

recommend_after: "var fn = function(one, event) {\n\t // this will be \"bound\"\n\t // one will be 1\n\t // event will be the event (comes last)\n\t}\n\tfn.bind('bound', 1)",
ref: 'Function/bind'
},

@@ -709,8 +765,10 @@ {

recommend_after: "fn.bind(null, 'one', 'two')",
ref: 'Function/bind'
},
{
name: 'defer',
message: 'Function#defer exists in Sugar as Function#lazy.\nWhen no params are passed it will behave precisely the same as calling the function with a timeout of 1 ms.',
message: 'Function#defer exists in Sugar as Function#delay.\nWhen no params are passed it will behave precisely the same as calling the function with a timeout of 1 ms (as with defer):',
recommend_before: "fn.defer()",
recommend_after: "fn.lazy()"
recommend_after: "fn.delay()",
ref: 'Function/delay'
},

@@ -722,2 +780,3 @@ {

recommend_after: "fn.delay(2000)\n\tfn.cancel()",
ref: 'Function/delay'
},

@@ -742,14 +801,28 @@ {

* Function#bind exists and is identical
* Date#toISOString exists and is identical
* Date#toJSON exists and is identical
*
* */
**/
}
];
/***
*
* Date#toISOString exists and is identical
* Date#toJSON exists and is identical
*
* */
var UnderscoreCollisions = [
{
module: '_',
class_methods: [
{
name: 'map',
message: '_.map exists natively in modern browsing engines.\nSugar provides this method when it is not supported, and additionally augments it to allow passing a string as a shortcut.',
recommended_before: '_.map([1,2,3], function(a){ return a * 2; })',
recommended_after: '[1,2,3].map(function(a){ return a * 2; })',
ref: 'Array/map'
}
]
}
];
var TS = ' ';
var stackLevelOffset;

@@ -761,5 +834,6 @@ var warn = function(message, level, skipMeta, docs) {

if(stack) {
match = stack.split('\n')[level].match(/@(.+):(\d+)$/);
match = stack.split(/@|at/m)[level].match(/(http.+):(\d+)(?::(\d+))?/);
file = match[1];
if(file.match(/prototype[^/]+$/)) {
console.info('wats', file);
if(file.match(/prototype[^/]+$/) || file.match(/analyzer\.js/)) {
// Assumed to be internally called method, so don't display warnings in this case.

@@ -772,3 +846,3 @@ return;

if(docs){
message += '\n----------- Docs: ' + docs + ' ---------';
message += '\n----------- Docs: http://sugarjs.com/api/' + docs.toLowerCase() + ' ---------';
}

@@ -801,2 +875,3 @@ }

} else {
if(!window[module]) window[module] = function(){};
m = instance ? window[module].prototype : window[module];

@@ -810,3 +885,2 @@ }

if(collision.recommend_before){
//message += '\n\nSugar equivalent...\n';
message += '\n\n';

@@ -817,4 +891,3 @@ message += '\nPrototype: ' + collision.recommend_before;

}
var ref = 'http://sugarjs.com/api/#!/' + module + '#' + (collision.alternate || collision.name);
warn(message, 3, false, ref);
warn(message, 3, false, collision.ref);
}

@@ -846,3 +919,2 @@ if(collision.one_time_warning && !collision.warned) {

var initialize = function() {

@@ -857,4 +929,4 @@ var welcome =

wrapMethods(PrototypeCollisions);
} else if(typeof Mootools != 'undefined') {
wrapMethods(MootoolsCollisions);
} else if(typeof _ != 'undefined') {
wrapMethods(UnderscoreCollisions);
}

@@ -861,0 +933,0 @@ }

@@ -271,2 +271,3 @@

numbers: ['一','二','三','四','五','六','七','八','九','十'],
optionals: ['日|号'],
numbersAreDigits: true,

@@ -291,5 +292,5 @@ outputFormat: '{yyyy}年{M}月{d}日',

'{shift}{unit=5}{weekday}',
'{year}年{month?}月?{date?}日?',
'{month}月{date?}日?',
'{date}日'
'{year}年{month?}月?{date?}{1}',
'{month}月{date?}{1}',
'{date}{1}'
]

@@ -305,2 +306,3 @@ });

numbersAreDigits: true,
optionals: ['日|號'],
outputFormat: '{yyyy}年{M}月{d}日',

@@ -326,5 +328,5 @@ pastFormat: '{num}{unit}{sign}',

'{shift}{unit=5}{weekday}',
'{year}年{month?}月?{date?}日?',
'{month}月{date?}日?',
'{date}日'
'{year}年{month?}月?{date?}{1}',
'{month}月{date?}{1}',
'{date}{1}'
]

@@ -331,0 +333,0 @@ });

{
"name": "sugar",
"version": "1.0.0",
"version": "1.1.0",
"description": "A Javascript library for working with native objects.",

@@ -5,0 +5,0 @@ "keywords": ["functional", "utility", "ender"],

@@ -20,2 +20,3 @@

require('../sugar/es5.js');
require('../sugar/equals.js');
require('../sugar/date_zh_cn.js')

@@ -22,0 +23,0 @@ require('../sugar/date_zh_tw.js')

@@ -6,4 +6,2 @@ test('Dates | German', function () {

dateEqual(Date.create('15. Mai 2011'), new Date(2011, 4, 15), 'Date#create | basic German date');

@@ -10,0 +8,0 @@ dateEqual(Date.create('Dienstag, 5. Januar 2012'), new Date(2012, 0, 5), 'Date#create | German | 2012-01-05');

@@ -16,2 +16,4 @@ test('Dates | Simplified Chinese', function () {

dateEqual(Date.create('二十五日'), new Date(now.getFullYear(), now.getMonth(), 25), 'Date#create | Simplified Chinese | the 25th');
dateEqual(Date.create('二十五号'), new Date(now.getFullYear(), now.getMonth(), 25), 'Date#create | Simplified Chinese | 号 should be understood as well');
dateEqual(Date.create('九月二十五号'), new Date(now.getFullYear(), 8, 25), 'Date#create | Simplified Chinese | 9.25');

@@ -18,0 +20,0 @@

@@ -16,2 +16,3 @@ test('Dates | Traditional Chinese', function () {

dateEqual(Date.create('二十五日'), new Date(now.getFullYear(), now.getMonth(), 25), 'Date#create | Traditional Chinese | the 25th');
dateEqual(Date.create('二十五號'), new Date(now.getFullYear(), now.getMonth(), 25), 'Date#create | Simplified Chinese | 號 should be understood as well');

@@ -18,0 +19,0 @@ dateEqual(Date.create('一毫秒前'), getRelativeDate(null, null, null, null, null, null,-1), 'Date#create | Traditional Chinese | one millisecond ago');

@@ -295,3 +295,3 @@

// Array#some
// Array#some

@@ -298,0 +298,0 @@ raisesError(function(){ [].some(); }, 'Array#some | should raise an error when no first param');

test('Function', function () {
var bound,obj,result;

@@ -34,3 +33,3 @@

(function(){
async(function(){
var fn, ref;

@@ -43,5 +42,5 @@ fn = function(one, two) {

equal(typeof ref, 'function', 'Function#delay | returns the function', { prototype: 'number', mootools: 'number' });
})();
});
(function(){
async(function(){
var fn, ref, shouldBeFalse = false;

@@ -59,9 +58,26 @@ fn = function() {

}, 60);
})();
});
// Properly unit testing Function#lazy will probably be a bitch...
// Will have to rethink strategy here.
(function() {
async(function(){
var counter = 0;
var expected = [['maybe','a',1],['baby','b',2],['you lazy','c',3]];
var fn = function(){ counter++; }
fn.delay(50);
fn.delay(10);
setTimeout(function() {
fn.cancel();
}, 30);
setTimeout(function() {
equal(counter, 1, 'Function#cancel | should be able to find the correct timers', { prototype: 0 });
fn.cancel();
}, 60);
});
async(function() {
var counter = 0;
var expected = [['maybe','a',1],['baby','b',2],['you lazy','c',3],['biotch','d',4]];
var fn = (function(one, two) {

@@ -74,10 +90,12 @@ equal([this.toString(), one, two], expected[counter], 'Function#lazy | scope and arguments are correct');

fn.call('you lazy', 'c', 3);
equal(counter, 0, "Function#lazy | hasn't executed yet");
equal(counter, 1, "Function#lazy | should have executed once");
setTimeout(function() {
equal(counter, 3, 'Function#lazy | was executed by 10ms');
}, 10);
})();
fn.call('biotch', 'd', 4);
equal(counter, 4, 'Function#lazy | next execution should be immediate');
}, 100);
});
(function() {
async(function() {
var counter = 0;

@@ -87,11 +105,26 @@ var fn = (function() { counter++; }).lazy();

fn();
fn();
fn.cancel();
setTimeout(function() {
equal(counter, 0, 'Function#lazy | lazy functions can also be canceled');
equal(counter, 1, 'Function#lazy | lazy functions can also be canceled');
}, 10);
})();
});
(function() {
async(function() {
var counter = 0;
var fn = (function() { counter++; }).lazy(0.1);
for(var i = 0; i < 20; i++) {
fn();
}
setTimeout(function() {
equal(counter, 20, 'Function#lazy | lazy (throttled) functions can have a [wait] value of < 1ms');
}, 100);
});
async(function() {
var counter = 0;
var fn = (function() { counter++; }).lazy(0.1, 10);

@@ -103,7 +136,16 @@ for(var i = 0; i < 50; i++) {

equal(counter, 10, 'Function#lazy | lazy functions have an upper threshold');
equal(fn.timers.length, 0, 'Function#lazy | timers should be cleared');
}, 50);
})();
});
async(function() {
var counter = 0;
var fn = (function() { counter++; }).lazy(0.1, 1);
for(var i = 0; i < 50; i++) {
fn();
}
setTimeout(function() {
equal(counter, 1, 'Function#lazy | lazy functions with a limit of 1 WILL still execute');
}, 50);
});

@@ -114,8 +156,3 @@

// Giving this it's own scope + a timeout here as it seems to make this
// temperamental test happier to run after other execution (GC?) has finished.
/*
* I can't for the life of me get these tests not to fail randomly, so come back here when we have more bandwidth to work on it.
setTimeout(function(){
async(function(){
var fn, ret, counter = 0, expected = [['leia', 5],['han solo', 7]];

@@ -125,3 +162,3 @@ var fn = (function(one){

counter++;
}).debounce(10);
}).debounce(30);

@@ -148,6 +185,5 @@ fn.call('3p0', 1);

}, 500);
}, 1);
*/
});
setTimeout(function(){
async(function(){
var fn, ret, counter = 0, expected = [['3p0', 1],['luke', 6]];

@@ -177,3 +213,3 @@ var fn = (function(one){

}, 200);
}, 1);
});

@@ -184,3 +220,3 @@

(function() {
async(function() {
var fn, ret, counter = 0, i = 1;

@@ -197,3 +233,3 @@ fn = (function() {

equal(counter, 2, 'Function#after | calls a function only after a certain number of calls');
})();
});

@@ -203,3 +239,3 @@

(function() {
async(function() {
var fn, obj = { foo:'bar' }, counter = 0;

@@ -221,6 +257,6 @@ fn = (function(one, two) {

equal(counter, 1, 'Function#once | counter is only incremented once');
})();
});
(function() {
async(function() {
var fn, counter = 0;

@@ -236,9 +272,32 @@ fn = (function(one, two) {

equal(counter, 1, 'Function#once | returning undefined will not affect the number of calls');
})();
});
// Function#fill
Number.prototype.two = Number.prototype.format.fill(2);
equal((18).two(), '18.00', 'Function#fill | 18');
equal((9999).two(), '9,999.00', 'Function#fill | 9,999.00');
equal((9999).two(' '), '9 999.00', 'Function#fill | 9 999.00');
equal((9999).two('+', '-'), '9+999-00', 'Function#fill | 9+999-00');
Number.prototype.euro = Number.prototype.format.fill(undefined, '.', ',');
equal((9999.77).euro(), '9.999,77', 'Function#fill | no params | 9.999,77');
equal((9999.77).euro(0), '10.000', 'Function#fill | 0 | 9.999');
equal((9999.77).euro(1), '9.999,8', 'Function#fill | 1 | 9.999,8');
equal((9999.77).euro(2), '9.999,77', 'Function#fill | 2 | 9.999,77');
equal((9999.77).euro(3), '9.999,770', 'Function#fill | 3 | 9.999,777');
Number.prototype.noop = Number.prototype.format.fill();
equal((1000).noop(3, ' ', ','), '1 000,000', 'Function#fill | noop | 1 000,000');
equal((1000).noop(4, ' ', ','), '1 000,0000', 'Function#fill | noop | 1 000,0000');
equal((1000).noop(5, ' ', ','), '1 000,00000', 'Function#fill | noop | 1 000,00000');
});

@@ -220,10 +220,49 @@

equal((1000).format(' '), '1 000', 'Number#format | 1000')
equal((1532587).format(' '), '1 532 587', 'Number#format | larger number')
equal((1532587.5752).format(' ', ','), '1 532 587,5752', 'Number#format | larger number with decimal')
equal((1000).format(null, ' '), '1 000', 'Number#format | 1000')
equal((1532587).format(null, ' '), '1 532 587', 'Number#format | larger number')
equal((1532587.5752).format(null, ' ', ','), '1 532 587,5752', 'Number#format | larger number with decimal')
equal((9999999.99).format(), '9,999,999.99', 'Number#format | Standard');
equal((9999999.99).format('.',','), '9.999.999,99', 'Number#format | Euro style!');
equal((9999999.99).format(null, '.',','), '9.999.999,99', 'Number#format | Euro style!');
equal((1).format(2), '1.00', 'Number#format | to 2 places')
equal((10).format(2), '10.00', 'Number#format | to 2 places')
equal((100).format(2), '100.00', 'Number#format | to 2 places')
equal((1000).format(2), '1,000.00', 'Number#format | to 2 places')
equal((10000).format(2), '10,000.00', 'Number#format | to 2 places')
equal((100000).format(2), '100,000.00', 'Number#format | to 2 places')
equal((1000000).format(2), '1,000,000.00', 'Number#format | to 2 places')
equal((1).format(4), '1.0000', 'Number#format | to 4 places')
equal((10).format(4), '10.0000', 'Number#format | to 4 places')
equal((100).format(4), '100.0000', 'Number#format | to 4 places')
equal((1000).format(4), '1,000.0000', 'Number#format | to 4 places')
equal((10000).format(4), '10,000.0000', 'Number#format | to 4 places')
equal((100000).format(4), '100,000.0000', 'Number#format | to 4 places')
equal((1000000).format(4), '1,000,000.0000', 'Number#format | to 4 places')
equal((-1).format(2), '-1.00', 'Number#format | to 2 places')
equal((-10).format(2), '-10.00', 'Number#format | to 2 places')
equal((-100).format(2), '-100.00', 'Number#format | to 2 places')
equal((-1000).format(2), '-1,000.00', 'Number#format | to 2 places')
equal((-10000).format(2), '-10,000.00', 'Number#format | to 2 places')
equal((-100000).format(2), '-100,000.00', 'Number#format | to 2 places')
equal((-1000000).format(2), '-1,000,000.00', 'Number#format | to 2 places')
equal((-1).format(4), '-1.0000', 'Number#format | to 4 places')
equal((-10).format(4), '-10.0000', 'Number#format | to 4 places')
equal((-100).format(4), '-100.0000', 'Number#format | to 4 places')
equal((-1000).format(4), '-1,000.0000', 'Number#format | to 4 places')
equal((-10000).format(4), '-10,000.0000', 'Number#format | to 4 places')
equal((-100000).format(4), '-100,000.0000', 'Number#format | to 4 places')
equal((-1000000).format(4), '-1,000,000.0000', 'Number#format | to 4 places')
equal((2.435).format(2), '2.44', 'Number#format | 2.44')
equal((553599.435).format(2), '553,599.44', 'Number#format | 553,599.44')
equal((553599.435).format(1), '553,599.4', 'Number#format | 553,599.4')
equal((553599.435).format(0), '553,599', 'Number#format | 553,599')
equal((553599.435).format(-1), '553,600', 'Number#format | 553,600')
equal((553599.435).format(-2), '553,600', 'Number#format | 553,600')
equal((553599.435).format(-3), '554,000', 'Number#format | 553,600')
equal((553599.435).format(-4), '550,000', 'Number#format | 550,000')
equal((553599.435).format(-5), '600,000', 'Number#format | 600,000')
raisesError(function(){ (1000).format(2, 5) }, 'Number#format | should raise an error if a digit is given for the thousands separator');
equal((1).pad(0), '1', 'Number#pad | 1 no padding')

@@ -230,0 +269,0 @@ equal((1).pad(1), '1', 'Number#pad | 1 padded to 1 place')

@@ -236,2 +236,3 @@ test('Object', function () {

equal(Object.merge({ foo: 'bar' }, 'wear', 8, null), { foo: 'bar' }, 'Object.merge | merge multi invalid', { mootools: { foo: 'bar', wear: 8 } });
equal(Object.merge([1,2,3,4], [4,5,6]), [4,5,6,4], 'Object.merge | arrays should also be mergeable');

@@ -249,2 +250,7 @@

skipEnvironments(['prototype','mootools'], function() {
equal(Object.clone('hardy'), 'hardy', 'Object.clone | clone on a string');
});
equal(Object.clone(undefined), undefined, 'Object.clone | clone on undefined', { prototype: {} });
equal(Object.clone(null), null, 'Object.clone | clone on null', { prototype: {} });
equal(Object.clone({ foo: 'bar' }), { foo: 'bar' }, 'Object.clone | basic clone');

@@ -318,5 +324,7 @@ equal(Object.clone({ foo: 'bar', broken: 1, wear: null }), { foo: 'bar', broken: 1, wear: null }, 'Object.clone | complex clone');

equal(obj2.foo.jumpy, 'hump', 'Object#clone | clone is shallow');
equal(obj3.foo.jumpy, 'jump', 'Object#clone | clone is deep');
equal(obj3.foo.jumpy, 'jump', 'Object#clone | clone is deep', { prototype: 'hump' });
equal(obj2.keys().sort(), ['broken','foo'], 'Object#clone | cloned objects are themselves extended');
skipEnvironments(['prototype','mootools'], function() {
equal(obj2.keys().sort(), ['broken','foo'], 'Object#clone | cloned objects are themselves extended');
});

@@ -333,3 +341,3 @@ obj1 = Object.extended({

equal(obj1.foo.bar, [1,'b',3], 'Object#clone | original object is modified');
equal(obj3.foo.bar, [1,2,3], 'Object#clone | cloned object is not modified');
equal(obj3.foo.bar, [1,2,3], 'Object#clone | cloned object is not modified', { prototype: [1,'b',3] });

@@ -350,9 +358,9 @@

equal(Object.equals({ broken: 'wear' }, { broken: 'wear' }), true, 'Object.equals | objects are equal');
equal(Object.equals({ broken: 'wear' }, { broken: 'jumpy' }), false, 'Object.equals | objects are not equal');
equal(Object.equals({}, {}), true, 'Object.equals | empty objects are equal');
equal(Object.equals({}, { broken: 'wear' }), false, 'Object.equals | 1st empty');
equal(Object.equals({ broken: 'wear' }, {}), false, 'Object.equals | 2nd empty');
equal(Object.equal({ broken: 'wear' }, { broken: 'wear' }), true, 'Object.equal | objects are equal');
equal(Object.equal({ broken: 'wear' }, { broken: 'jumpy' }), false, 'Object.equal | objects are not equal');
equal(Object.equal({}, {}), true, 'Object.equal | empty objects are equal');
equal(Object.equal({}, { broken: 'wear' }), false, 'Object.equal | 1st empty');
equal(Object.equal({ broken: 'wear' }, {}), false, 'Object.equal | 2nd empty');
equal(Object.equals({x: 1, y: undefined}, {x: 1, z: 2}), false, 'Object.equals | undefined keys');
equal(Object.equal({x: 1, y: undefined}, {x: 1, z: 2}), false, 'Object.equal | undefined keys');

@@ -367,3 +375,10 @@

var obj1 = { foo: 'bar' };
equal(Object.equal({ a: obj1, b: obj1 }, { a: obj1, b: obj1 }), true, 'Object.equal | multiple references will not choke');
var obj1 = { foo: 'bar' };
obj1.moo = obj1;
equal(Object.equal(obj1, { foo: 'bar', moo: obj1 }), true, 'Object.equal | cyclical references handled');
equal(Object.equal(undefined, 'one'), false, 'Object.equal | string to undefined');
// Enabling native object methods

@@ -370,0 +385,0 @@

@@ -37,11 +37,16 @@ test('RegExp', function () {

equal(n.global, false, 'RegExp#removeFlag');
equal(n.ignoreCase, true, 'RegExp#removeFlag');
equal(n.multiline, true, 'RegExp#removeFlag');
equal(n.global, false, 'RegExp#removeFlag | global');
equal(n.ignoreCase, true, 'RegExp#removeFlag | ignoreCase');
equal(n.multiline, true, 'RegExp#removeFlag | multiline');
equal(r.global, true, 'RegExp#removeFlag | initial regex is untouched');
equal(r.ignoreCase, true, 'RegExp#removeFlag | initial regex is untouched');
equal(r.multiline, true, 'RegExp#removeFlag | initial regex is untouched');
equal(r.global, true, 'RegExp#removeFlag | initial regex is untouched | global');
equal(r.ignoreCase, true, 'RegExp#removeFlag | initial regex is untouched | ignoreCase');
equal(r.multiline, true, 'RegExp#removeFlag | initial regex is untouched | multiline');
// RegExp#getFlags
equal(/foobar/gim.getFlags(), 'gim', 'RegExp#getFlags');
});

@@ -28,3 +28,3 @@ $(document).ready(function() {

func = function(context, message) { equals(this, context, message); };
func = function(context, message) { equals(this == context, true, message); };
_.bind(func, 0, 0, 'can bind a function to `0`')();

@@ -31,0 +31,0 @@ _.bind(func, '', '', 'can bind a function to an empty string')();

@@ -1,2 +0,2 @@

// Underscore.js 1.1.7
// Underscore.js 1.2.1
// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.

@@ -51,8 +51,15 @@ // Underscore is freely distributable under the MIT license.

// Export the Underscore object for **CommonJS**, with backwards-compatibility
// for the old `require()` API. If we're not in CommonJS, add `_` to the
// global object.
if (typeof module !== 'undefined' && module.exports) {
module.exports = _;
_._ = _;
// Export the Underscore object for **Node.js** and **"CommonJS"**, with
// backwards-compatibility for the old `require()` API. If we're not in
// CommonJS, add `_` to the global object.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else if (typeof define === 'function' && define.amd) {
// Register as a named module with AMD.
define('underscore', function() {
return _;
});
} else {

@@ -64,3 +71,3 @@ // Exported as a string, for Closure Compiler "advanced" mode.

// Current version.
_.VERSION = '1.1.7';
_.VERSION = '1.2.1';

@@ -203,4 +210,4 @@ // Collection Functions

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

@@ -226,2 +233,3 @@ return found;

if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return -Infinity;
var result = {computed : -Infinity};

@@ -238,2 +246,3 @@ each(obj, function(value, index, list) {

if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return Infinity;
var result = {computed : Infinity};

@@ -247,2 +256,17 @@ each(obj, function(value, index, list) {

// Shuffle an array.
_.shuffle = function(obj) {
var shuffled = [], rand;
each(obj, function(value, index, list) {
if (index == 0) {
shuffled[0] = value;
} else {
rand = Math.floor(Math.random() * (index + 1));
shuffled[index] = shuffled[rand];
shuffled[rand] = value;
}
});
return shuffled;
};
// Sort the object's values by a criterion produced by an iterator.

@@ -261,5 +285,7 @@ _.sortBy = function(obj, iterator, context) {

// Groups the object's values by a criterion produced by an iterator
_.groupBy = function(obj, iterator) {
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = function(obj, val) {
var result = {};
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
each(obj, function(value, index) {

@@ -308,2 +334,16 @@ var key = iterator(value, index);

// Returns everything but the last entry of the array. Especcialy useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N. The **guard** check allows it to work with
// `_.map`.
_.initial = function(array, n, guard) {
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) {
return (n != null) && !guard ? slice.call(array, array.length - n) : array[array.length - 1];
};
// Returns everything but the first entry of the array. Aliased as `tail`.

@@ -317,7 +357,2 @@ // Especially useful on the arguments object. Passing an **index** will return

// Get the last element of an array.
_.last = function(array) {
return array[array.length - 1];
};
// Trim out all falsy values from an array.

@@ -329,5 +364,5 @@ _.compact = function(array) {

// Return a completely flattened version of an array.
_.flatten = function(array) {
_.flatten = function(array, shallow) {
return _.reduce(array, function(memo, value) {
if (_.isArray(value)) return memo.concat(_.flatten(value));
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
memo[memo.length] = value;

@@ -362,3 +397,3 @@ return memo;

_.union = function() {
return _.uniq(_.flatten(arguments));
return _.uniq(_.flatten(arguments, true));
};

@@ -411,3 +446,2 @@

// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.

@@ -447,2 +481,5 @@ _.lastIndexOf = function(array, item) {

// Reusable constructor function for prototype setting.
var ctor = function(){};
// Create a function bound to a given object (assigning `this`, and arguments,

@@ -452,7 +489,14 @@ // optionally). Binding with arguments is also known as `curry`.

// We check for `func.bind` first, to fail fast when `func` is undefined.
_.bind = function(func, obj) {
_.bind = function bind(func, context) {
var bound, args;
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
var args = slice.call(arguments, 2);
return function() {
return func.apply(obj, args.concat(slice.call(arguments)));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
return bound = function() {
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
};

@@ -493,22 +537,21 @@ };

// Internal function used to implement `_.throttle` and `_.debounce`.
var limit = function(func, wait, debounce) {
var timeout;
// 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);
return function() {
var context = this, args = arguments;
context = this; args = arguments;
var throttler = function() {
timeout = null;
func.apply(context, args);
finishThrottle();
};
if (debounce) clearTimeout(timeout);
if (debounce || !timeout) timeout = setTimeout(throttler, wait);
if (!timeout) timeout = setTimeout(throttler, wait);
if (!throttling) func.apply(context, args);
if (finishThrottle) finishThrottle();
throttling = true;
};
};
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time.
_.throttle = function(func, wait) {
return limit(func, wait, false);
};
// Returns a function, that, as long as it continues to be invoked, will not

@@ -518,3 +561,12 @@ // be triggered. The function will be called after it stops being called for

_.debounce = function(func, wait) {
return limit(func, wait, true);
var timeout;
return function() {
var context = this, args = arguments;
var throttler = function() {
timeout = null;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(throttler, wait);
};
};

@@ -563,3 +615,2 @@

// Object Functions

@@ -614,2 +665,3 @@ // ----------------

_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);

@@ -626,43 +678,89 @@ };

// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
// Check object identity.
if (a === b) return true;
// Different types?
var atype = typeof(a), btype = typeof(b);
if (atype != btype) return false;
// Basic equality test (watch out for coercions).
if (a == b) return true;
// One is falsy and the other truthy.
if ((!a && b) || (a && !b)) return false;
// 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;
// One of them implements an isEqual()?
if (a.isEqual) return a.isEqual(b);
if (b.isEqual) return b.isEqual(a);
// Check dates' integer values.
if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
// Both are NaN?
if (_.isNaN(a) && _.isNaN(b)) return false;
// Compare regular expressions.
if (_.isRegExp(a) && _.isRegExp(b))
return a.source === b.source &&
a.global === b.global &&
a.ignoreCase === b.ignoreCase &&
a.multiline === b.multiline;
// If a is not an object by this point, we can't handle it.
if (atype !== 'object') return false;
// Check for different array lengths before comparing contents.
if (a.length && (a.length !== b.length)) return false;
// Nothing else worked, deep compare the contents.
var aKeys = _.keys(a), bKeys = _.keys(b);
// Different object sizes?
if (aKeys.length != bKeys.length) return false;
// Recursive comparison of contents.
for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
return true;
// 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
// 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
// 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;
}
}
// 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;
}
// 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) {
return eq(a, b, []);
};
// Is a given array or object empty?
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {

@@ -682,3 +780,3 @@ if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;

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

@@ -692,9 +790,15 @@

// Is a given variable an arguments object?
_.isArguments = function(obj) {
return !!(obj && hasOwnProperty.call(obj, 'callee'));
};
if (toString.call(arguments) == '[object Arguments]') {
_.isArguments = function(obj) {
return toString.call(obj) == '[object Arguments]';
};
} else {
_.isArguments = function(obj) {
return !!(obj && hasOwnProperty.call(obj, 'callee'));
};
}
// Is a given value a function?
_.isFunction = function(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
return toString.call(obj) == '[object Function]';
};

@@ -704,3 +808,3 @@

_.isString = function(obj) {
return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
return toString.call(obj) == '[object String]';
};

@@ -710,8 +814,8 @@

_.isNumber = function(obj) {
return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
return toString.call(obj) == '[object Number]';
};
// Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
// that does not equal itself.
// Is the given value `NaN`?
_.isNaN = function(obj) {
// `NaN` is the only value for which `===` is not reflexive.
return obj !== obj;

@@ -722,3 +826,3 @@ };

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

@@ -728,3 +832,3 @@

_.isDate = function(obj) {
return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
return toString.call(obj) == '[object Date]';
};

@@ -734,3 +838,3 @@

_.isRegExp = function(obj) {
return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
return toString.call(obj) == '[object RegExp]';
};

@@ -768,2 +872,7 @@

// 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

@@ -789,3 +898,4 @@ // they're correctly added to the OOP wrapper as well.

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

@@ -802,2 +912,5 @@

.replace(/'/g, "\\'")
.replace(c.escape, function(match, code) {
return "',_.escape(" + code.replace(/\\'/g, "'") + "),'";
})
.replace(c.interpolate, function(match, code) {

@@ -804,0 +917,0 @@ return "'," + code.replace(/\\'/g, "'") + ",'";

@@ -106,4 +106,5 @@

}
var s = e.stack.split('\n');
var match = s[level].match(/\/(.+?):(\d+)(?:(\d+))?/);
var s = e.stack.split(/@|at/m);
var match = s[level].match(/(http.+):(\d+)(?::(\d+))?/);
if(!match) match = [];
return { file: match[1], line: match[2] };

@@ -242,1 +243,7 @@ }

// This method has 2 benefits:
// 1. It gives asynchronous functions their own scope so vars can't be overwritten later by other asynchronous functions
// 2. It runs the tests after the CPU is free decreasing the chance of timing based errors.
async = function(fn) {
setTimeout(fn, 200);
}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc