Script debugger reports "operation not allowed" - javascript

I have a simple project that does some generic array calculations and returns the result in a grid. I needed a short way to scan an array for the maximum value and tried using this:
var max = Math.max.bind( Math.max );
var vector_max = Function.apply.bind( max, null );
Now, this works great when I am not debugging. But, if I wrap a test function around any statement, like, say:
function tester() {
var r = 0;
return r;
}
..., set a breakpoint anywhere in this function, and click debug, I get an error:
"Typeerror: This operation is not allowed. (line XXX, file xxx)"
This happens even in a completely new script attached to an empty sheet. Of course, Google has no documentation on their script debugger and no references to any limitations, so, I am totally in the dark.
Any ideas?

I can also reproduce this. It indeed seems like a bug in the debugger! :)
You should report this in the Apps Script issue tracker. And in the mean time use another implementation for your vector_max function to debug your code. For example:
function vector_max(a){ return a.reduce(function(r,v){ return r < v ? v : r; }, -Infinity); }

Related

How can I decode a javascript snippet that is obfuscated with what appears to be a unicode or regex string with an eval() function?

So I came across an interesting piece of javascript that I can't quit figure out. It appears to me at first to be either regex function or a unicode string, that is then passed onto an eval function for processing. I have been trying for quite some time to decode it, but I don't seem to be making any headway. I'm hoping someone might be able to tell me what is going on here, and maybe show me how to decode it.
Edit: So it turns out that the code I posted before was flawed from a previous decoding attempt. This is the corrected code.
$(window).load(function() {
var d = '960';
var d1 = '960';
var q = 'u94';
var uw = $("#u94");
var _0xf924 = ["1m B=[\"\\a\\l\\v\\e\\k\\t\\d\\s\\9\\a\\a\\9\\a\\e\\9\\h\\g\\9\\i\\j\\9\\a\\g\\9\\a\\e\\9\\a\\g\\9\\f\\l\\9\\a\\j\\9\\h\\h\\9\\i\\b\\9\\h\\e\\9\\a\\k\\9\\a\\i\\9\\h\\e\\9\\h\\k\\9\\b\\b\\l\\9\\k\\b\\9\\a\\a\\9\\a\\e\\9\\h\\g\\9\\i\\j\\9\\a\\g\\9\\a\\e\\9\\a\\g\\9\\f\\l\\9\\a\\j\\9\\h\\h\\9\\i\\b\\9\\h\\e\\9\\k\\g\\9\\k\\j\\9\\h\\e\\9\\h\\k\\s\\m\\s\\9\\a\\g\\9\\a\\e\\9\\a\\g\\9\\f\\l\\9\\a\\j\\s\\m\\s\\9\\a\\f\\9\\a\\g\\9\\a\\g\\9\\a\\k\\s\\m\\s\\9\\b\\g\\f\\9\\f\\j\\9\\a\\f\\9\\h\\b\\9\\a\\j\\s\\m\\s\\9\\h\\g\\9\\a\\e\\9\\f\\e\\9\\a\\e\\9\\h\\l\\9\\f\\l\\9\\a\\j\\s\\m\\s\\9\\h\\f\\9\\f\\e\\9\\f\\e\\s\\m\\s\\9\\h\\a\\9\\h\\b\\9\\a\\k\\9\\f\\j\\9\\a\\j\\9\\f\\l\\9\\a\\j\\9\\f\\k\\s\\m\\s\\9\\b\\b\\g\\9\\a\\e\\9\\f\\i\\9\\a\\a\\s\\m\\s\\9\\h\\a\\9\\b\\j\\l\\9\\i\\i\\9\\a\\g\\9\\a\\g\\9\\a\\h\\9\\f\\i\\9\\i\\j\\9\\a\\g\\9\\a\\e\\9\\a\\g\\9\\f\\l\\9\\a\\j\\9\\h\\h\\9\\i\\b\\9\\k\\h\\9\\a\\k\\9\\a\\i\\9\\k\\h\\9\\h\\k\\9\\b\\b\\l\\9\\k\\b\\9\\h\\a\\9\\b\\j\\l\\9\\i\\i\\9\\a\\g\\9\\a\\g\\9\\a\\h\\9\\f\\i\\9\\i\\j\\9\\a\\g\\9\\a\\e\\9\\a\\g\\9\\f\\l\\9\\a\\j\\9\\h\\h\\9\\i\\b\\9\\k\\h\\9\\a\\k\\9\\a\\i\\9\\k\\h\\9\\h\\k\\s\\m\\s\\9\\a\\e\\9\\a\\a\\s\\m\\s\\9\\f\\k\\9\\a\\f\\9\\a\\g\\9\\h\\f\\9\\a\\i\\s\\m\\s\\9\\f\\k\\9\\a\\f\\9\\f\\j\\s\\m\\s\\9\\f\\e\\9\\f\\j\\9\\f\\l\\9\\a\\e\\9\\a\\g\\s\\m\\s\\9\\k\\g\\9\\k\\j\\s\\m\\s\\9\\a\\k\\9\\a\\i\\s\\m\\s\\s\\m\\s\\9\\k\\g\\9\\a\\i\\s\\m\\s\\9\\k\\b\\s\\m\\s\\9\\a\\k\\9\\a\\j\\9\\f\\j\\9\\f\\l\\9\\a\\f\\9\\h\\f\\9\\a\\j\\s\\m\\s\\9\\b\\g\\e\\9\\a\\h\\9\\a\\h\\9\\b\\g\\e\\9\\a\\j\\9\\a\\j\\9\\f\\a\\9\\k\\g\\9\\a\\j\\9\\f\\e\\9\\f\\j\\9\\a\\h\\9\\f\\i\\9\\f\\e\\9\\a\\e\\9\\h\\g\\9\\a\\j\\9\\f\\a\\9\\k\\j\\9\\a\\j\\9\\a\\e\\9\\h\\b\\9\\a\\i\\9\\a\\g\\s\\m\\s\\9\\a\\f\\9\\a\\a\\9\\a\\a\\9\\b\\l\\g\\9\\f\\l\\9\\a\\f\\9\\f\\e\\9\\f\\e\\s\\m\\s\\9\\h\\l\\9\\a\\h\\9\\a\\a\\9\\b\\j\\g\\s\\m\\s\\9\\h\\a\\9\\h\\l\\9\\a\\k\\9\\a\\j\\9\\a\\f\\9\\b\\j\\f\\9\\f\\j\\9\\a\\h\\9\\a\\e\\9\\f\\i\\9\\a\\g\\9\\h\\a\\9\\a\\f\\9\\h\\f\\9\\a\\g\\9\\a\\e\\9\\h\\g\\9\\a\\j\\s\\m\\s\\9\\a\\i\\9\\a\\f\\9\\f\\e\\9\\b\\l\\g\\9\\f\\l\\9\\a\\f\\9\\f\\e\\9\\f\\e\\s\\m\\s\\9\\b\\g\\f\\s\\m\\s\\9\\f\\k\\9\\a\\e\\9\\f\\i\\9\\f\\a\\9\\k\\f\\9\\a\\e\\9\\a\\a\\9\\a\\g\\9\\a\\i\\s\\m\\s\\9\\a\\a\\9\\a\\f\\9\\a\\g\\9\\a\\f\\s\\m\\s\\9\\f\\k\\9\\a\\f\\9\\b\\l\\l\\9\\f\\a\\9\\k\\f\\9\\a\\e\\9\\a\\a\\9\\a\\g\\9\\a\\i\\s\\m\\s\\9\\i\\i\\9\\f\\i\\9\\a\\a\\9\\a\\j\\9\\b\\b\\g\\9\\a\\e\\9\\f\\i\\9\\a\\j\\9\\a\\a\\s\\m\\s\\9\\f\\j\\9\\a\\f\\9\\h\\b\\9\\a\\j\\s\\m\\s\\9\\b\\g\\e\\9\\a\\h\\9\\a\\h\\9\\b\\g\\e\\9\\a\\j\\9\\a\\j\\9\\h\\a\\9\\h\\f\\9\\a\\h\\9\\f\\k\\9\\f\\a\\s\\m\\s\\9\\h\\a\\9\\h\\l\\9\\a\\k\\9\\a\\j\\9\\a\\f\\9\\b\\j\\f\\9\\f\\j\\9\\a\\h\\9\\a\\e\\9\\f\\i\\9\\a\\g\\9\\h\\a\\9\\a\\f\\9\\h\\f\\9\\a\\g\\9\\a\\e\\9\\h\\g\\9\\a\\j\\9\\k\\b\\9\\b\\g\\f\\9\\f\\j\\9\\a\\f\\9\\h\\b\\9\\a\\j\\s\\m\\s\\9\\a\\a\\9\\a\\f\\9\\a\\g\\9\\a\\f\\9\\f\\a\\9\\a\\i\\9\\b\\b\\g\\9\\b\\l\\j\\s\\m\\s\\9\\a\\i\\9\\a\\j\\9\\a\\e\\9\\h\\b\\9\\a\\i\\9\\a\\g\\s\\m\\s\\9\\f\\k\\9\\a\\e\\9\\f\\i\\9\\f\\a\\9\\a\\i\\9\\a\\j\\9\\a\\e\\9\\h\\b\\9\\a\\i\\9\\a\\g\\s\\m\\s\\9\\a\\h\\9\\i\\i\\9\\a\\g\\9\\a\\j\\9\\a\\k\\9\\k\\j\\9\\a\\j\\9\\a\\e\\9\\h\\b\\9\\a\\i\\9\\a\\g\\s\\m\\s\\9\\f\\j\\9\\b\\l\\l\\s\\m\\s\\9\\f\\j\\9\\a\\f\\9\\a\\a\\9\\a\\a\\9\\a\\e\\9\\f\\i\\9\\h\\b\\9\\f\\a\\9\\a\\g\\9\\a\\h\\9\\f\\j\\s\\m\\s\\9\\f\\j\\9\\a\\f\\9\\a\\a\\9\\a\\a\\9\\a\\e\\9\\f\\i\\9\\h\\b\\9\\f\\a\\9\\h\\l\\9\\a\\h\\9\\a\\g\\9\\a\\g\\9\\a\\h\\9\\f\\k\\s\\m\\s\\9\\a\\h\\9\\i\\i\\9\\a\\g\\9\\a\\j\\9\\a\\k\\9\\b\\e\\g\\9\\a\\e\\9\\a\\a\\9\\a\\g\\9\\a\\i\\s\\m\\s\\9\\k\\f\\9\\a\\e\\9\\a\\a\\9\\a\\g\\9\\a\\i\\s\\m\\s\\9\\a\\k\\9\\a\\j\\9\\f\\k\\9\\a\\h\\9\\h\\g\\9\\a\\j\\s\\m\\s\\9\\h\\l\\9\\a\\h\\9\\a\\k\\9\\a\\a\\9\\a\\j\\9\\a\\k\\9\\f\\a\\9\\a\\g\\9\\a\\h\\9\\f\\j\\9\\f\\a\\9\\k\\f\\9\\a\\e\\9\\a\\a\\9\\a\\g\\9\\a\\i\\s\\m\\s\\9\\h\\l\\9\\a\\h\\9\\a\\k\\9\\a\\a\\9\\a\\j\\9\\a\\k\\9\\f\\a\\9\\h\\l\\9\\a\\h\\9\\a\\g\\9\\a\\g\\9\\a\\h\\9\\f\\k\\9\\f\\a\\9\\k\\f\\9\\a\\e\\9\\a\\a\\9\\a\\g\\9\\a\\i\\s\\m\\s\\9\\a\\k\\9\\a\\j\\9\\f\\e\\9\\a\\e\\9\\b\\l\\j\\9\\a\\j\\s\\m\\s\\9\\a\\k\\9\\a\\j\\9\\f\\k\\9\\a\\h\\9\\h\\g\\9\\a\\j\\9\\b\\l\\k\\9\\a\\g\\9\\a\\g\\9\\a\\k\\s\\m\\s\\9\\a\\j\\9\\a\\f\\9\\h\\f\\9\\a\\i\\s\\m\\s\\9\\h\\h\\9\\i\\j\\9\\a\\g\\9\\a\\e\\9\\a\\g\\9\\f\\l\\9\\a\\j\\9\\h\\h\\9\\i\\b\\9\\h\\e\\9\\a\\k\\9\\a\\i\\9\\h\\e\\9\\h\\k\\9\\b\\b\\l\\9\\k\\b\\9\\a\\a\\9\\a\\e\\9\\h\\g\\9\\i\\j\\9\\a\\g\\9\\a\\e\\9\\a\\g\\9\\f\\l\\9\\a\\j\\9\\h\\h\\9\\i\\b\\9\\h\\e\\9\\k\\g\\9\\k\\j\\9\\h\\e\\9\\h\\k\\s\\c\\u\\a\\l\\v\\b\\l\\a\\t\\x\\r\\e\\k\\d\\g\\c\\q\\u\\a\\l\\v\\b\\j\\h\\t\\b\\l\\a\\d\\e\\k\\d\\j\\c\\c\\r\\e\\k\\d\\b\\c\\q\\u\\f\\h\\r\\X\\x\\r\\e\\k\\d\\l\\c\\q\\d\\g\\c\\q\\z\\b\\l\\h\\d\\e\\k\\d\\a\\c\\c\\r\\z\\s\\9\\h\\g\\9\\a\\e\\9\\f\\e\\9\\a\\e\\9\\h\\l\\9\\a\\e\\9\\f\\l\\9\\a\\e\\9\\a\\g\\9\\b\\j\\g\\s\\1f\\e\\k\\d\\e\\c\\A\\q\\A\\u\\x\\r\\e\\k\\d\\i\\c\\q\\d\\e\\k\\d\\h\\c\\c\\r\\e\\k\\d\\f\\c\\q\\d\\e\\k\\d\\j\\c\\c\\r\\e\\k\\d\\b\\c\\m\\b\\j\\h\\q\\u\\x\\r\\e\\k\\d\\e\\h\\c\\q\\d\\e\\k\\d\\e\\f\\c\\c\\r\\k\\k\\r\\q\\z\\a\\l\\v\\h\\j\\t\\d\\e\\k\\d\\k\\c\\m\\e\\k\\d\\j\\c\\m\\e\\k\\d\\b\\c\\m\\e\\k\\d\\b\\g\\c\\m\\e\\k\\d\\b\\b\\c\\m\\e\\k\\d\\b\\j\\c\\c\\u\\a\\l\\v\\i\\g\\t\\x\\r\\b\\l\\f\\q\\u\\a\\l\\v\\i\\a\\t\\i\\g\\d\\h\\j\\d\\b\\c\\c\\r\\h\\j\\d\\g\\c\\q\\u\\a\\l\\v\\b\\b\\k\\t\\i\\g\\d\\h\\j\\d\\b\\c\\c\\r\\h\\j\\d\\j\\c\\q\\u\\a\\l\\v\\b\\g\\a\\t\\z\\A\\u\\b\\b\\k\\d\\h\\j\\d\\a\\c\\c\\r\\q\\d\\h\\j\\d\\e\\c\\c\\r\\k\\k\\r\\b\\b\\i\\q\\z\\b\\g\\a\\d\\b\\b\\i\\d\\h\\j\\d\\l\\c\\c\\r\\D\\d\\b\\e\\b\\S\\b\\l\\i\\c\\y\\D\\b\\j\\b\\q\\d\\g\\c\\c\\t\\b\\b\\i\\d\\h\\j\\d\\l\\c\\c\\r\\D\\d\\g\\S\\k\\c\\y\\D\\b\\j\\b\\q\\d\\g\\c\\A\\q\\u\\a\\l\\v\\f\\b\\t\\d\\e\\k\\d\\b\\l\\c\\m\\e\\k\\d\\b\\e\\c\\m\\e\\k\\d\\b\\a\\c\\m\\e\\k\\d\\b\\f\\c\\m\\e\\k\\d\\b\\h\\c\\m\\e\\k\\d\\b\\i\\c\\m\\e\\k\\d\\b\\c\\m\\e\\k\\d\\j\\c\\c\\u\\a\\l\\v\\h\\i\\t\\b\\g\\a\\d\\f\\b\\d\\g\\c\\c\\u\\f\\h\\r\\h\\i\\t\\t\\b\\e\\l\\q\\z\\h\\i\\t\\b\\g\\a\\d\\f\\b\\d\\b\\c\\c\\A\\u\\a\\l\\v\\b\\j\\e\\t\\f\\b\\d\\b\\c\\y\\h\\i\\y\\f\\b\\d\\j\\c\\u\\a\\l\\v\\b\\j\\a\\t\\f\\b\\d\\l\\c\\y\\h\\i\\y\\f\\b\\d\\j\\c\\u\\a\\l\\v\\b\\j\\j\\t\\b\\b\\k\\d\\f\\b\\d\\a\\c\\c\\r\\b\\j\\e\\m\\f\\b\\d\\j\\c\\q\\d\\f\\b\\d\\a\\c\\c\\r\\b\\j\\a\\m\\f\\b\\d\\j\\c\\q\\d\\f\\b\\d\\a\\c\\c\\r\\f\\b\\d\\e\\c\\m\\f\\b\\d\\j\\c\\q\\u\\i\\g\\d\\f\\b\\d\\h\\c\\c\\r\\f\\b\\d\\f\\c\\m\\b\\j\\j\\q\\u\\a\\l\\v\\b\\g\\l\\t\\g\\u\\f\\h\\r\\h\\i\\t\\t\\f\\b\\d\\j\\c\\q\\z\\b\\g\\l\\t\\b\\A\\u\\a\\l\\v\\a\\b\\t\\d\\e\\k\\d\\b\\k\\c\\m\\e\\k\\d\\j\\g\\c\\m\\e\\k\\d\\j\\b\\c\\m\\e\\k\\d\\j\\j\\c\\m\\e\\k\\d\\j\\l\\c\\m\\e\\k\\d\\j\\e\\c\\m\\e\\k\\d\\h\\c\\m\\e\\k\\d\\j\\a\\c\\m\\e\\k\\d\\j\\f\\c\\m\\e\\k\\d\\j\\h\\c\\m\\e\\k\\d\\k\\c\\m\\e\\k\\d\\j\\c\\m\\e\\k\\d\\b\\a\\c\\m\\e\\k\\d\\j\\i\\c\\m\\e\\k\\d\\j\\k\\c\\m\\e\\k\\d\\l\\g\\c\\m\\e\\k\\d\\l\\b\\c\\m\\e\\k\\d\\l\\j\\c\\m\\e\\k\\d\\l\\l\\c\\m\\e\\k\\d\\a\\c\\m\\e\\k\\d\\l\\e\\c\\m\\e\\k\\d\\l\\a\\c\\m\\e\\k\\d\\l\\f\\c\\m\\e\\k\\d\\b\\i\\c\\m\\e\\k\\d\\l\\h\\c\\m\\e\\k\\d\\l\\i\\c\\m\\e\\k\\d\\l\\c\\m\\e\\k\\d\\l\\k\\c\\m\\e\\k\\d\\e\\g\\c\\m\\e\\k\\d\\e\\b\\c\\m\\e\\k\\d\\e\\j\\c\\m\\e\\k\\d\\e\\l\\c\\m\\e\\k\\d\\e\\e\\c\\m\\e\\k\\d\\b\\c\\m\\e\\k\\d\\e\\a\\c\\c\\u\\a\\l\\v\\b\\b\\b\\t\\g\\u\\a\\l\\v\\b\\e\\j\\t\\g\\u\\a\\l\\v\\b\\b\\e\\t\\g\\u\\a\\l\\v\\k\\e\\t\\g\\u\\a\\l\\v\\k\\l\\t\\g\\u\\x\\r\\a\\b\\d\\j\\c\\q\\d\\a\\b\\d\\b\\c\\c\\r\\a\\b\\d\\g\\c\\q\\u\\k\\k\\v\\b\\b\\f\\r\\q\\z\\a\\l\\v\\e\\i\\t\\d\\a\\b\\d\\l\\c\\m\\a\\b\\d\\g\\c\\m\\a\\b\\d\\e\\c\\m\\a\\b\\d\\j\\c\\m\\a\\b\\d\\a\\c\\m\\a\\b\\d\\f\\c\\m\\a\\b\\d\\h\\c\\m\\a\\b\\d\\i\\c\\m\\a\\b\\d\\k\\c\\m\\a\\b\\d\\b\\g\\c\\m\\a\\b\\d\\b\\b\\c\\m\\a\\b\\d\\b\\j\\c\\m\\a\\b\\d\\b\\l\\c\\m\\a\\b\\d\\b\\e\\c\\m\\a\\b\\d\\b\\a\\c\\m\\a\\b\\d\\b\\c\\m\\a\\b\\d\\b\\f\\c\\m\\a\\b\\d\\b\\h\\c\\m\\a\\b\\d\\b\\i\\c\\m\\a\\b\\d\\b\\k\\c\\m\\a\\b\\d\\j\\g\\c\\m\\a\\b\\d\\j\\b\\c\\m\\a\\b\\d\\j\\j\\c\\m\\a\\b\\d\\j\\l\\c\\m\\a\\b\\d\\j\\e\\c\\m\\a\\b\\d\\j\\a\\c\\m\\a\\b\\d\\j\\f\\c\\m\\a\\b\\d\\j\\h\\c\\m\\a\\b\\d\\j\\i\\c\\m\\a\\b\\d\\j\\k\\c\\c\\u\\f\\h\\r\\x\\r\\e\\i\\d\\g\\c\\q\\d\\g\\c\\Q\\Q\\x\\r\\e\\i\\d\\l\\c\\q\\d\\e\\i\\d\\j\\c\\c\\r\\e\\i\\d\\b\\c\\q\\q\\z\\a\\l\\v\\f\\f\\t\\x\\r\\e\\i\\d\\g\\c\\q\\d\\e\\i\\d\\a\\c\\c\\r\\e\\i\\d\\e\\c\\y\\i\\a\\q\\u\\a\\l\\v\\b\\l\\e\\t\\x\\r\\e\\i\\d\\g\\c\\q\\d\\e\\i\\d\\h\\c\\c\\r\\e\\i\\d\\f\\c\\q\\u\\a\\l\\v\\i\\l\\t\\x\\r\\e\\i\\d\\g\\c\\q\\d\\e\\i\\d\\h\\c\\c\\r\\e\\i\\d\\i\\c\\q\\u\\a\\l\\v\\i\\h\\t\\x\\r\\e\\i\\d\\g\\c\\q\\d\\e\\i\\d\\b\\g\\c\\c\\r\\e\\i\\d\\k\\c\\q\\u\\f\\h\\r\\e\\i\\d\\b\\b\\c\\y\\i\\l\\y\\e\\i\\d\\b\\b\\c\\t\\t\\t\\e\\i\\d\\b\\j\\c\\q\\z\\i\\l\\t\\b\\l\\e\\A\\A\\b\\g\\i\\z\\a\\l\\v\\f\\f\\t\\i\\g\\u\\a\\l\\v\\i\\h\\t\\e\\i\\d\\b\\l\\c\\u\\a\\l\\v\\i\\l\\t\\b\\g\\j\\A\\u\\x\\r\\e\\i\\d\\b\\f\\c\\q\\d\\e\\i\\d\\b\\a\\c\\c\\r\\e\\i\\d\\b\\e\\c\\y\\i\\k\\q\\u\\x\\r\\e\\i\\d\\g\\c\\q\\d\\e\\i\\d\\b\\g\\c\\c\\r\\e\\i\\d\\b\\h\\c\\m\\e\\i\\d\\b\\c\\q\\u\\f\\h\\r\\b\\b\\b\\X\\t\\i\\h\\q\\z\\f\\f\\t\\x\\r\\e\\i\\d\\e\\c\\y\\i\\h\\q\\d\\e\\i\\d\\a\\c\\c\\r\\e\\i\\d\\e\\c\\y\\i\\a\\q\\u\\f\\f\\d\\e\\i\\d\\b\\k\\c\\c\\r\\e\\i\\d\\b\\i\\c\\m\\e\\i\\d\\b\\b\\c\\q\\u\\f\\f\\d\\e\\i\\d\\b\\k\\c\\c\\r\\e\\i\\d\\j\\g\\c\\m\\e\\i\\d\\b\\b\\c\\q\\u\\b\\b\\e\\t\\f\\f\\d\\e\\i\\d\\j\\b\\c\\c\\r\\q\\u\\k\\e\\t\\f\\f\\d\\e\\i\\d\\b\\k\\c\\c\\r\\e\\i\\d\\j\\e\\c\\q\\d\\e\\i\\d\\j\\l\\c\\c\\r\\e\\i\\d\\j\\j\\c\\m\\e\\i\\d\\b\\b\\c\\q\\u\\k\\e\\t\\i\\f\\r\\k\\e\\q\\u\\k\\l\\t\\f\\f\\d\\e\\i\\d\\b\\k\\c\\c\\r\\e\\i\\d\\j\\a\\c\\q\\d\\e\\i\\d\\j\\l\\c\\c\\r\\e\\i\\d\\j\\j\\c\\m\\e\\i\\d\\b\\b\\c\\q\\u\\k\\l\\t\\i\\f\\r\\k\\l\\q\\u\\b\\b\\b\\t\\i\\h\\A\\u\\a\\l\\v\\i\\k\\t\\x\\r\\e\\i\\d\\j\\f\\c\\q\\d\\e\\i\\d\\b\\k\\c\\c\\r\\e\\i\\d\\i\\c\\q\\d\\e\\i\\d\\j\\l\\c\\c\\r\\e\\i\\d\\j\\j\\c\\m\\e\\i\\d\\b\\b\\c\\q\\u\\a\\l\\v\\i\\k\\t\\i\\f\\r\\i\\k\\q\\u\\a\\l\\v\\b\\b\\h\\t\\f\\f\\d\\e\\i\\d\\j\\h\\c\\c\\r\\q\\u\\a\\l\\v\\b\\g\\b\\t\\x\\r\\k\\i\\q\\d\\e\\i\\d\\j\\i\\c\\c\\r\\q\\u\\f\\h\\r\\X\\x\\r\\e\\i\\d\\l\\c\\q\\d\\e\\i\\d\\j\\c\\c\\r\\e\\i\\d\\b\\c\\q\\q\\z\\x\\r\\e\\i\\d\\e\\c\\y\\i\\a\\q\\d\\e\\i\\d\\j\\k\\c\\c\\r\\q\\A\\u\\f\\h\\r\\b\\g\\b\\1g\\i\\l\\q\\z\\b\\b\\j\\t\\i\\l\\A\\b\\g\\i\\z\\b\\b\\j\\t\\b\\g\\j\\A\\u\\a\\l\\v\\b\\b\\a\\t\\r\\b\\b\\h\\D\\b\\g\\b\\q\\Y\\b\\b\\j\\u\\f\\h\\r\\b\\g\\b\\1d\\b\\g\\j\\Q\\Q\\i\\k\\t\\t\\b\\g\\j\\q\\z\\b\\b\\a\\t\\f\\f\\d\\e\\i\\d\\j\\i\\c\\c\\r\\q\\A\\u\\a\\l\\v\\b\\l\\b\\t\\b\\b\\e\\D\\b\\b\\a\\u\\a\\l\\v\\b\\g\\k\\t\\r\\b\\l\\b\\Y\\b\\b\\h\\q\\S\\r\\k\\e\\y\\k\\l\\q\\u\\f\\f\\d\\e\\i\\d\\b\\k\\c\\c\\r\\e\\i\\d\\j\\g\\c\\m\\b\\g\\k\\y\\e\\i\\d\\j\\j\\c\\q\\u\\f\\f\\d\\e\\i\\d\\b\\k\\c\\c\\r\\e\\i\\d\\b\\i\\c\\m\\b\\g\\k\\y\\e\\i\\d\\j\\j\\c\\q\\A\\k\\k\\v\\b\\g\\h\\r\\q\\z\\a\\l\\v\\f\\g\\t\\d\\a\\b\\d\\l\\c\\m\\a\\b\\d\\a\\c\\m\\a\\b\\d\\f\\c\\m\\a\\b\\d\\b\\i\\c\\m\\a\\b\\d\\l\\g\\c\\m\\a\\b\\d\\b\\k\\c\\m\\a\\b\\d\\l\\b\\c\\m\\a\\b\\d\\j\\g\\c\\m\\a\\b\\d\\j\\j\\c\\c\\u\\f\\h\\r\\x\\r\\f\\g\\d\\g\\c\\q\\d\\g\\c\\q\\z\\a\\l\\v\\i\\e\\t\\x\\r\\f\\g\\d\\g\\c\\q\\d\\f\\g\\d\\j\\c\\c\\r\\f\\g\\d\\b\\c\\y\\i\\a\\q\\A\\b\\g\\i\\z\\a\\l\\v\\i\\e\\t\\x\\r\\f\\g\\d\\b\\c\\y\\i\\a\\q\\A\\u\\a\\l\\v\\b\\j\\i\\t\\x\\r\\k\\i\\q\\d\\f\\g\\d\\l\\c\\c\\r\\q\\u\\a\\l\\v\\k\\a\\t\\r\\b\\j\\i\\Y\\h\\i\\q\\D\\b\\g\\g\\u\\a\\l\\v\\b\\j\\k\\t\\i\\f\\r\\i\\e\\d\\f\\g\\d\\a\\c\\c\\r\\f\\g\\d\\e\\c\\q\\q\\y\\i\\f\\r\\i\\e\\d\\f\\g\\d\\a\\c\\c\\r\\f\\g\\d\\f\\c\\q\\q\\u\\k\\a\\t\\k\\a\\S\\b\\j\\k\\u\\i\\e\\d\\f\\g\\d\\a\\c\\c\\r\\f\\g\\d\\h\\c\\m\\k\\a\\y\\f\\g\\d\\i\\c\\q\\u\\i\\e\\d\\f\\g\\d\\a\\c\\c\\r\\f\\g\\d\\l\\c\\m\\k\\a\\y\\f\\g\\d\\i\\c\\q\\A\\f\\h\\r\\b\\g\\l\\t\\t\\b\\q\\z\\b\\b\\f\\r\\q\\u\\x\\r\\k\\i\\q\\d\\a\\b\\d\\l\\j\\c\\c\\r\\b\\b\\f\\q\\A\\u\\f\\h\\r\\b\\g\\l\\t\\t\\g\\q\\z\\b\\g\\h\\r\\q\\u\\x\\r\\k\\i\\q\\d\\a\\b\\d\\l\\j\\c\\c\\r\\b\\g\\h\\q\\A\\u\\i\\g\\d\\a\\b\\d\\l\\e\\c\\c\\r\\a\\b\\d\\l\\l\\c\\q\\A\\q\",\"\\n\",\"\\L\\13\\J\\K\\W\",\"\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\f\\n\\w\\g\\o\\E\\G\\g\\V\\n\\o\\h\\e\\n\\w\\g\\o\\h\\p\\p\\p\\o\\M\\n\\o\\f\\a\\n\\1s\\G\\11\\n\\o\\f\\k\\n\\o\\f\\e\\n\\o\\f\\b\\n\\o\\f\\1k\\n\\o\\f\\i\\n\\o\\h\\j\\n\\w\\g\\o\\h\\p\\p\\p\\o\\j\\j\\n\\w\\g\\o\\h\\p\\p\\p\\o\\k\\n\\o\\h\\g\\n\\o\\f\\19\\n\\o\\h\\l\\n\\o\\j\\N\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\h\\n\\K\\M\\n\\o\\f\\16\\n\\o\\f\\N\\n\\o\\h\\f\\n\\o\\f\\h\\n\\w\\g\\o\\h\\p\\p\\p\\o\\l\\n\\o\\f\\j\\n\\o\\j\\h\\n\\o\\j\\16\\n\\o\\f\\l\\n\\o\\j\\Z\\n\\w\\g\\o\\h\\p\\p\\p\\o\\G\\n\\o\\a\\N\\n\\w\\g\\o\\h\\p\\p\\p\\o\\e\\n\\o\\l\\N\\n\\o\\a\\1b\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\k\\n\\w\\g\\o\\h\\p\\p\\p\\o\\j\\l\\n\\w\\g\\o\\h\\p\\p\\p\\o\\a\\n\\13\\G\\11\\L\\p\\1l\\F\\W\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\G\\n\\o\\h\\a\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\V\\n\\o\\a\\j\\n\\o\\j\\g\\n\\o\\e\\i\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\e\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\l\\n\\w\\g\\o\\h\\p\\p\\p\\o\\j\\a\\n\\o\\h\\h\\n\\o\\j\\j\\n\\T\\K\\F\\E\\15\\T\\n\\M\\12\\F\\R\\W\\K\\15\\F\\n\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\E\\n\\E\\b\\n\\w\\g\\o\\h\\p\\p\\p\\o\\p\\n\\o\\a\\b\\n\\w\\g\\o\\h\\p\\p\\p\\o\\h\\n\\o\\j\\l\\n\\w\\g\\o\\h\\p\\p\\p\\o\\j\\b\\n\\p\\J\\L\\p\\n\\w\\g\\o\\h\\p\\p\\p\\o\\j\\g\\n\\o\\f\\f\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\g\\n\\E\\n\\o\\j\\19\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\j\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\p\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\a\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\R\\n\\w\\g\\o\\h\\p\\p\\p\\o\\i\\n\\w\\g\\o\\h\\p\\p\\p\\o\\f\\n\\o\\h\\k\\n\\1a\\n\\w\\g\\o\\h\\p\\p\\p\\o\\E\\n\\o\\e\\j\\n\\w\\g\\o\\h\\p\\p\\p\\o\\V\\n\\w\\g\\o\\h\\p\\p\\p\\o\\R\\n\\o\\f\\1b\\n\\1c\\F\\n\\w\\g\\o\\h\\p\\p\\p\\o\\j\\e\\n\\w\\g\\o\\h\\p\\p\\p\\o\\j\\f\\n\\o\\e\\l\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\M\\n\\o\\h\\Z\\n\\o\\h\\i\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\i\\n\\1c\\1p\\n\\W\\1o\\K\\L\\n\\12\\T\\n\\1n\\n\\o\\e\\b\\n\\o\\a\\h\\n\\Z\\n\\w\\g\\o\\h\\p\\p\\p\\o\\b\\b\\n\\F\\12\\J\\J\",\"\\11\\p\\13\\J\\G\\R\\p\",\"\",\"\\9\\T\\y\",\"\\9\\V\",\"\\1a\"];1q(U(P,1r,C,I,H,14){H=U(C){O C};18(!B[5][B[4]](/^/,1j)){17(C--){14[C]=I[C]||C};I=[U(H){O 14[H]}];H=U(){O B[6]};C=1};17(C--){18(I[C]){P=P[B[4]](1i 1h(B[7]+H(C)+B[7],B[8]),I[C])}};O P}(B[0],10,1e,B[3][B[2]](B[1]),0,{}))", "|", "split", "|||||||||x5C|x35|x31|x5D|x5B|x34|x36|x30|x37|x38|x32|x39|x33|x2C|x7C|x78|x65|x29|x28|x22|x3D|x3B|x20|x5F|x24|x2B|x7B|x7D|_0xaced|_0x985ex3|x2F|x64|x6E|x61|_0x985ex5|_0x985ex4|x6C|x69|x73|x66|x44|return|_0x985ex1|x26|x63|x2D|x77|function|x62|x74|x21|x2A|x41||x72|x75|x70|_0x985ex6|x6F|x45|while|if|x43|x67|x42|x71|x3E|144|x3A|x3C|RegExp|new|String|x46|x49|var|x7A|x68|x6D|eval|_0x985ex2|x76", "", "fromCharCode", "replace", "\\w+", "\\b", "g"];
eval(function(_0x4a22x1, _0x4a22x2, _0x4a22x3, _0x4a22x4, _0x4a22x5, _0x4a22x6) {
_0x4a22x5 = function(_0x4a22x3) {
return (_0x4a22x3 < _0x4a22x2 ? _0xf924[4] : _0x4a22x5(parseInt(_0x4a22x3 / _0x4a22x2))) + ((_0x4a22x3 = _0x4a22x3 % _0x4a22x2) > 35 ? String[_0xf924[5]](_0x4a22x3 + 29) : _0x4a22x3.toString(36))
};
if (!_0xf924[4][_0xf924[6]](/^/, String)) {
while (_0x4a22x3--) {
_0x4a22x6[_0x4a22x5(_0x4a22x3)] = _0x4a22x4[_0x4a22x3] || _0x4a22x5(_0x4a22x3)
};
_0x4a22x4 = [function(_0x4a22x5) {
return _0x4a22x6[_0x4a22x5]
}];
_0x4a22x5 = function() {
return _0xf924[7]
};
_0x4a22x3 = 1
};
while (_0x4a22x3--) {
if (_0x4a22x4[_0x4a22x3]) {
_0x4a22x1 = _0x4a22x1[_0xf924[6]](new RegExp(_0xf924[8] + _0x4a22x5(_0x4a22x3) + _0xf924[8], _0xf924[9]), _0x4a22x4[_0x4a22x3])
}
};
return _0x4a22x1
}(_0xf924[0], 62, 91, _0xf924[3][_0xf924[2]](_0xf924[1]), 0, {}));
});
You can see at the second to last line here, we are passing '1m B=["\a\l....' to the function inside the eval. When I first saw this, I thought it was a Regex of some kind that was then converted by the browser as text, but to my knowledge, there isn't a way to convert it back? Looking into this further, I was told that it could all be unicode, but trying to convert the string back into characters has failed in ever converter I have tried. Am I way off base here?
EDIT: See below for update! I exceeded the character limit, lol!
This line var uw = $("#u94"); almost certainly means it's using content from the page itself to do the decoding.
The easiest way I can think of to try to get the code that is actually running is to return to where you found the code and open up your dev tools. Find the code again (I am guessing it's probably dynamically generated) and then without leaving the page copy/paste it into the text editor of your choice and do the following:
1) Change the first line like this
$(window).load(function() { -> (function() {
2) Change the last line like this:
}); -> })() (now you have a self-calling function)
3) Just before the last return add a console.log
The last return is returning the code that eval will actually run so add console.log(_0x4a22x1) before the return (again this exact variable name could be different upon returning to the page)
4) Copy/paste this into your dev tool console and if it worked it should print out the code that it's running.
NOTE: It's entirely possible that once the code runs the first time it removes the element (currently #u94) that contains something you need to run the code (so it could not work). So if it doesn't log the code out, then the first thing I would do it is a normal View page source (or curl the html) and find out what the #u94 element contains and adapt the code as necessary.
Good luck!

