Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / node_modules / protobufjs / tests / nodeunit-browser / nodeunit.js
diff --git a/legacy-libs/grpc/node_modules/protobufjs/tests/nodeunit-browser/nodeunit.js b/legacy-libs/grpc/node_modules/protobufjs/tests/nodeunit-browser/nodeunit.js
new file mode 100644 (file)
index 0000000..2f8f20d
--- /dev/null
@@ -0,0 +1,2108 @@
+/*!\r
+ * Nodeunit\r
+ * https://github.com/caolan/nodeunit\r
+ * Copyright (c) 2010 Caolan McMahon\r
+ * MIT Licensed\r
+ *\r
+ * json2.js\r
+ * http://www.JSON.org/json2.js\r
+ * Public Domain.\r
+ * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.\r
+ */\r
+nodeunit = (function(){\r
+/*\r
+    http://www.JSON.org/json2.js\r
+    2010-11-17\r
+\r
+    Public Domain.\r
+\r
+    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.\r
+\r
+    See http://www.JSON.org/js.html\r
+\r
+\r
+    This code should be minified before deployment.\r
+    See http://javascript.crockford.com/jsmin.html\r
+\r
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO\r
+    NOT CONTROL.\r
+\r
+\r
+    This file creates a global JSON object containing two methods: stringify\r
+    and parse.\r
+\r
+        JSON.stringify(value, replacer, space)\r
+            value       any JavaScript value, usually an object or array.\r
+\r
+            replacer    an optional parameter that determines how object\r
+                        values are stringified for objects. It can be a\r
+                        function or an array of strings.\r
+\r
+            space       an optional parameter that specifies the indentation\r
+                        of nested structures. If it is omitted, the text will\r
+                        be packed without extra whitespace. If it is a number,\r
+                        it will specify the number of spaces to indent at each\r
+                        level. If it is a string (such as '\t' or ' '),\r
+                        it contains the characters used to indent at each level.\r
+\r
+            This method produces a JSON text from a JavaScript value.\r
+\r
+            When an object value is found, if the object contains a toJSON\r
+            method, its toJSON method will be called and the result will be\r
+            stringified. A toJSON method does not serialize: it returns the\r
+            value represented by the name/value pair that should be serialized,\r
+            or undefined if nothing should be serialized. The toJSON method\r
+            will be passed the key associated with the value, and this will be\r
+            bound to the value\r
+\r
+            For example, this would serialize Dates as ISO strings.\r
+\r
+                Date.prototype.toJSON = function (key) {\r
+                    function f(n) {\r
+                        // Format integers to have at least two digits.\r
+                        return n < 10 ? '0' + n : n;\r
+                    }\r
+\r
+                    return this.getUTCFullYear()   + '-' +\r
+                         f(this.getUTCMonth() + 1) + '-' +\r
+                         f(this.getUTCDate())      + 'T' +\r
+                         f(this.getUTCHours())     + ':' +\r
+                         f(this.getUTCMinutes())   + ':' +\r
+                         f(this.getUTCSeconds())   + 'Z';\r
+                };\r
+\r
+            You can provide an optional replacer method. It will be passed the\r
+            key and value of each member, with this bound to the containing\r
+            object. The value that is returned from your method will be\r
+            serialized. If your method returns undefined, then the member will\r
+            be excluded from the serialization.\r
+\r
+            If the replacer parameter is an array of strings, then it will be\r
+            used to select the members to be serialized. It filters the results\r
+            such that only members with keys listed in the replacer array are\r
+            stringified.\r
+\r
+            Values that do not have JSON representations, such as undefined or\r
+            functions, will not be serialized. Such values in objects will be\r
+            dropped; in arrays they will be replaced with null. You can use\r
+            a replacer function to replace those with JSON values.\r
+            JSON.stringify(undefined) returns undefined.\r
+\r
+            The optional space parameter produces a stringification of the\r
+            value that is filled with line breaks and indentation to make it\r
+            easier to read.\r
+\r
+            If the space parameter is a non-empty string, then that string will\r
+            be used for indentation. If the space parameter is a number, then\r
+            the indentation will be that many spaces.\r
+\r
+            Example:\r
+\r
+            text = JSON.stringify(['e', {pluribus: 'unum'}]);\r
+            // text is '["e",{"pluribus":"unum"}]'\r
+\r
+\r
+            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');\r
+            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'\r
+\r
+            text = JSON.stringify([new Date()], function (key, value) {\r
+                return this[key] instanceof Date ?\r
+                    'Date(' + this[key] + ')' : value;\r
+            });\r
+            // text is '["Date(---current time---)"]'\r
+\r
+\r
+        JSON.parse(text, reviver)\r
+            This method parses a JSON text to produce an object or array.\r
+            It can throw a SyntaxError exception.\r
+\r
+            The optional reviver parameter is a function that can filter and\r
+            transform the results. It receives each of the keys and values,\r
+            and its return value is used instead of the original value.\r
+            If it returns what it received, then the structure is not modified.\r
+            If it returns undefined then the member is deleted.\r
+\r
+            Example:\r
+\r
+            // Parse the text. Values that look like ISO date strings will\r
+            // be converted to Date objects.\r
+\r
+            myData = JSON.parse(text, function (key, value) {\r
+                var a;\r
+                if (typeof value === 'string') {\r
+                    a =\r
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);\r
+                    if (a) {\r
+                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],\r
+                            +a[5], +a[6]));\r
+                    }\r
+                }\r
+                return value;\r
+            });\r
+\r
+            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {\r
+                var d;\r
+                if (typeof value === 'string' &&\r
+                        value.slice(0, 5) === 'Date(' &&\r
+                        value.slice(-1) === ')') {\r
+                    d = new Date(value.slice(5, -1));\r
+                    if (d) {\r
+                        return d;\r
+                    }\r
+                }\r
+                return value;\r
+            });\r
+\r
+\r
+    This is a reference implementation. You are free to copy, modify, or\r
+    redistribute.\r
+*/\r
+\r
+/*jslint evil: true, strict: false, regexp: false */\r
+\r
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,\r
+    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,\r
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,\r
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,\r
+    test, toJSON, toString, valueOf\r
+*/\r
+\r
+\r
+// Create a JSON object only if one does not already exist. We create the\r
+// methods in a closure to avoid creating global variables.\r
+\r
+var JSON = {};\r
+\r
+(function () {\r
+    "use strict";\r
+\r
+    function f(n) {\r
+        // Format integers to have at least two digits.\r
+        return n < 10 ? '0' + n : n;\r
+    }\r
+\r
+    if (typeof Date.prototype.toJSON !== 'function') {\r
+\r
+        Date.prototype.toJSON = function (key) {\r
+\r
+            return isFinite(this.valueOf()) ?\r
+                   this.getUTCFullYear()   + '-' +\r
+                 f(this.getUTCMonth() + 1) + '-' +\r
+                 f(this.getUTCDate())      + 'T' +\r
+                 f(this.getUTCHours())     + ':' +\r
+                 f(this.getUTCMinutes())   + ':' +\r
+                 f(this.getUTCSeconds())   + 'Z' : null;\r
+        };\r
+\r
+        String.prototype.toJSON =\r
+        Number.prototype.toJSON =\r
+        Boolean.prototype.toJSON = function (key) {\r
+            return this.valueOf();\r
+        };\r
+    }\r
+\r
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,\r
+        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,\r
+        gap,\r
+        indent,\r
+        meta = {    // table of character substitutions\r
+            '\b': '\\b',\r
+            '\t': '\\t',\r
+            '\n': '\\n',\r
+            '\f': '\\f',\r
+            '\r': '\\r',\r
+            '"' : '\\"',\r
+            '\\': '\\\\'\r
+        },\r
+        rep;\r
+\r
+\r
+    function quote(string) {\r
+\r
+// If the string contains no control characters, no quote characters, and no\r
+// backslash characters, then we can safely slap some quotes around it.\r
+// Otherwise we must also replace the offending characters with safe escape\r
+// sequences.\r
+\r
+        escapable.lastIndex = 0;\r
+        return escapable.test(string) ?\r
+            '"' + string.replace(escapable, function (a) {\r
+                var c = meta[a];\r
+                return typeof c === 'string' ? c :\r
+                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\r
+            }) + '"' :\r
+            '"' + string + '"';\r
+    }\r
+\r
+\r
+    function str(key, holder) {\r
+\r
+// Produce a string from holder[key].\r
+\r
+        var i,          // The loop counter.\r
+            k,          // The member key.\r
+            v,          // The member value.\r
+            length,\r
+            mind = gap,\r
+            partial,\r
+            value = holder[key];\r
+\r
+// If the value has a toJSON method, call it to obtain a replacement value.\r
+\r
+        if (value && typeof value === 'object' &&\r
+                typeof value.toJSON === 'function') {\r
+            value = value.toJSON(key);\r
+        }\r
+\r
+// If we were called with a replacer function, then call the replacer to\r
+// obtain a replacement value.\r
+\r
+        if (typeof rep === 'function') {\r
+            value = rep.call(holder, key, value);\r
+        }\r
+\r
+// What happens next depends on the value's type.\r
+\r
+        switch (typeof value) {\r
+        case 'string':\r
+            return quote(value);\r
+\r
+        case 'number':\r
+\r
+// JSON numbers must be finite. Encode non-finite numbers as null.\r
+\r
+            return isFinite(value) ? String(value) : 'null';\r
+\r
+        case 'boolean':\r
+        case 'null':\r
+\r
+// If the value is a boolean or null, convert it to a string. Note:\r
+// typeof null does not produce 'null'. The case is included here in\r
+// the remote chance that this gets fixed someday.\r
+\r
+            return String(value);\r
+\r
+// If the type is 'object', we might be dealing with an object or an array or\r
+// null.\r
+\r
+        case 'object':\r
+\r
+// Due to a specification blunder in ECMAScript, typeof null is 'object',\r
+// so watch out for that case.\r
+\r
+            if (!value) {\r
+                return 'null';\r
+            }\r
+\r
+// Make an array to hold the partial results of stringifying this object value.\r
+\r
+            gap += indent;\r
+            partial = [];\r
+\r
+// Is the value an array?\r
+\r
+            if (Object.prototype.toString.apply(value) === '[object Array]') {\r
+\r
+// The value is an array. Stringify every element. Use null as a placeholder\r
+// for non-JSON values.\r
+\r
+                length = value.length;\r
+                for (i = 0; i < length; i += 1) {\r
+                    partial[i] = str(i, value) || 'null';\r
+                }\r
+\r
+// Join all of the elements together, separated with commas, and wrap them in\r
+// brackets.\r
+\r
+                v = partial.length === 0 ? '[]' :\r
+                    gap ? '[\n' + gap +\r
+                            partial.join(',\n' + gap) + '\n' +\r
+                                mind + ']' :\r
+                          '[' + partial.join(',') + ']';\r
+                gap = mind;\r
+                return v;\r
+            }\r
+\r
+// If the replacer is an array, use it to select the members to be stringified.\r
+\r
+            if (rep && typeof rep === 'object') {\r
+                length = rep.length;\r
+                for (i = 0; i < length; i += 1) {\r
+                    k = rep[i];\r
+                    if (typeof k === 'string') {\r
+                        v = str(k, value);\r
+                        if (v) {\r
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\r
+                        }\r
+                    }\r
+                }\r
+            } else {\r
+\r
+// Otherwise, iterate through all of the keys in the object.\r
+\r
+                for (k in value) {\r
+                    if (Object.hasOwnProperty.call(value, k)) {\r
+                        v = str(k, value);\r
+                        if (v) {\r
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+\r
+// Join all of the member texts together, separated with commas,\r
+// and wrap them in braces.\r
+\r
+            v = partial.length === 0 ? '{}' :\r
+                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +\r
+                        mind + '}' : '{' + partial.join(',') + '}';\r
+            gap = mind;\r
+            return v;\r
+        }\r
+    }\r
+\r
+// If the JSON object does not yet have a stringify method, give it one.\r
+\r
+    if (typeof JSON.stringify !== 'function') {\r
+        JSON.stringify = function (value, replacer, space) {\r
+\r
+// The stringify method takes a value and an optional replacer, and an optional\r
+// space parameter, and returns a JSON text. The replacer can be a function\r
+// that can replace values, or an array of strings that will select the keys.\r
+// A default replacer method can be provided. Use of the space parameter can\r
+// produce text that is more easily readable.\r
+\r
+            var i;\r
+            gap = '';\r
+            indent = '';\r
+\r
+// If the space parameter is a number, make an indent string containing that\r
+// many spaces.\r
+\r
+            if (typeof space === 'number') {\r
+                for (i = 0; i < space; i += 1) {\r
+                    indent += ' ';\r
+                }\r
+\r
+// If the space parameter is a string, it will be used as the indent string.\r
+\r
+            } else if (typeof space === 'string') {\r
+                indent = space;\r
+            }\r
+\r
+// If there is a replacer, it must be a function or an array.\r
+// Otherwise, throw an error.\r
+\r
+            rep = replacer;\r
+            if (replacer && typeof replacer !== 'function' &&\r
+                    (typeof replacer !== 'object' ||\r
+                     typeof replacer.length !== 'number')) {\r
+                throw new Error('JSON.stringify');\r
+            }\r
+\r
+// Make a fake root object containing our value under the key of ''.\r
+// Return the result of stringifying the value.\r
+\r
+            return str('', {'': value});\r
+        };\r
+    }\r
+\r
+\r
+// If the JSON object does not yet have a parse method, give it one.\r
+\r
+    if (typeof JSON.parse !== 'function') {\r
+        JSON.parse = function (text, reviver) {\r
+\r
+// The parse method takes a text and an optional reviver function, and returns\r
+// a JavaScript value if the text is a valid JSON text.\r
+\r
+            var j;\r
+\r
+            function walk(holder, key) {\r
+\r
+// The walk method is used to recursively walk the resulting structure so\r
+// that modifications can be made.\r
+\r
+                var k, v, value = holder[key];\r
+                if (value && typeof value === 'object') {\r
+                    for (k in value) {\r
+                        if (Object.hasOwnProperty.call(value, k)) {\r
+                            v = walk(value, k);\r
+                            if (v !== undefined) {\r
+                                value[k] = v;\r
+                            } else {\r
+                                delete value[k];\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+                return reviver.call(holder, key, value);\r
+            }\r
+\r
+\r
+// Parsing happens in four stages. In the first stage, we replace certain\r
+// Unicode characters with escape sequences. JavaScript handles many characters\r
+// incorrectly, either silently deleting them, or treating them as line endings.\r
+\r
+            text = String(text);\r
+            cx.lastIndex = 0;\r
+            if (cx.test(text)) {\r
+                text = text.replace(cx, function (a) {\r
+                    return '\\u' +\r
+                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\r
+                });\r
+            }\r
+\r
+// In the second stage, we run the text against regular expressions that look\r
+// for non-JSON patterns. We are especially concerned with '()' and 'new'\r
+// because they can cause invocation, and '=' because it can cause mutation.\r
+// But just to be safe, we want to reject all unexpected forms.\r
+\r
+// We split the second stage into 4 regexp operations in order to work around\r
+// crippling inefficiencies in IE's and Safari's regexp engines. First we\r
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we\r
+// replace all simple value tokens with ']' characters. Third, we delete all\r
+// open brackets that follow a colon or comma or that begin the text. Finally,\r
+// we look to see that the remaining characters are only whitespace or ']' or\r
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.\r
+\r
+            if (/^[\],:{}\s]*$/\r
+.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')\r
+.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')\r
+.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {\r
+\r
+// In the third stage we use the eval function to compile the text into a\r
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity\r
+// in JavaScript: it can begin a block or an object literal. We wrap the text\r
+// in parens to eliminate the ambiguity.\r
+\r
+                j = eval('(' + text + ')');\r
+\r
+// In the optional fourth stage, we recursively walk the new structure, passing\r
+// each name/value pair to a reviver function for possible transformation.\r
+\r
+                return typeof reviver === 'function' ?\r
+                    walk({'': j}, '') : j;\r
+            }\r
+\r
+// If the text is not JSON parseable, then a SyntaxError is thrown.\r
+\r
+            throw new SyntaxError('JSON.parse');\r
+        };\r
+    }\r
+}());\r
+var assert = this.assert = {};\r
+var types = {};\r
+var core = {};\r
+var nodeunit = {};\r
+var reporter = {};\r
+/*global setTimeout: false, console: false */\r
+(function () {\r
+\r
+    var async = {};\r
+\r
+    // global on the server, window in the browser\r
+    var root = this,\r
+        previous_async = root.async;\r
+\r
+    if (typeof module !== 'undefined' && module.exports) {\r
+        module.exports = async;\r
+    }\r
+    else {\r
+        root.async = async;\r
+    }\r
+\r
+    async.noConflict = function () {\r
+        root.async = previous_async;\r
+        return async;\r
+    };\r
+\r
+    //// cross-browser compatiblity functions ////\r
+\r
+    var _forEach = function (arr, iterator) {\r
+        if (arr.forEach) {\r
+            return arr.forEach(iterator);\r
+        }\r
+        for (var i = 0; i < arr.length; i += 1) {\r
+            iterator(arr[i], i, arr);\r
+        }\r
+    };\r
+\r
+    var _map = function (arr, iterator) {\r
+        if (arr.map) {\r
+            return arr.map(iterator);\r
+        }\r
+        var results = [];\r
+        _forEach(arr, function (x, i, a) {\r
+            results.push(iterator(x, i, a));\r
+        });\r
+        return results;\r
+    };\r
+\r
+    var _reduce = function (arr, iterator, memo) {\r
+        if (arr.reduce) {\r
+            return arr.reduce(iterator, memo);\r
+        }\r
+        _forEach(arr, function (x, i, a) {\r
+            memo = iterator(memo, x, i, a);\r
+        });\r
+        return memo;\r
+    };\r
+\r
+    var _keys = function (obj) {\r
+        if (Object.keys) {\r
+            return Object.keys(obj);\r
+        }\r
+        var keys = [];\r
+        for (var k in obj) {\r
+            if (obj.hasOwnProperty(k)) {\r
+                keys.push(k);\r
+            }\r
+        }\r
+        return keys;\r
+    };\r
+\r
+    var _indexOf = function (arr, item) {\r
+        if (arr.indexOf) {\r
+            return arr.indexOf(item);\r
+        }\r
+        for (var i = 0; i < arr.length; i += 1) {\r
+            if (arr[i] === item) {\r
+                return i;\r
+            }\r
+        }\r
+        return -1;\r
+    };\r
+\r
+    //// exported async module functions ////\r
+\r
+    //// nextTick implementation with browser-compatible fallback ////\r
+    if (typeof process === 'undefined' || !(process.nextTick)) {\r
+        async.nextTick = function (fn) {\r
+            setTimeout(fn, 0);\r
+        };\r
+    }\r
+    else {\r
+        async.nextTick = process.nextTick;\r
+    }\r
+\r
+    async.forEach = function (arr, iterator, callback) {\r
+        if (!arr.length) {\r
+            return callback();\r
+        }\r
+        var completed = 0;\r
+        _forEach(arr, function (x) {\r
+            iterator(x, function (err) {\r
+                if (err) {\r
+                    callback(err);\r
+                    callback = function () {};\r
+                }\r
+                else {\r
+                    completed += 1;\r
+                    if (completed === arr.length) {\r
+                        callback();\r
+                    }\r
+                }\r
+            });\r
+        });\r
+    };\r
+\r
+    async.forEachSeries = function (arr, iterator, callback) {\r
+        if (!arr.length) {\r
+            return callback();\r
+        }\r
+        var completed = 0;\r
+        var iterate = function () {\r
+            iterator(arr[completed], function (err) {\r
+                if (err) {\r
+                    callback(err);\r
+                    callback = function () {};\r
+                }\r
+                else {\r
+                    completed += 1;\r
+                    if (completed === arr.length) {\r
+                        callback();\r
+                    }\r
+                    else {\r
+                        iterate();\r
+                    }\r
+                }\r
+            });\r
+        };\r
+        iterate();\r
+    };\r
+\r
+\r
+    var doParallel = function (fn) {\r
+        return function () {\r
+            var args = Array.prototype.slice.call(arguments);\r
+            return fn.apply(null, [async.forEach].concat(args));\r
+        };\r
+    };\r
+    var doSeries = function (fn) {\r
+        return function () {\r
+            var args = Array.prototype.slice.call(arguments);\r
+            return fn.apply(null, [async.forEachSeries].concat(args));\r
+        };\r
+    };\r
+\r
+\r
+    var _asyncMap = function (eachfn, arr, iterator, callback) {\r
+        var results = [];\r
+        arr = _map(arr, function (x, i) {\r
+            return {index: i, value: x};\r
+        });\r
+        eachfn(arr, function (x, callback) {\r
+            iterator(x.value, function (err, v) {\r
+                results[x.index] = v;\r
+                callback(err);\r
+            });\r
+        }, function (err) {\r
+            callback(err, results);\r
+        });\r
+    };\r
+    async.map = doParallel(_asyncMap);\r
+    async.mapSeries = doSeries(_asyncMap);\r
+\r
+\r
+    // reduce only has a series version, as doing reduce in parallel won't\r
+    // work in many situations.\r
+    async.reduce = function (arr, memo, iterator, callback) {\r
+        async.forEachSeries(arr, function (x, callback) {\r
+            iterator(memo, x, function (err, v) {\r
+                memo = v;\r
+                callback(err);\r
+            });\r
+        }, function (err) {\r
+            callback(err, memo);\r
+        });\r
+    };\r
+    // inject alias\r
+    async.inject = async.reduce;\r
+    // foldl alias\r
+    async.foldl = async.reduce;\r
+\r
+    async.reduceRight = function (arr, memo, iterator, callback) {\r
+        var reversed = _map(arr, function (x) {\r
+            return x;\r
+        }).reverse();\r
+        async.reduce(reversed, memo, iterator, callback);\r
+    };\r
+    // foldr alias\r
+    async.foldr = async.reduceRight;\r
+\r
+    var _filter = function (eachfn, arr, iterator, callback) {\r
+        var results = [];\r
+        arr = _map(arr, function (x, i) {\r
+            return {index: i, value: x};\r
+        });\r
+        eachfn(arr, function (x, callback) {\r
+            iterator(x.value, function (v) {\r
+                if (v) {\r
+                    results.push(x);\r
+                }\r
+                callback();\r
+            });\r
+        }, function (err) {\r
+            callback(_map(results.sort(function (a, b) {\r
+                return a.index - b.index;\r
+            }), function (x) {\r
+                return x.value;\r
+            }));\r
+        });\r
+    };\r
+    async.filter = doParallel(_filter);\r
+    async.filterSeries = doSeries(_filter);\r
+    // select alias\r
+    async.select = async.filter;\r
+    async.selectSeries = async.filterSeries;\r
+\r
+    var _reject = function (eachfn, arr, iterator, callback) {\r
+        var results = [];\r
+        arr = _map(arr, function (x, i) {\r
+            return {index: i, value: x};\r
+        });\r
+        eachfn(arr, function (x, callback) {\r
+            iterator(x.value, function (v) {\r
+                if (!v) {\r
+                    results.push(x);\r
+                }\r
+                callback();\r
+            });\r
+        }, function (err) {\r
+            callback(_map(results.sort(function (a, b) {\r
+                return a.index - b.index;\r
+            }), function (x) {\r
+                return x.value;\r
+            }));\r
+        });\r
+    };\r
+    async.reject = doParallel(_reject);\r
+    async.rejectSeries = doSeries(_reject);\r
+\r
+    var _detect = function (eachfn, arr, iterator, main_callback) {\r
+        eachfn(arr, function (x, callback) {\r
+            iterator(x, function (result) {\r
+                if (result) {\r
+                    main_callback(x);\r
+                }\r
+                else {\r
+                    callback();\r
+                }\r
+            });\r
+        }, function (err) {\r
+            main_callback();\r
+        });\r
+    };\r
+    async.detect = doParallel(_detect);\r
+    async.detectSeries = doSeries(_detect);\r
+\r
+    async.some = function (arr, iterator, main_callback) {\r
+        async.forEach(arr, function (x, callback) {\r
+            iterator(x, function (v) {\r
+                if (v) {\r
+                    main_callback(true);\r
+                    main_callback = function () {};\r
+                }\r
+                callback();\r
+            });\r
+        }, function (err) {\r
+            main_callback(false);\r
+        });\r
+    };\r
+    // any alias\r
+    async.any = async.some;\r
+\r
+    async.every = function (arr, iterator, main_callback) {\r
+        async.forEach(arr, function (x, callback) {\r
+            iterator(x, function (v) {\r
+                if (!v) {\r
+                    main_callback(false);\r
+                    main_callback = function () {};\r
+                }\r
+                callback();\r
+            });\r
+        }, function (err) {\r
+            main_callback(true);\r
+        });\r
+    };\r
+    // all alias\r
+    async.all = async.every;\r
+\r
+    async.sortBy = function (arr, iterator, callback) {\r
+        async.map(arr, function (x, callback) {\r
+            iterator(x, function (err, criteria) {\r
+                if (err) {\r
+                    callback(err);\r
+                }\r
+                else {\r
+                    callback(null, {value: x, criteria: criteria});\r
+                }\r
+            });\r
+        }, function (err, results) {\r
+            if (err) {\r
+                return callback(err);\r
+            }\r
+            else {\r
+                var fn = function (left, right) {\r
+                    var a = left.criteria, b = right.criteria;\r
+                    return a < b ? -1 : a > b ? 1 : 0;\r
+                };\r
+                callback(null, _map(results.sort(fn), function (x) {\r
+                    return x.value;\r
+                }));\r
+            }\r
+        });\r
+    };\r
+\r
+    async.auto = function (tasks, callback) {\r
+        callback = callback || function () {};\r
+        var keys = _keys(tasks);\r
+        if (!keys.length) {\r
+            return callback(null);\r
+        }\r
+\r
+        var completed = [];\r
+\r
+        var listeners = [];\r
+        var addListener = function (fn) {\r
+            listeners.unshift(fn);\r
+        };\r
+        var removeListener = function (fn) {\r
+            for (var i = 0; i < listeners.length; i += 1) {\r
+                if (listeners[i] === fn) {\r
+                    listeners.splice(i, 1);\r
+                    return;\r
+                }\r
+            }\r
+        };\r
+        var taskComplete = function () {\r
+            _forEach(listeners, function (fn) {\r
+                fn();\r
+            });\r
+        };\r
+\r
+        addListener(function () {\r
+            if (completed.length === keys.length) {\r
+                callback(null);\r
+            }\r
+        });\r
+\r
+        _forEach(keys, function (k) {\r
+            var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];\r
+            var taskCallback = function (err) {\r
+                if (err) {\r
+                    callback(err);\r
+                    // stop subsequent errors hitting callback multiple times\r
+                    callback = function () {};\r
+                }\r
+                else {\r
+                    completed.push(k);\r
+                    taskComplete();\r
+                }\r
+            };\r
+            var requires = task.slice(0, Math.abs(task.length - 1)) || [];\r
+            var ready = function () {\r
+                return _reduce(requires, function (a, x) {\r
+                    return (a && _indexOf(completed, x) !== -1);\r
+                }, true);\r
+            };\r
+            if (ready()) {\r
+                task[task.length - 1](taskCallback);\r
+            }\r
+            else {\r
+                var listener = function () {\r
+                    if (ready()) {\r
+                        removeListener(listener);\r
+                        task[task.length - 1](taskCallback);\r
+                    }\r
+                };\r
+                addListener(listener);\r
+            }\r
+        });\r
+    };\r
+\r
+    async.waterfall = function (tasks, callback) {\r
+        if (!tasks.length) {\r
+            return callback();\r
+        }\r
+        callback = callback || function () {};\r
+        var wrapIterator = function (iterator) {\r
+            return function (err) {\r
+                if (err) {\r
+                    callback(err);\r
+                    callback = function () {};\r
+                }\r
+                else {\r
+                    var args = Array.prototype.slice.call(arguments, 1);\r
+                    var next = iterator.next();\r
+                    if (next) {\r
+                        args.push(wrapIterator(next));\r
+                    }\r
+                    else {\r
+                        args.push(callback);\r
+                    }\r
+                    async.nextTick(function () {\r
+                        iterator.apply(null, args);\r
+                    });\r
+                }\r
+            };\r
+        };\r
+        wrapIterator(async.iterator(tasks))();\r
+    };\r
+\r
+    async.parallel = function (tasks, callback) {\r
+        callback = callback || function () {};\r
+        if (tasks.constructor === Array) {\r
+            async.map(tasks, function (fn, callback) {\r
+                if (fn) {\r
+                    fn(function (err) {\r
+                        var args = Array.prototype.slice.call(arguments, 1);\r
+                        if (args.length <= 1) {\r
+                            args = args[0];\r
+                        }\r
+                        callback.call(null, err, args || null);\r
+                    });\r
+                }\r
+            }, callback);\r
+        }\r
+        else {\r
+            var results = {};\r
+            async.forEach(_keys(tasks), function (k, callback) {\r
+                tasks[k](function (err) {\r
+                    var args = Array.prototype.slice.call(arguments, 1);\r
+                    if (args.length <= 1) {\r
+                        args = args[0];\r
+                    }\r
+                    results[k] = args;\r
+                    callback(err);\r
+                });\r
+            }, function (err) {\r
+                callback(err, results);\r
+            });\r
+        }\r
+    };\r
+\r
+    async.series = function (tasks, callback) {\r
+        callback = callback || function () {};\r
+        if (tasks.constructor === Array) {\r
+            async.mapSeries(tasks, function (fn, callback) {\r
+                if (fn) {\r
+                    fn(function (err) {\r
+                        var args = Array.prototype.slice.call(arguments, 1);\r
+                        if (args.length <= 1) {\r
+                            args = args[0];\r
+                        }\r
+                        callback.call(null, err, args || null);\r
+                    });\r
+                }\r
+            }, callback);\r
+        }\r
+        else {\r
+            var results = {};\r
+            async.forEachSeries(_keys(tasks), function (k, callback) {\r
+                tasks[k](function (err) {\r
+                    var args = Array.prototype.slice.call(arguments, 1);\r
+                    if (args.length <= 1) {\r
+                        args = args[0];\r
+                    }\r
+                    results[k] = args;\r
+                    callback(err);\r
+                });\r
+            }, function (err) {\r
+                callback(err, results);\r
+            });\r
+        }\r
+    };\r
+\r
+    async.iterator = function (tasks) {\r
+        var makeCallback = function (index) {\r
+            var fn = function () {\r
+                if (tasks.length) {\r
+                    tasks[index].apply(null, arguments);\r
+                }\r
+                return fn.next();\r
+            };\r
+            fn.next = function () {\r
+                return (index < tasks.length - 1) ? makeCallback(index + 1): null;\r
+            };\r
+            return fn;\r
+        };\r
+        return makeCallback(0);\r
+    };\r
+\r
+    async.apply = function (fn) {\r
+        var args = Array.prototype.slice.call(arguments, 1);\r
+        return function () {\r
+            return fn.apply(\r
+                null, args.concat(Array.prototype.slice.call(arguments))\r
+            );\r
+        };\r
+    };\r
+\r
+    var _concat = function (eachfn, arr, fn, callback) {\r
+        var r = [];\r
+        eachfn(arr, function (x, cb) {\r
+            fn(x, function (err, y) {\r
+                r = r.concat(y || []);\r
+                cb(err);\r
+            });\r
+        }, function (err) {\r
+            callback(err, r);\r
+        });\r
+    };\r
+    async.concat = doParallel(_concat);\r
+    async.concatSeries = doSeries(_concat);\r
+\r
+    async.whilst = function (test, iterator, callback) {\r
+        if (test()) {\r
+            iterator(function (err) {\r
+                if (err) {\r
+                    return callback(err);\r
+                }\r
+                async.whilst(test, iterator, callback);\r
+            });\r
+        }\r
+        else {\r
+            callback();\r
+        }\r
+    };\r
+\r
+    async.until = function (test, iterator, callback) {\r
+        if (!test()) {\r
+            iterator(function (err) {\r
+                if (err) {\r
+                    return callback(err);\r
+                }\r
+                async.until(test, iterator, callback);\r
+            });\r
+        }\r
+        else {\r
+            callback();\r
+        }\r
+    };\r
+\r
+    async.queue = function (worker, concurrency) {\r
+        var workers = 0;\r
+        var tasks = [];\r
+        var q = {\r
+            concurrency: concurrency,\r
+            push: function (data, callback) {\r
+                tasks.push({data: data, callback: callback});\r
+                async.nextTick(q.process);\r
+            },\r
+            process: function () {\r
+                if (workers < q.concurrency && tasks.length) {\r
+                    var task = tasks.splice(0, 1)[0];\r
+                    workers += 1;\r
+                    worker(task.data, function () {\r
+                        workers -= 1;\r
+                        if (task.callback) {\r
+                            task.callback.apply(task, arguments);\r
+                        }\r
+                        q.process();\r
+                    });\r
+                }\r
+            },\r
+            length: function () {\r
+                return tasks.length;\r
+            }\r
+        };\r
+        return q;\r
+    };\r
+\r
+    var _console_fn = function (name) {\r
+        return function (fn) {\r
+            var args = Array.prototype.slice.call(arguments, 1);\r
+            fn.apply(null, args.concat([function (err) {\r
+                var args = Array.prototype.slice.call(arguments, 1);\r
+                if (typeof console !== 'undefined') {\r
+                    if (err) {\r
+                        if (console.error) {\r
+                            console.error(err);\r
+                        }\r
+                    }\r
+                    else if (console[name]) {\r
+                        _forEach(args, function (x) {\r
+                            console[name](x);\r
+                        });\r
+                    }\r
+                }\r
+            }]));\r
+        };\r
+    };\r
+    async.log = _console_fn('log');\r
+    async.dir = _console_fn('dir');\r
+    /*async.info = _console_fn('info');\r
+    async.warn = _console_fn('warn');\r
+    async.error = _console_fn('error');*/\r
+\r
+    async.memoize = function (fn, hasher) {\r
+        var memo = {};\r
+        hasher = hasher || function (x) {\r
+            return x;\r
+        };\r
+        return function () {\r
+            var args = Array.prototype.slice.call(arguments);\r
+            var callback = args.pop();\r
+            var key = hasher.apply(null, args);\r
+            if (key in memo) {\r
+                callback.apply(null, memo[key]);\r
+            }\r
+            else {\r
+                fn.apply(null, args.concat([function () {\r
+                    memo[key] = arguments;\r
+                    callback.apply(null, arguments);\r
+                }]));\r
+            }\r
+        };\r
+    };\r
+\r
+}());\r
+(function(exports){\r
+/**\r
+ * This file is based on the node.js assert module, but with some small\r
+ * changes for browser-compatibility\r
+ * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!\r
+ */\r
+\r
+\r
+/**\r
+ * Added for browser compatibility\r
+ */\r
+\r
+var _keys = function(obj){\r
+    if(Object.keys) return Object.keys(obj);\r
+    if (typeof obj != 'object' && typeof obj != 'function') {\r
+        throw new TypeError('-');\r
+    }\r
+    var keys = [];\r
+    for(var k in obj){\r
+        if(obj.hasOwnProperty(k)) keys.push(k);\r
+    }\r
+    return keys;\r
+};\r
+\r
+\r
+\r
+// http://wiki.commonjs.org/wiki/Unit_Testing/1.0\r
+//\r
+// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!\r
+//\r
+// Originally from narwhal.js (http://narwhaljs.org)\r
+// Copyright (c) 2009 Thomas Robinson <280north.com>\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining a copy\r
+// of this software and associated documentation files (the 'Software'), to\r
+// deal in the Software without restriction, including without limitation the\r
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\r
+// sell copies of the Software, and to permit persons to whom the Software is\r
+// furnished to do so, subject to the following conditions:\r
+//\r
+// The above copyright notice and this permission notice shall be included in\r
+// all copies or substantial portions of the Software.\r
+//\r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+\r
+\r
+var pSlice = Array.prototype.slice;\r
+\r
+// 1. The assert module provides functions that throw\r
+// AssertionError's when particular conditions are not met. The\r
+// assert module must conform to the following interface.\r
+\r
+var assert = exports;\r
+\r
+// 2. The AssertionError is defined in assert.\r
+// new assert.AssertionError({message: message, actual: actual, expected: expected})\r
+\r
+assert.AssertionError = function AssertionError (options) {\r
+  this.name = "AssertionError";\r
+  this.message = options.message;\r
+  this.actual = options.actual;\r
+  this.expected = options.expected;\r
+  this.operator = options.operator;\r
+  var stackStartFunction = options.stackStartFunction || fail;\r
+\r
+  if (Error.captureStackTrace) {\r
+    Error.captureStackTrace(this, stackStartFunction);\r
+  }\r
+};\r
+// code from util.inherits in node\r
+assert.AssertionError.super_ = Error;\r
+\r
+\r
+// EDITED FOR BROWSER COMPATIBILITY: replaced Object.create call\r
+// TODO: test what effect this may have\r
+var ctor = function () { this.constructor = assert.AssertionError; };\r
+ctor.prototype = Error.prototype;\r
+assert.AssertionError.prototype = new ctor();\r
+\r
+\r
+assert.AssertionError.prototype.toString = function() {\r
+  if (this.message) {\r
+    return [this.name+":", this.message].join(' ');\r
+  } else {\r
+    return [ this.name+":"\r
+           , JSON.stringify(this.expected )\r
+           , this.operator\r
+           , JSON.stringify(this.actual)\r
+           ].join(" ");\r
+  }\r
+};\r
+\r
+// assert.AssertionError instanceof Error\r
+\r
+assert.AssertionError.__proto__ = Error.prototype;\r
+\r
+// At present only the three keys mentioned above are used and\r
+// understood by the spec. Implementations or sub modules can pass\r
+// other keys to the AssertionError's constructor - they will be\r
+// ignored.\r
+\r
+// 3. All of the following functions must throw an AssertionError\r
+// when a corresponding condition is not met, with a message that\r
+// may be undefined if not provided.  All assertion methods provide\r
+// both the actual and expected values to the assertion error for\r
+// display purposes.\r
+\r
+function fail(actual, expected, message, operator, stackStartFunction) {\r
+  throw new assert.AssertionError({\r
+    message: message,\r
+    actual: actual,\r
+    expected: expected,\r
+    operator: operator,\r
+    stackStartFunction: stackStartFunction\r
+  });\r
+}\r
+\r
+// EXTENSION! allows for well behaved errors defined elsewhere.\r
+assert.fail = fail;\r
+\r
+// 4. Pure assertion tests whether a value is truthy, as determined\r
+// by !!guard.\r
+// assert.ok(guard, message_opt);\r
+// This statement is equivalent to assert.equal(true, guard,\r
+// message_opt);. To test strictly for the value true, use\r
+// assert.strictEqual(true, guard, message_opt);.\r
+\r
+assert.ok = function ok(value, message) {\r
+  if (!!!value) fail(value, true, message, "==", assert.ok);\r
+};\r
+\r
+// 5. The equality assertion tests shallow, coercive equality with\r
+// ==.\r
+// assert.equal(actual, expected, message_opt);\r
+\r
+assert.equal = function equal(actual, expected, message) {\r
+  if (actual != expected) fail(actual, expected, message, "==", assert.equal);\r
+};\r
+\r
+// 6. The non-equality assertion tests for whether two objects are not equal\r
+// with != assert.notEqual(actual, expected, message_opt);\r
+\r
+assert.notEqual = function notEqual(actual, expected, message) {\r
+  if (actual == expected) {\r
+    fail(actual, expected, message, "!=", assert.notEqual);\r
+  }\r
+};\r
+\r
+// 7. The equivalence assertion tests a deep equality relation.\r
+// assert.deepEqual(actual, expected, message_opt);\r
+\r
+assert.deepEqual = function deepEqual(actual, expected, message) {\r
+  if (!_deepEqual(actual, expected)) {\r
+    fail(actual, expected, message, "deepEqual", assert.deepEqual);\r
+  }\r
+};\r
+\r
+var Buffer = null;\r
+if (typeof require !== 'undefined' && typeof process !== 'undefined') {\r
+    try {\r
+        Buffer = require('buffer').Buffer;\r
+    }\r
+    catch (e) {\r
+        // May be a CommonJS environment other than Node.js\r
+        Buffer = null;\r
+    }\r
+}\r
+\r
+function _deepEqual(actual, expected) {\r
+  // 7.1. All identical values are equivalent, as determined by ===.\r
+  if (actual === expected) {\r
+    return true;\r
+  // 7.2. If the expected value is a Date object, the actual value is\r
+  // equivalent if it is also a Date object that refers to the same time.\r
+  } else if (actual instanceof Date && expected instanceof Date) {\r
+    return actual.getTime() === expected.getTime();\r
+\r
+  // 7.2.1 If the expcted value is a RegExp object, the actual value is\r
+  // equivalent if it is also a RegExp object that refers to the same source and options\r
+  } else if (actual instanceof RegExp && expected instanceof RegExp) {\r
+    return actual.source === expected.source &&\r
+           actual.global === expected.global &&\r
+           actual.ignoreCase === expected.ignoreCase &&\r
+           actual.multiline === expected.multiline;\r
+\r
+  } else if (Buffer && actual instanceof Buffer && expected instanceof Buffer) {\r
+    return (function() {\r
+      var i, len;\r
+\r
+      for (i = 0, len = expected.length; i < len; i++) {\r
+        if (actual[i] !== expected[i]) {\r
+          return false;\r
+        }\r
+      }\r
+      return actual.length === expected.length;\r
+    })();\r
+  // 7.3. Other pairs that do not both pass typeof value == "object",\r
+  // equivalence is determined by ==.\r
+  } else if (typeof actual != 'object' && typeof expected != 'object') {\r
+    return actual == expected;\r
+\r
+  // 7.4. For all other Object pairs, including Array objects, equivalence is\r
+  // determined by having the same number of owned properties (as verified\r
+  // with Object.prototype.hasOwnProperty.call), the same set of keys\r
+  // (although not necessarily the same order), equivalent values for every\r
+  // corresponding key, and an identical "prototype" property. Note: this\r
+  // accounts for both named and indexed properties on Arrays.\r
+  } else {\r
+    return objEquiv(actual, expected);\r
+  }\r
+}\r
+\r
+function isUndefinedOrNull (value) {\r
+  return value === null || value === undefined;\r
+}\r
+\r
+function isArguments (object) {\r
+  return Object.prototype.toString.call(object) == '[object Arguments]';\r
+}\r
+\r
+function objEquiv (a, b) {\r
+  if (isUndefinedOrNull(a) || isUndefinedOrNull(b))\r
+    return false;\r
+  // an identical "prototype" property.\r
+  if (a.prototype !== b.prototype) return false;\r
+  //~~~I've managed to break Object.keys through screwy arguments passing.\r
+  //   Converting to array solves the problem.\r
+  if (isArguments(a)) {\r
+    if (!isArguments(b)) {\r
+      return false;\r
+    }\r
+    a = pSlice.call(a);\r
+    b = pSlice.call(b);\r
+    return _deepEqual(a, b);\r
+  }\r
+  try{\r
+    var ka = _keys(a),\r
+      kb = _keys(b),\r
+      key, i;\r
+  } catch (e) {//happens when one is a string literal and the other isn't\r
+    return false;\r
+  }\r
+  // having the same number of owned properties (keys incorporates hasOwnProperty)\r
+  if (ka.length != kb.length)\r
+    return false;\r
+  //the same set of keys (although not necessarily the same order),\r
+  ka.sort();\r
+  kb.sort();\r
+  //~~~cheap key test\r
+  for (i = ka.length - 1; i >= 0; i--) {\r
+    if (ka[i] != kb[i])\r
+      return false;\r
+  }\r
+  //equivalent values for every corresponding key, and\r
+  //~~~possibly expensive deep test\r
+  for (i = ka.length - 1; i >= 0; i--) {\r
+    key = ka[i];\r
+    if (!_deepEqual(a[key], b[key] ))\r
+       return false;\r
+  }\r
+  return true;\r
+}\r
+\r
+// 8. The non-equivalence assertion tests for any deep inequality.\r
+// assert.notDeepEqual(actual, expected, message_opt);\r
+\r
+assert.notDeepEqual = function notDeepEqual(actual, expected, message) {\r
+  if (_deepEqual(actual, expected)) {\r
+    fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual);\r
+  }\r
+};\r
+\r
+// 9. The strict equality assertion tests strict equality, as determined by ===.\r
+// assert.strictEqual(actual, expected, message_opt);\r
+\r
+assert.strictEqual = function strictEqual(actual, expected, message) {\r
+  if (actual !== expected) {\r
+    fail(actual, expected, message, "===", assert.strictEqual);\r
+  }\r
+};\r
+\r
+// 10. The strict non-equality assertion tests for strict inequality, as determined by !==.\r
+// assert.notStrictEqual(actual, expected, message_opt);\r
+\r
+assert.notStrictEqual = function notStrictEqual(actual, expected, message) {\r
+  if (actual === expected) {\r
+    fail(actual, expected, message, "!==", assert.notStrictEqual);\r
+  }\r
+};\r
+\r
+function expectedException(actual, expected) {\r
+  if (!actual || !expected) {\r
+    return false;\r
+  }\r
+\r
+  if (expected instanceof RegExp) {\r
+    return expected.test(actual.message || actual);\r
+  } else if (actual instanceof expected) {\r
+    return true;\r
+  } else if (expected.call({}, actual) === true) {\r
+    return true;\r
+  }\r
+\r
+  return false;\r
+}\r
+\r
+function _throws(shouldThrow, block, expected, message) {\r
+  var actual;\r
+\r
+  if (typeof expected === 'string') {\r
+    message = expected;\r
+    expected = null;\r
+  }\r
+\r
+  try {\r
+    block();\r
+  } catch (e) {\r
+    actual = e;\r
+  }\r
+\r
+  message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +\r
+            (message ? ' ' + message : '.');\r
+\r
+  if (shouldThrow && !actual) {\r
+    fail('Missing expected exception' + message);\r
+  }\r
+\r
+  if (!shouldThrow && expectedException(actual, expected)) {\r
+    fail('Got unwanted exception' + message);\r
+  }\r
+\r
+  if ((shouldThrow && actual && expected &&\r
+      !expectedException(actual, expected)) || (!shouldThrow && actual)) {\r
+    throw actual;\r
+  }\r
+}\r
+\r
+// 11. Expected to throw an error:\r
+// assert.throws(block, Error_opt, message_opt);\r
+\r
+assert.throws = function(block, /*optional*/error, /*optional*/message) {\r
+  _throws.apply(this, [true].concat(pSlice.call(arguments)));\r
+};\r
+\r
+// EXTENSION! This is annoying to write outside this module.\r
+assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {\r
+  _throws.apply(this, [false].concat(pSlice.call(arguments)));\r
+};\r
+\r
+assert.ifError = function (err) { if (err) {throw err;}};\r
+})(assert);\r
+(function(exports){\r
+/*!\r
+ * Nodeunit\r
+ * Copyright (c) 2010 Caolan McMahon\r
+ * MIT Licensed\r
+ *\r
+ * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!\r
+ * Only code on that line will be removed, it's mostly to avoid requiring code\r
+ * that is node specific\r
+ */\r
+\r
+/**\r
+ * Module dependencies\r
+ */\r
+\r
+\r
+\r
+/**\r
+ * Creates assertion objects representing the result of an assert call.\r
+ * Accepts an object or AssertionError as its argument.\r
+ *\r
+ * @param {object} obj\r
+ * @api public\r
+ */\r
+\r
+exports.assertion = function (obj) {\r
+    return {\r
+        method: obj.method || '',\r
+        message: obj.message || (obj.error && obj.error.message) || '',\r
+        error: obj.error,\r
+        passed: function () {\r
+            return !this.error;\r
+        },\r
+        failed: function () {\r
+            return Boolean(this.error);\r
+        }\r
+    };\r
+};\r
+\r
+/**\r
+ * Creates an assertion list object representing a group of assertions.\r
+ * Accepts an array of assertion objects.\r
+ *\r
+ * @param {Array} arr\r
+ * @param {Number} duration\r
+ * @api public\r
+ */\r
+\r
+exports.assertionList = function (arr, duration) {\r
+    var that = arr || [];\r
+    that.failures = function () {\r
+        var failures = 0;\r
+        for (var i = 0; i < this.length; i += 1) {\r
+            if (this[i].failed()) {\r
+                failures += 1;\r
+            }\r
+        }\r
+        return failures;\r
+    };\r
+    that.passes = function () {\r
+        return that.length - that.failures();\r
+    };\r
+    that.duration = duration || 0;\r
+    return that;\r
+};\r
+\r
+/**\r
+ * Create a wrapper function for assert module methods. Executes a callback\r
+ * after it's complete with an assertion object representing the result.\r
+ *\r
+ * @param {Function} callback\r
+ * @api private\r
+ */\r
+\r
+var assertWrapper = function (callback) {\r
+    return function (new_method, assert_method, arity) {\r
+        return function () {\r
+            var message = arguments[arity - 1];\r
+            var a = exports.assertion({method: new_method, message: message});\r
+            try {\r
+                assert[assert_method].apply(null, arguments);\r
+            }\r
+            catch (e) {\r
+                a.error = e;\r
+            }\r
+            callback(a);\r
+        };\r
+    };\r
+};\r
+\r
+/**\r
+ * Creates the 'test' object that gets passed to every test function.\r
+ * Accepts the name of the test function as its first argument, followed by\r
+ * the start time in ms, the options object and a callback function.\r
+ *\r
+ * @param {String} name\r
+ * @param {Number} start\r
+ * @param {Object} options\r
+ * @param {Function} callback\r
+ * @api public\r
+ */\r
+\r
+exports.test = function (name, start, options, callback) {\r
+    var expecting;\r
+    var a_list = [];\r
+\r
+    var wrapAssert = assertWrapper(function (a) {\r
+        a_list.push(a);\r
+        if (options.log) {\r
+            async.nextTick(function () {\r
+                options.log(a);\r
+            });\r
+        }\r
+    });\r
+\r
+    var test = {\r
+        done: function (err) {\r
+            if (expecting !== undefined && expecting !== a_list.length) {\r
+                var e = new Error(\r
+                    'Expected ' + expecting + ' assertions, ' +\r
+                    a_list.length + ' ran'\r
+                );\r
+                var a1 = exports.assertion({method: 'expect', error: e});\r
+                a_list.push(a1);\r
+                if (options.log) {\r
+                    async.nextTick(function () {\r
+                        options.log(a1);\r
+                    });\r
+                }\r
+            }\r
+            if (err) {\r
+                var a2 = exports.assertion({error: err});\r
+                a_list.push(a2);\r
+                if (options.log) {\r
+                    async.nextTick(function () {\r
+                        options.log(a2);\r
+                    });\r
+                }\r
+            }\r
+            var end = new Date().getTime();\r
+            async.nextTick(function () {\r
+                var assertion_list = exports.assertionList(a_list, end - start);\r
+                options.testDone(name, assertion_list);\r
+                callback(null, a_list);\r
+            });\r
+        },\r
+        ok: wrapAssert('ok', 'ok', 2),\r
+        same: wrapAssert('same', 'deepEqual', 3),\r
+        equals: wrapAssert('equals', 'equal', 3),\r
+        expect: function (num) {\r
+            expecting = num;\r
+        },\r
+        _assertion_list: a_list\r
+    };\r
+    // add all functions from the assert module\r
+    for (var k in assert) {\r
+        if (assert.hasOwnProperty(k)) {\r
+            test[k] = wrapAssert(k, k, assert[k].length);\r
+        }\r
+    }\r
+    return test;\r
+};\r
+\r
+/**\r
+ * Ensures an options object has all callbacks, adding empty callback functions\r
+ * if any are missing.\r
+ *\r
+ * @param {Object} opt\r
+ * @return {Object}\r
+ * @api public\r
+ */\r
+\r
+exports.options = function (opt) {\r
+    var optionalCallback = function (name) {\r
+        opt[name] = opt[name] || function () {};\r
+    };\r
+\r
+    optionalCallback('moduleStart');\r
+    optionalCallback('moduleDone');\r
+    optionalCallback('testStart');\r
+    optionalCallback('testDone');\r
+    //optionalCallback('log');\r
+\r
+    // 'done' callback is not optional.\r
+\r
+    return opt;\r
+};\r
+})(types);\r
+(function(exports){\r
+/*!\r
+ * Nodeunit\r
+ * Copyright (c) 2010 Caolan McMahon\r
+ * MIT Licensed\r
+ *\r
+ * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!\r
+ * Only code on that line will be removed, it's mostly to avoid requiring code\r
+ * that is node specific\r
+ */\r
+\r
+/**\r
+ * Module dependencies\r
+ */\r
+\r
+\r
+\r
+/**\r
+ * Added for browser compatibility\r
+ */\r
+\r
+var _keys = function (obj) {\r
+    if (Object.keys) {\r
+        return Object.keys(obj);\r
+    }\r
+    var keys = [];\r
+    for (var k in obj) {\r
+        if (obj.hasOwnProperty(k)) {\r
+            keys.push(k);\r
+        }\r
+    }\r
+    return keys;\r
+};\r
+\r
+\r
+var _copy = function (obj) {\r
+    var nobj = {};\r
+    var keys = _keys(obj);\r
+    for (var i = 0; i <  keys.length; i += 1) {\r
+        nobj[keys[i]] = obj[keys[i]];\r
+    }\r
+    return nobj;\r
+};\r
+\r
+\r
+/**\r
+ * Runs a test function (fn) from a loaded module. After the test function\r
+ * calls test.done(), the callback is executed with an assertionList as its\r
+ * second argument.\r
+ *\r
+ * @param {String} name\r
+ * @param {Function} fn\r
+ * @param {Object} opt\r
+ * @param {Function} callback\r
+ * @api public\r
+ */\r
+\r
+exports.runTest = function (name, fn, opt, callback) {\r
+    var options = types.options(opt);\r
+\r
+    options.testStart(name);\r
+    var start = new Date().getTime();\r
+    var test = types.test(name, start, options, callback);\r
+\r
+    try {\r
+        fn(test);\r
+    }\r
+    catch (e) {\r
+        test.done(e);\r
+    }\r
+};\r
+\r
+/**\r
+ * Takes an object containing test functions or other test suites as properties\r
+ * and runs each in series. After all tests have completed, the callback is\r
+ * called with a list of all assertions as the second argument.\r
+ *\r
+ * If a name is passed to this function it is prepended to all test and suite\r
+ * names that run within it.\r
+ *\r
+ * @param {String} name\r
+ * @param {Object} suite\r
+ * @param {Object} opt\r
+ * @param {Function} callback\r
+ * @api public\r
+ */\r
+\r
+exports.runSuite = function (name, suite, opt, callback) {\r
+    suite = wrapGroup(suite);\r
+    var keys = _keys(suite);\r
+\r
+    async.concatSeries(keys, function (k, cb) {\r
+        var prop = suite[k], _name;\r
+\r
+        _name = name ? [].concat(name, k) : [k];\r
+        _name.toString = function () {\r
+            // fallback for old one\r
+            return this.join(' - ');\r
+        };\r
+\r
+        if (typeof prop === 'function') {\r
+            var in_name = false,\r
+                in_specific_test = (_name.toString() === opt.testFullSpec) ? true : false;\r
+            for (var i = 0; i < _name.length; i += 1) {\r
+                if (_name[i] === opt.testspec) {\r
+                    in_name = true;\r
+                }\r
+            }\r
+\r
+            if ((!opt.testFullSpec || in_specific_test) && (!opt.testspec || in_name)) {\r
+                if (opt.moduleStart) {\r
+                    opt.moduleStart();\r
+                }\r
+                exports.runTest(_name, suite[k], opt, cb);\r
+            }\r
+            else {\r
+                return cb();\r
+            }\r
+        }\r
+        else {\r
+            exports.runSuite(_name, suite[k], opt, cb);\r
+        }\r
+    }, callback);\r
+};\r
+\r
+/**\r
+ * Run each exported test function or test suite from a loaded module.\r
+ *\r
+ * @param {String} name\r
+ * @param {Object} mod\r
+ * @param {Object} opt\r
+ * @param {Function} callback\r
+ * @api public\r
+ */\r
+\r
+exports.runModule = function (name, mod, opt, callback) {\r
+    var options = _copy(types.options(opt));\r
+\r
+    var _run = false;\r
+    var _moduleStart = options.moduleStart;\r
+\r
+    mod = wrapGroup(mod);\r
+\r
+    function run_once() {\r
+        if (!_run) {\r
+            _run = true;\r
+            _moduleStart(name);\r
+        }\r
+    }\r
+    options.moduleStart = run_once;\r
+\r
+    var start = new Date().getTime();\r
+\r
+    exports.runSuite(null, mod, options, function (err, a_list) {\r
+        var end = new Date().getTime();\r
+        var assertion_list = types.assertionList(a_list, end - start);\r
+        options.moduleDone(name, assertion_list);\r
+        if (nodeunit.complete) {\r
+            nodeunit.complete(name, assertion_list);\r
+        }\r
+        callback(null, a_list);\r
+    });\r
+};\r
+\r
+/**\r
+ * Treats an object literal as a list of modules keyed by name. Runs each\r
+ * module and finished with calling 'done'. You can think of this as a browser\r
+ * safe alternative to runFiles in the nodeunit module.\r
+ *\r
+ * @param {Object} modules\r
+ * @param {Object} opt\r
+ * @api public\r
+ */\r
+\r
+// TODO: add proper unit tests for this function\r
+exports.runModules = function (modules, opt) {\r
+    var all_assertions = [];\r
+    var options = types.options(opt);\r
+    var start = new Date().getTime();\r
+\r
+    async.concatSeries(_keys(modules), function (k, cb) {\r
+        exports.runModule(k, modules[k], options, cb);\r
+    },\r
+    function (err, all_assertions) {\r
+        var end = new Date().getTime();\r
+        options.done(types.assertionList(all_assertions, end - start));\r
+    });\r
+};\r
+\r
+\r
+/**\r
+ * Wraps a test function with setUp and tearDown functions.\r
+ * Used by testCase.\r
+ *\r
+ * @param {Function} setUp\r
+ * @param {Function} tearDown\r
+ * @param {Function} fn\r
+ * @api private\r
+ */\r
+\r
+var wrapTest = function (setUp, tearDown, fn) {\r
+    return function (test) {\r
+        var context = {};\r
+        if (tearDown) {\r
+            var done = test.done;\r
+            test.done = function (err) {\r
+                try {\r
+                    tearDown.call(context, function (err2) {\r
+                        if (err && err2) {\r
+                            test._assertion_list.push(\r
+                                types.assertion({error: err})\r
+                            );\r
+                            return done(err2);\r
+                        }\r
+                        done(err || err2);\r
+                    });\r
+                }\r
+                catch (e) {\r
+                    done(e);\r
+                }\r
+            };\r
+        }\r
+        if (setUp) {\r
+            setUp.call(context, function (err) {\r
+                if (err) {\r
+                    return test.done(err);\r
+                }\r
+                fn.call(context, test);\r
+            });\r
+        }\r
+        else {\r
+            fn.call(context, test);\r
+        }\r
+    };\r
+};\r
+\r
+\r
+/**\r
+ * Returns a serial callback from two functions.\r
+ *\r
+ * @param {Function} funcFirst\r
+ * @param {Function} funcSecond\r
+ * @api private\r
+ */\r
+\r
+var getSerialCallback = function (fns) {\r
+    if (!fns.length) {\r
+        return null;\r
+    }\r
+    return function (callback) {\r
+        var that = this;\r
+        var bound_fns = [];\r
+        for (var i = 0, len = fns.length; i < len; i++) {\r
+            (function (j) {\r
+                bound_fns.push(function () {\r
+                    return fns[j].apply(that, arguments);\r
+                });\r
+            })(i);\r
+        }\r
+        return async.series(bound_fns, callback);\r
+    };\r
+};\r
+\r
+\r
+/**\r
+ * Wraps a group of tests with setUp and tearDown functions.\r
+ * Used by testCase.\r
+ *\r
+ * @param {Object} group\r
+ * @param {Array} setUps - parent setUp functions\r
+ * @param {Array} tearDowns - parent tearDown functions\r
+ * @api private\r
+ */\r
+\r
+var wrapGroup = function (group, setUps, tearDowns) {\r
+    var tests = {};\r
+\r
+    var setUps = setUps ? setUps.slice(): [];\r
+    var tearDowns = tearDowns ? tearDowns.slice(): [];\r
+\r
+    if (group.setUp) {\r
+        setUps.push(group.setUp);\r
+        delete group.setUp;\r
+    }\r
+    if (group.tearDown) {\r
+        tearDowns.unshift(group.tearDown);\r
+        delete group.tearDown;\r
+    }\r
+\r
+    var keys = _keys(group);\r
+\r
+    for (var i = 0; i < keys.length; i += 1) {\r
+        var k = keys[i];\r
+        if (typeof group[k] === 'function') {\r
+            tests[k] = wrapTest(\r
+                getSerialCallback(setUps),\r
+                getSerialCallback(tearDowns),\r
+                group[k]\r
+            );\r
+        }\r
+        else if (typeof group[k] === 'object') {\r
+            tests[k] = wrapGroup(group[k], setUps, tearDowns);\r
+        }\r
+    }\r
+    return tests;\r
+};\r
+\r
+\r
+/**\r
+ * Backwards compatibility for test suites using old testCase API\r
+ */\r
+\r
+exports.testCase = function (suite) {\r
+    return suite;\r
+};\r
+})(core);\r
+(function(exports){\r
+/*!\r
+ * Nodeunit\r
+ * Copyright (c) 2010 Caolan McMahon\r
+ * MIT Licensed\r
+ *\r
+ * THIS FILE SHOULD BE BROWSER-COMPATIBLE JS!\r
+ * Only code on that line will be removed, its mostly to avoid requiring code\r
+ * that is node specific\r
+ */\r
+\r
+\r
+/**\r
+ * NOTE: this test runner is not listed in index.js because it cannot be\r
+ * used with the command-line tool, only inside the browser.\r
+ */\r
+\r
+\r
+/**\r
+ * Reporter info string\r
+ */\r
+\r
+exports.info = "Browser-based test reporter";\r
+\r
+\r
+/**\r
+ * Run all tests within each module, reporting the results\r
+ *\r
+ * @param {Array} files\r
+ * @api public\r
+ */\r
+\r
+exports.run = function (modules, options) {\r
+    var start = new Date().getTime(), div;\r
+       options = options || {};\r
+       div = options.div || document.body;\r
+\r
+    function setText(el, txt) {\r
+        if ('innerText' in el) {\r
+            el.innerText = txt;\r
+        }\r
+        else if ('textContent' in el){\r
+            el.textContent = txt;\r
+        }\r
+    }\r
+\r
+    function getOrCreate(tag, id) {\r
+        var el = document.getElementById(id);\r
+        if (!el) {\r
+            el = document.createElement(tag);\r
+            el.id = id;\r
+            div.appendChild(el);\r
+        }\r
+        return el;\r
+    };\r
+\r
+    var header = getOrCreate('h1', 'nodeunit-header');\r
+    var banner = getOrCreate('h2', 'nodeunit-banner');\r
+    var userAgent = getOrCreate('h2', 'nodeunit-userAgent');\r
+    var tests = getOrCreate('ol', 'nodeunit-tests');\r
+    var result = getOrCreate('p', 'nodeunit-testresult');\r
+\r
+    setText(userAgent, navigator.userAgent);\r
+\r
+    nodeunit.runModules(modules, {\r
+        moduleStart: function (name) {\r
+            /*var mheading = document.createElement('h2');\r
+            mheading.innerText = name;\r
+            results.appendChild(mheading);\r
+            module = document.createElement('ol');\r
+            results.appendChild(module);*/\r
+        },\r
+        testDone: function (name, assertions) {\r
+            var test = document.createElement('li');\r
+            var strong = document.createElement('strong');\r
+            strong.innerHTML = name + ' <b style="color: black;">(' +\r
+                '<b class="fail">' + assertions.failures() + '</b>, ' +\r
+                '<b class="pass">' + assertions.passes() + '</b>, ' +\r
+                assertions.length +\r
+            ')</b>';\r
+            test.className = assertions.failures() ? 'fail': 'pass';\r
+            test.appendChild(strong);\r
+\r
+            var aList = document.createElement('ol');\r
+            aList.style.display = 'none';\r
+            test.onclick = function () {\r
+                var d = aList.style.display;\r
+                aList.style.display = (d == 'none') ? 'block': 'none';\r
+            };\r
+            for (var i=0; i<assertions.length; i++) {\r
+                var li = document.createElement('li');\r
+                var a = assertions[i];\r
+                if (a.failed()) {\r
+                    li.innerHTML = (a.message || a.method || 'no message') +\r
+                        '<pre>' + (a.error.stack || a.error) + '</pre>';\r
+                    li.className = 'fail';\r
+                }\r
+                else {\r
+                    li.innerHTML = a.message || a.method || 'no message';\r
+                    li.className = 'pass';\r
+                }\r
+                aList.appendChild(li);\r
+            }\r
+            test.appendChild(aList);\r
+            tests.appendChild(test);\r
+        },\r
+        done: function (assertions) {\r
+            var end = new Date().getTime();\r
+            var duration = end - start;\r
+\r
+            var failures = assertions.failures();\r
+            banner.className = failures ? 'fail': 'pass';\r
+\r
+            result.innerHTML = 'Tests completed in ' + duration +\r
+                ' milliseconds.<br/><span class="passed">' +\r
+                assertions.passes() + '</span> assertions of ' +\r
+                '<span class="all">' + assertions.length + '<span> passed, ' +\r
+                assertions.failures() + ' failed.';\r
+        }\r
+    });\r
+};\r
+})(reporter);\r
+nodeunit = core;\r
+nodeunit.assert = assert;\r
+nodeunit.reporter = reporter;\r
+nodeunit.run = reporter.run;\r
+return nodeunit; })();\r