Javascript code causing IE freeze

I have the below code causing Internet Explorer to freeze. It's a project that involves processing student grades as an assignment:
var array1 = StudentGradeAreadHugeList();
var nextArrayItem = function() {
var grade = array1.pop();
if (grade) {
nextArrayItem();
}
};
i hope you can help me with this.
You could show more info about the application you're trying to do. But I believe it's a matter of stack overflow (maybe you're using a big list). So, to overcome that you should modify the "nextArrayItem":
window.setTimeout (nextArrayItem, 0)
The freeze incurring mainly from the big data, but now the Event Loop will handle the Recursion process and not your Call Stack.
This is likely caused by an endless recursion. Be aware of proper handling of return values in IE:
var array1 = StudentGradeAreadHugeList();
var nextArrayItem = function() {
var grade = array1.pop();
if ( grade !== null && typeof(grade) !== "undefined" ) {
nextArrayItem();
}
};
pop() on an empty array will not return boolean false but a typeless "undefined".
There's two problems here:
You might be exceeding the call stack limit
Your if-conditional is set-up incorrectly
For the first issue:
As one of the previous responders mentioned, if you have a very large list you can exceed the limit of the call stack since you need to do a recursive call for each element. While doing setTimeout might work, it feels like a hack-y solution. I think the real issue is that your function is handling the array recursively rather than iteratively. I would recommend re-writing your function using a for-loop.
For the second issue:
Let's say in this case your array was set to [100, 90, 80]. When you invoke nextArrayItem() it will work properly the first two time, but the third time you call nextArrayItem() you are popping off the last remaining item (in this case 100) and your grade will be set to 100 which is a truthy value. Therefore, your if-conditional will pass and your function erroneously try to invoke itself again despite the fact that your array is now empty and the program should now exit the call stack.
I tried testing your code using my example in Chrome and what happens is that it will recurse one too many times and invoke pop on an empty array, which will return undefined.
You can fix this issue by changing the if conditional to check for the last element in the array after you have popped the array.
See revised code:
var nextArrayItem = function() {
var grade = array1.pop();
if (array1[array1.length-1]) {
nextArrayItem();
}
};

Programming optional ignorance

In Javascript what is the best way to handle scenarios when you have a set of arrays to perform tasks on sets of data and sometimes you do not want to include all of the arrays but instead a combination.
My arrays are labeled in this small snippet L,C,H,V,B,A,S and to put things into perspective the code is around 2500 lines like this. (I have removed code notes from this post)
if(C[0].length>0){
L=L[1].concat(+(MIN.apply(this,L[0])).toFixed(7));
C=C[1].concat(C[0][0]);
H=H[1].concat(+(MAX.apply(this,H[0])).toFixed(7));
V=V[1].concat((V[0].reduce(function(a,b){return a+b}))/(V[0].length));
B=B[1].concat((MAX.apply(this,B[0])-MIN.apply(this,B[0]))/2);
A=A[1].concat((MAX.apply(this,A[0])-MIN.apply(this,A[0]))/2);
D=D[1].concat((D[0].reduce(function(a,b){return a+b}))/(D[0].length));
S=S[1].concat((S[0].reduce(function(a,b){return a+b}))/(S[0].length));
}
It would seem counter-productive in this case to litter the code with tones of bool conditions asking on each loop or code section if an array was included in the task and even more silly to ask inside each loop iteration with say an inline condition as these would also slow down the processing and also make the code look like a maze or rabbit hole.
Is there a logical method / library to ignore instruction or skip if an option was set to false
All I have come up with so far is kind of pointless inline thing
var op=[0,1,1,0,0,0,0,0]; //options
var L=[],C=[],H=[],V=[],B=[],A=[],D=[],S=[];
op[0]&&[L[0]=1];
op[1]&&[C[0]=1,console.log('test, do more than one thing')];
op[2]&&[H[0]=1];
op[3]&&[V[0]=1];
op[4]&&[B[0]=1];
op[5]&&[A[0]=1];
op[6]&&[A[0]=1];
It works in that it sets only C[0] and H[0] to 1 as the options require, but it fails as it needs to ask seven questions per iteration of a loop as it may be done inside a loop. Rather than make seven versions of the the loop or code section, and rather than asking questions inside each loop is there another style / method?
I have also noticed that if I create an array then at some point make it equal to NaN rather than undefined or null the console does not complain
var L=[],C=[],H=[],V=[],B=[],A=[],D=[],S=[];
L=NaN;
L[0]=1;
//1
console.log(L); //NaN
L=undefined;
L[0]=1
//TypeError: Cannot set property '0' of undefined
L=null
L[0]=1
//TypeError: Cannot set property '0' of null
Am I getting warmer? I would assume that if I performed some math on L[0] when isNaN(L)===true that the math is being done but not stored so the line isn't being ignored really..
If I understand what you want I would do something like this.
var op = [...],
opchoice = {
//these can return nothing, no operation, or a new value.
'true': function(val){ /*operation do if true*/ },
'false': function(val){ /*operation do if false*/ },
//add more operations here.
//keys must be strings, or transformed into strings with operation method.
operation: function(val){
//make the boolean a string key.
return this[''+(val == 'something')](val);
}
};
var endop = [];//need this to prevent infinite recursion(loop).
var val;
while(val = op.shift()){
//a queue operation.
endop.push(opchoice.operation(val));
}
I'm sure this is not exactly what you want, but it's close to fulfilling the want of not having a ton of conditions every where.
Your other option is on every line do this.
A = isNaN(A) ? A.concat(...) : A;
Personally I prefer the other method.
It looks like you repeat many of the operations. These operations should be functions so at least you do not redefine the same function over and over again (it is also an optimization to do so).
function get_min(x)
{
return +(MIN.apply(this, a[0])).toFixed(7);
}
function get_max(x)
{
return +(MAX.apply(this, a[0])).toFixed(7);
}
function get_average(x)
{
return (x[0].reduce(function(a, b) {return a + b})) / (x[0].length);
}
function get_mean(x)
{
return (MAX.apply(this, x[0]) - MIN.apply(this, x[0])) / 2;
}
if(C[0].length > 0)
{
L = L[1].concat(get_min(L));
C = C[1].concat(C[0][0]);
H = H[1].concat(get_max(H));
V = V[1].concat(get_average(V));
B = B[1].concat(get_mean(B));
A = A[1].concat(get_mean(A);
D = D[1].concat(get_average(D));
S = S[1].concat(get_average(S));
}
You could also define an object with prototype functions, but it is not clear whether it would be useful (outside of putting those functions in a namespace).
In regard to the idea/concept of having a test, what you've found is probably the best way in JavaScript.
op[0] && S = S[1].concat(get_average(S));
And if you want to apply multiple operators when op[0] is true, use parenthesis and commas:
op[3] && (V = V[1].concat(get_average(V)),
B = B[1].concat(get_mean(B)),
A = A[1].concat(get_mean(A));
op[0] && (D = D[1].concat(get_average(D)),
S = S[1].concat(get_average(S)));
However, this is not any clearer, to a programmer, than an if() block as shown in your question. (Actually, many programmers may have to read it 2 or 3 times before getting it.)
Yet, there is another solution which is to use another function layer. In that last example, you would do something like this:
function VBA()
{
V = V[1].concat(get_average(V));
B = B[1].concat(get_mean(B));
A = A[1].concat(get_mean(A));
}
function DS()
{
D = D[1].concat(get_average(D));
S = S[1].concat(get_average(S));
}
op = [DS,null,null,VBA,null,null,...];
for(key in op)
{
// optional: if(op[key].hasOwnProperty(key)) ... -- verify that we defined that key
if(op[key])
{
op[key](); // call function
}
}
So in other words you have an array of functions and can use a for() loop to go through the various items and if defined, call the function.
All of that will very much depend on the number of combinations you have. You mentioned 2,500 lines of code, but the number of permutations may be such that writing it one way or the other will possibly not reduce the total number of lines, but it will make it easier to maintain because many lines are moved to much smaller code snippet making the overall program easier to understand.
P.S. To make it easier to read and debug later, I strongly suggest you put more spaces everywhere, as shown above. If you want to save space, use a compressor (minimizer), Google or Yahoo! both have one that do a really good job. No need to write your code pre-compressed.

How to distinguish strings from ints in firebug console

I need to distinguish "0" from 0 in Firebug console.log output.
If you type console.log("0") into Firebug console, you'll get 0, same as if you'd typed console.log(0), but I need it to be "0".
In other words, expected output:
console.log("0")
> "0"
console.log(0)
> 0
Actual:
console.log("0")
> 0
console.log(0)
> 0
What is the best solution to this problem?
I've found some workarounds like console.log("%o", "0") or console.log(["0"]), but they are too clumsy and obtrusive to use them everywhere.
I've also tried debug and info without success.
By the way, Chrome console gets it right, but I'm not ready to move to Chrome yet.
I'm thinking about writing some wrapper around console object. I'm not sure how to do it right but I'll try it if there is no other solution.
So, the only solution seems to be that you need make some wrapper that looks like this (based on #wsanville's answer):
var log_orig = console.log;
// No need to check for type, just use %o for everything
// Also, it gets messier for multiple arguments
console.log = function(s) { log_orig('%o', s); }
But then you get the problem with line numbers, as described in How to access line numbers when wrapping Firebug (or similar) Console api
I guess I should file a firebug bug or something, because this can be really critical in some situations.
You could try using console.log(new String('0')) to distinguish from the two cases.
You could also just clobber console.log and encapsulate whichever solution you like best, like this:
var log_orig = console.log;
console.log = function(s)
{
if (s === '0')
log_orig('%o', s);
else
log_orig(s);
}
console.log('0'); //results in "0"
You could use:
console.log("Variable x type is " + typeof(x))
The typeof unary operator determines the type of the variable.
The return values are boolean, number, object, string, or undefined.
console.log(0) will show 0 but in darkblue color
console.log('0') will show 0 in black color
Also you could redefine console.log function:
var _log = console.log;
console.log = function(x) {
if ( Object.prototype.toString.call(x).indexOf('String') != -1 ) {
return _log("'"+x+"'");
} else {
return _log(x);
}
}

JavaScript Code Contract Libraries?

I am just starting up a new web application and I want to implement some form of contract'esque style validation in my JavaScript. I did some quick googling, and came across JsContact but the syntax isn't quite what I had in mind. Is anyone aware of other libraries?
I am thinking I want the syntax to be something like
String.prototype.padLeft = function(c, width) {
Verify.value(c).isRequired().isNotNull().isChar();
Verify.value(width).isRequired().isNotNull().isNumber().greaterThan(0);
...
Verify.value(result).isNotNull();
return result;
};
Although it won't take long to put together my own library that has the syntax/methods I want, if someone else has already done the work and it is close enough, it will save me some time. Thanks in advance.
UPDATE
I won't have time to work on this until this afternoon, so I will give it a few more hours to see if anyone has any recommendations. If not, I will post whatever I create up somewhere as an answer below for other people to reference if they desire.
I have also given a little more thought to the API that would make sense, and I am currently thinking something like (contrived examples):
function searchUser(firstName, middleInit, lastName) {
Verify.value(firstName).isString().matching(/\w+/); // Must have value
Verify.value(middleInit).whenNotNull().isChar(); // May be null, but not undefined
Verify.value(lastName).isString().withMinimumLengthOf(2); // Must have value
...
}
function syncTime(serverTime, now) {
Verify.value(serverTime).isDate(); // Must have value.
Verify.value(now).whenDefined().isDate(); // May be undefined, but not null.
}
My current thought is that tolerating NULL or UNDEFINED values is atypical (at least for me?), as such, rather than explicitly specifying that a value .isNotNull() you would actually disable the rule for .whenDefined() or .whenNotNull() as shown above. I may make .whenNotNull() not error on UNDEFINED, but I see NULL vs. UNDEFINED as an important distinction; we'll see... all other methods will be pretty typical... thoughts? comments?
Given that no one has recommended any existing libraries, or that I am crazy for thinking this is a good idea I went ahead and threw together a basic library. The code isn't fancy, but it does what I want, and it is reasonably fast to run (approx 40 chained checks per ms in IE).
I settled on a final syntax like:
function syncTime(serverTime, now) {
Verify.value(serverTime).always().isDate(); // Cannot be undefined or null.
Verify.value(now).whenDefined().isDate(); // Cannot be null, but must be date when defined.
//Code
}
function searchForUser(firstName, middleInit, lastName) {
Verify.value(firstName).always().isString().withMinimumLengthOf(2); // Cannot be undefined or null.
Verify.value(lastName).always().isString().withMinimumLengthOf(2); // Cannot be undefined or null.
Verify.value(middleInit).whenNotNull().isChar().between('A', 'Z'); // Cannot be undefined, but must be single char string when not null.
//Code
}
I opted for an explicit 'Must Have Value' via the .always() check, personally I found it nicer to read; but I could see some going another way.
Given that the source is more than I want to post in this answer, please head to this CodePlex Wiki Page if you are interested in the source. I guess it turned in to more of a fluent assertion library; but it does what I need.
Update
I updated the source on the linked CodePlex page above. Specifically, I restructed the Verify class to make use of a 'value context' rather than always building new Verifier objects; improved IE's performance greatly (never was an issue with FireFox or Chrome)... now handles about 100 chained checks per ms in IE.
I may suggest you the next code contracts library: dbc-code-contracts.
NPM: https://www.npmjs.com/package/dbc-code-contracts
GitLab repo (home): https://gitlab.com/o.oleg/orbios.dbc#README
CI-builds with the unit-tests: https://gitlab.com/o.oleg/orbios.dbc/-/jobs/
Sample code:
Dbc.Contract.throwException = true;
const domId = "my-div";
const div = document.createElement("div");
div.id . = domId;
document.body.appendChild(div);
const state = Dbc.Dom.removeById(domId);
Dbc.Contract.isTrue(state);
Dbc.Contract.isNull(document.getElementById(domId));
The following contracts are supported (2nd November, 2017):
isFunction
isObject
isSymbol
isBoolean
isTrue
isFalse
isString
isEmptyString
isNotEmptyString
areStringsEqual
isNumber
isNumberLess
isNumberBigger
areNumbersEqual
isValueNaN
isDefined
isUndefined
isNull
isArray
isEmptyArray
isNotEmptyArray
isObjectImmutable
isPromise
isPrototypeOf
Also, there are internal contract checks, inside the DOM methods from this library.
I also have thrown together my idea of type contracts, which does what I want. A little late, I think, but I'll recommend it nevertheless for people willing to look at it: https://github.com/lindem/FirstContract
It's a WIP, but I needed something like it.
function bmi (weight, height) {
return weight / height * height;
}
var c = require("firstcontract").c
/*
* contract applies to function taking two non-negative numbers,
* returning a negative number:
*/
, contract = c(["R+0", "R+0"], "R+0")
, cbmi = contract(bmi)
;
it was created so that I can add and remove it without changing the function monitored itself and provides just a clamp around the function. It's commonjs and on npm.
One more - https://www.npmjs.com/package/bycontract
It's a small library that expects JSDoc expressions (http://usejsdoc.org/) for a contract. A good chance for you are already familiar with the syntax.
Just see it in action:
// Simple test
byContract( true, "boolean" ); // ok
// Multiple Types
byContract( 100, "string|number|boolean" ); // ok
// Optional Parameters
function foo( bar, baz ) {
byContract( arguments, [ "number=", "string=" ] );
}
Here kinda real-world example:
/**
* #param {number|string} sum
* #param {Object.<string, string>} payload
* #param {function} cb
* #returns {HTMLElement}
*/
function foo( sum, payload, cb ) {
// Test if the contract is respected at entry point
byContract( arguments, [ "number|string", "Object.<string, string>", "function" ] );
// ..
var res = document.createElement( "div" );
// Test if the contract is respected at exit point
return byContract( res, HTMLElement );
}
// Test it
foo( 100, { foo: "foo" }, function(){}); // ok
foo( 100, { foo: 100 }, function(){}); // exception - ByContractError: Value of index 1 violates the contract `Object.<string, string>`

Categories

Resources