| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770 | 
							- // json5.js
 
- // Modern JSON. See README.md for details.
 
- //
 
- // This file is based directly off of Douglas Crockford's json_parse.js:
 
- // https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js
 
- var JSON5 = (typeof exports === 'object' ? exports : {});
 
- JSON5.parse = (function () {
 
-     "use strict";
 
- // This is a function that can parse a JSON5 text, producing a JavaScript
 
- // data structure. It is a simple, recursive descent parser. It does not use
 
- // eval or regular expressions, so it can be used as a model for implementing
 
- // a JSON5 parser in other languages.
 
- // We are defining the function inside of another function to avoid creating
 
- // global variables.
 
-     var at,           // The index of the current character
 
-         lineNumber,   // The current line number
 
-         columnNumber, // The current column number
 
-         ch,           // The current character
 
-         escapee = {
 
-             "'":  "'",
 
-             '"':  '"',
 
-             '\\': '\\',
 
-             '/':  '/',
 
-             '\n': '',       // Replace escaped newlines in strings w/ empty string
 
-             b:    '\b',
 
-             f:    '\f',
 
-             n:    '\n',
 
-             r:    '\r',
 
-             t:    '\t'
 
-         },
 
-         ws = [
 
-             ' ',
 
-             '\t',
 
-             '\r',
 
-             '\n',
 
-             '\v',
 
-             '\f',
 
-             '\xA0',
 
-             '\uFEFF'
 
-         ],
 
-         text,
 
-         renderChar = function (chr) {
 
-             return chr === '' ? 'EOF' : "'" + chr + "'";
 
-         },
 
-         error = function (m) {
 
- // Call error when something is wrong.
 
-             var error = new SyntaxError();
 
-             // beginning of message suffix to agree with that provided by Gecko - see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
 
-             error.message = m + " at line " + lineNumber + " column " + columnNumber + " of the JSON5 data. Still to read: " + JSON.stringify(text.substring(at - 1, at + 19));
 
-             error.at = at;
 
-             // These two property names have been chosen to agree with the ones in Gecko, the only popular
 
-             // environment which seems to supply this info on JSON.parse
 
-             error.lineNumber = lineNumber;
 
-             error.columnNumber = columnNumber;
 
-             throw error;
 
-         },
 
-         next = function (c) {
 
- // If a c parameter is provided, verify that it matches the current character.
 
-             if (c && c !== ch) {
 
-                 error("Expected " + renderChar(c) + " instead of " + renderChar(ch));
 
-             }
 
- // Get the next character. When there are no more characters,
 
- // return the empty string.
 
-             ch = text.charAt(at);
 
-             at++;
 
-             columnNumber++;
 
-             if (ch === '\n' || ch === '\r' && peek() !== '\n') {
 
-                 lineNumber++;
 
-                 columnNumber = 0;
 
-             }
 
-             return ch;
 
-         },
 
-         peek = function () {
 
- // Get the next character without consuming it or
 
- // assigning it to the ch varaible.
 
-             return text.charAt(at);
 
-         },
 
-         identifier = function () {
 
- // Parse an identifier. Normally, reserved words are disallowed here, but we
 
- // only use this for unquoted object keys, where reserved words are allowed,
 
- // so we don't check for those here. References:
 
- // - http://es5.github.com/#x7.6
 
- // - https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Variables
 
- // - http://docstore.mik.ua/orelly/webprog/jscript/ch02_07.htm
 
- // TODO Identifiers can have Unicode "letters" in them; add support for those.
 
-             var key = ch;
 
-             // Identifiers must start with a letter, _ or $.
 
-             if ((ch !== '_' && ch !== '$') &&
 
-                     (ch < 'a' || ch > 'z') &&
 
-                     (ch < 'A' || ch > 'Z')) {
 
-                 error("Bad identifier as unquoted key");
 
-             }
 
-             // Subsequent characters can contain digits.
 
-             while (next() && (
 
-                     ch === '_' || ch === '$' ||
 
-                     (ch >= 'a' && ch <= 'z') ||
 
-                     (ch >= 'A' && ch <= 'Z') ||
 
-                     (ch >= '0' && ch <= '9'))) {
 
-                 key += ch;
 
-             }
 
-             return key;
 
-         },
 
-         number = function () {
 
- // Parse a number value.
 
-             var number,
 
-                 sign = '',
 
-                 string = '',
 
-                 base = 10;
 
-             if (ch === '-' || ch === '+') {
 
-                 sign = ch;
 
-                 next(ch);
 
-             }
 
-             // support for Infinity (could tweak to allow other words):
 
-             if (ch === 'I') {
 
-                 number = word();
 
-                 if (typeof number !== 'number' || isNaN(number)) {
 
-                     error('Unexpected word for number');
 
-                 }
 
-                 return (sign === '-') ? -number : number;
 
-             }
 
-             // support for NaN
 
-             if (ch === 'N' ) {
 
-               number = word();
 
-               if (!isNaN(number)) {
 
-                 error('expected word to be NaN');
 
-               }
 
-               // ignore sign as -NaN also is NaN
 
-               return number;
 
-             }
 
-             if (ch === '0') {
 
-                 string += ch;
 
-                 next();
 
-                 if (ch === 'x' || ch === 'X') {
 
-                     string += ch;
 
-                     next();
 
-                     base = 16;
 
-                 } else if (ch >= '0' && ch <= '9') {
 
-                     error('Octal literal');
 
-                 }
 
-             }
 
-             switch (base) {
 
-             case 10:
 
-                 while (ch >= '0' && ch <= '9' ) {
 
-                     string += ch;
 
-                     next();
 
-                 }
 
-                 if (ch === '.') {
 
-                     string += '.';
 
-                     while (next() && ch >= '0' && ch <= '9') {
 
-                         string += ch;
 
-                     }
 
-                 }
 
-                 if (ch === 'e' || ch === 'E') {
 
-                     string += ch;
 
-                     next();
 
-                     if (ch === '-' || ch === '+') {
 
-                         string += ch;
 
-                         next();
 
-                     }
 
-                     while (ch >= '0' && ch <= '9') {
 
-                         string += ch;
 
-                         next();
 
-                     }
 
-                 }
 
-                 break;
 
-             case 16:
 
-                 while (ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'F' || ch >= 'a' && ch <= 'f') {
 
-                     string += ch;
 
-                     next();
 
-                 }
 
-                 break;
 
-             }
 
-             if(sign === '-') {
 
-                 number = -string;
 
-             } else {
 
-                 number = +string;
 
-             }
 
-             if (!isFinite(number)) {
 
-                 error("Bad number");
 
-             } else {
 
-                 return number;
 
-             }
 
-         },
 
-         string = function () {
 
- // Parse a string value.
 
-             var hex,
 
-                 i,
 
-                 string = '',
 
-                 delim,      // double quote or single quote
 
-                 uffff;
 
- // When parsing for string values, we must look for ' or " and \ characters.
 
-             if (ch === '"' || ch === "'") {
 
-                 delim = ch;
 
-                 while (next()) {
 
-                     if (ch === delim) {
 
-                         next();
 
-                         return string;
 
-                     } else if (ch === '\\') {
 
-                         next();
 
-                         if (ch === 'u') {
 
-                             uffff = 0;
 
-                             for (i = 0; i < 4; i += 1) {
 
-                                 hex = parseInt(next(), 16);
 
-                                 if (!isFinite(hex)) {
 
-                                     break;
 
-                                 }
 
-                                 uffff = uffff * 16 + hex;
 
-                             }
 
-                             string += String.fromCharCode(uffff);
 
-                         } else if (ch === '\r') {
 
-                             if (peek() === '\n') {
 
-                                 next();
 
-                             }
 
-                         } else if (typeof escapee[ch] === 'string') {
 
-                             string += escapee[ch];
 
-                         } else {
 
-                             break;
 
-                         }
 
-                     } else if (ch === '\n') {
 
-                         // unescaped newlines are invalid; see:
 
-                         // https://github.com/aseemk/json5/issues/24
 
-                         // TODO this feels special-cased; are there other
 
-                         // invalid unescaped chars?
 
-                         break;
 
-                     } else {
 
-                         string += ch;
 
-                     }
 
-                 }
 
-             }
 
-             error("Bad string");
 
-         },
 
-         inlineComment = function () {
 
- // Skip an inline comment, assuming this is one. The current character should
 
- // be the second / character in the // pair that begins this inline comment.
 
- // To finish the inline comment, we look for a newline or the end of the text.
 
-             if (ch !== '/') {
 
-                 error("Not an inline comment");
 
-             }
 
-             do {
 
-                 next();
 
-                 if (ch === '\n' || ch === '\r') {
 
-                     next();
 
-                     return;
 
-                 }
 
-             } while (ch);
 
-         },
 
-         blockComment = function () {
 
- // Skip a block comment, assuming this is one. The current character should be
 
- // the * character in the /* pair that begins this block comment.
 
- // To finish the block comment, we look for an ending */ pair of characters,
 
- // but we also watch for the end of text before the comment is terminated.
 
-             if (ch !== '*') {
 
-                 error("Not a block comment");
 
-             }
 
-             do {
 
-                 next();
 
-                 while (ch === '*') {
 
-                     next('*');
 
-                     if (ch === '/') {
 
-                         next('/');
 
-                         return;
 
-                     }
 
-                 }
 
-             } while (ch);
 
-             error("Unterminated block comment");
 
-         },
 
-         comment = function () {
 
- // Skip a comment, whether inline or block-level, assuming this is one.
 
- // Comments always begin with a / character.
 
-             if (ch !== '/') {
 
-                 error("Not a comment");
 
-             }
 
-             next('/');
 
-             if (ch === '/') {
 
-                 inlineComment();
 
-             } else if (ch === '*') {
 
-                 blockComment();
 
-             } else {
 
-                 error("Unrecognized comment");
 
-             }
 
-         },
 
-         white = function () {
 
- // Skip whitespace and comments.
 
- // Note that we're detecting comments by only a single / character.
 
- // This works since regular expressions are not valid JSON(5), but this will
 
- // break if there are other valid values that begin with a / character!
 
-             while (ch) {
 
-                 if (ch === '/') {
 
-                     comment();
 
-                 } else if (ws.indexOf(ch) >= 0) {
 
-                     next();
 
-                 } else {
 
-                     return;
 
-                 }
 
-             }
 
-         },
 
-         word = function () {
 
- // true, false, or null.
 
-             switch (ch) {
 
-             case 't':
 
-                 next('t');
 
-                 next('r');
 
-                 next('u');
 
-                 next('e');
 
-                 return true;
 
-             case 'f':
 
-                 next('f');
 
-                 next('a');
 
-                 next('l');
 
-                 next('s');
 
-                 next('e');
 
-                 return false;
 
-             case 'n':
 
-                 next('n');
 
-                 next('u');
 
-                 next('l');
 
-                 next('l');
 
-                 return null;
 
-             case 'I':
 
-                 next('I');
 
-                 next('n');
 
-                 next('f');
 
-                 next('i');
 
-                 next('n');
 
-                 next('i');
 
-                 next('t');
 
-                 next('y');
 
-                 return Infinity;
 
-             case 'N':
 
-               next( 'N' );
 
-               next( 'a' );
 
-               next( 'N' );
 
-               return NaN;
 
-             }
 
-             error("Unexpected " + renderChar(ch));
 
-         },
 
-         value,  // Place holder for the value function.
 
-         array = function () {
 
- // Parse an array value.
 
-             var array = [];
 
-             if (ch === '[') {
 
-                 next('[');
 
-                 white();
 
-                 while (ch) {
 
-                     if (ch === ']') {
 
-                         next(']');
 
-                         return array;   // Potentially empty array
 
-                     }
 
-                     // ES5 allows omitting elements in arrays, e.g. [,] and
 
-                     // [,null]. We don't allow this in JSON5.
 
-                     if (ch === ',') {
 
-                         error("Missing array element");
 
-                     } else {
 
-                         array.push(value());
 
-                     }
 
-                     white();
 
-                     // If there's no comma after this value, this needs to
 
-                     // be the end of the array.
 
-                     if (ch !== ',') {
 
-                         next(']');
 
-                         return array;
 
-                     }
 
-                     next(',');
 
-                     white();
 
-                 }
 
-             }
 
-             error("Bad array");
 
-         },
 
-         object = function () {
 
- // Parse an object value.
 
-             var key,
 
-                 object = {};
 
-             if (ch === '{') {
 
-                 next('{');
 
-                 white();
 
-                 while (ch) {
 
-                     if (ch === '}') {
 
-                         next('}');
 
-                         return object;   // Potentially empty object
 
-                     }
 
-                     // Keys can be unquoted. If they are, they need to be
 
-                     // valid JS identifiers.
 
-                     if (ch === '"' || ch === "'") {
 
-                         key = string();
 
-                     } else {
 
-                         key = identifier();
 
-                     }
 
-                     white();
 
-                     next(':');
 
-                     object[key] = value();
 
-                     white();
 
-                     // If there's no comma after this pair, this needs to be
 
-                     // the end of the object.
 
-                     if (ch !== ',') {
 
-                         next('}');
 
-                         return object;
 
-                     }
 
-                     next(',');
 
-                     white();
 
-                 }
 
-             }
 
-             error("Bad object");
 
-         };
 
-     value = function () {
 
- // Parse a JSON value. It could be an object, an array, a string, a number,
 
- // or a word.
 
-         white();
 
-         switch (ch) {
 
-         case '{':
 
-             return object();
 
-         case '[':
 
-             return array();
 
-         case '"':
 
-         case "'":
 
-             return string();
 
-         case '-':
 
-         case '+':
 
-         case '.':
 
-             return number();
 
-         default:
 
-             return ch >= '0' && ch <= '9' ? number() : word();
 
-         }
 
-     };
 
- // Return the json_parse function. It will have access to all of the above
 
- // functions and variables.
 
-     return function (source, reviver) {
 
-         var result;
 
-         text = String(source);
 
-         at = 0;
 
-         lineNumber = 1;
 
-         columnNumber = 1;
 
-         ch = ' ';
 
-         result = value();
 
-         white();
 
-         if (ch) {
 
-             error("Syntax error");
 
-         }
 
- // If there is a reviver function, we recursively walk the new structure,
 
- // passing each name/value pair to the reviver function for possible
 
- // transformation, starting with a temporary root object that holds the result
 
- // in an empty key. If there is not a reviver function, we simply return the
 
- // result.
 
-         return typeof reviver === 'function' ? (function walk(holder, key) {
 
-             var k, v, value = holder[key];
 
-             if (value && typeof value === 'object') {
 
-                 for (k in value) {
 
-                     if (Object.prototype.hasOwnProperty.call(value, k)) {
 
-                         v = walk(value, k);
 
-                         if (v !== undefined) {
 
-                             value[k] = v;
 
-                         } else {
 
-                             delete value[k];
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             return reviver.call(holder, key, value);
 
-         }({'': result}, '')) : result;
 
-     };
 
- }());
 
- // JSON5 stringify will not quote keys where appropriate
 
- JSON5.stringify = function (obj, replacer, space) {
 
-     if (replacer && (typeof(replacer) !== "function" && !isArray(replacer))) {
 
-         throw new Error('Replacer must be a function or an array');
 
-     }
 
-     var getReplacedValueOrUndefined = function(holder, key, isTopLevel) {
 
-         var value = holder[key];
 
-         // Replace the value with its toJSON value first, if possible
 
-         if (value && value.toJSON && typeof value.toJSON === "function") {
 
-             value = value.toJSON();
 
-         }
 
-         // If the user-supplied replacer if a function, call it. If it's an array, check objects' string keys for
 
-         // presence in the array (removing the key/value pair from the resulting JSON if the key is missing).
 
-         if (typeof(replacer) === "function") {
 
-             return replacer.call(holder, key, value);
 
-         } else if(replacer) {
 
-             if (isTopLevel || isArray(holder) || replacer.indexOf(key) >= 0) {
 
-                 return value;
 
-             } else {
 
-                 return undefined;
 
-             }
 
-         } else {
 
-             return value;
 
-         }
 
-     };
 
-     function isWordChar(c) {
 
-         return (c >= 'a' && c <= 'z') ||
 
-             (c >= 'A' && c <= 'Z') ||
 
-             (c >= '0' && c <= '9') ||
 
-             c === '_' || c === '$';
 
-     }
 
-     function isWordStart(c) {
 
-         return (c >= 'a' && c <= 'z') ||
 
-             (c >= 'A' && c <= 'Z') ||
 
-             c === '_' || c === '$';
 
-     }
 
-     function isWord(key) {
 
-         if (typeof key !== 'string') {
 
-             return false;
 
-         }
 
-         if (!isWordStart(key[0])) {
 
-             return false;
 
-         }
 
-         var i = 1, length = key.length;
 
-         while (i < length) {
 
-             if (!isWordChar(key[i])) {
 
-                 return false;
 
-             }
 
-             i++;
 
-         }
 
-         return true;
 
-     }
 
-     // export for use in tests
 
-     JSON5.isWord = isWord;
 
-     // polyfills
 
-     function isArray(obj) {
 
-         if (Array.isArray) {
 
-             return Array.isArray(obj);
 
-         } else {
 
-             return Object.prototype.toString.call(obj) === '[object Array]';
 
-         }
 
-     }
 
-     function isDate(obj) {
 
-         return Object.prototype.toString.call(obj) === '[object Date]';
 
-     }
 
-     var objStack = [];
 
-     function checkForCircular(obj) {
 
-         for (var i = 0; i < objStack.length; i++) {
 
-             if (objStack[i] === obj) {
 
-                 throw new TypeError("Converting circular structure to JSON");
 
-             }
 
-         }
 
-     }
 
-     function makeIndent(str, num, noNewLine) {
 
-         if (!str) {
 
-             return "";
 
-         }
 
-         // indentation no more than 10 chars
 
-         if (str.length > 10) {
 
-             str = str.substring(0, 10);
 
-         }
 
-         var indent = noNewLine ? "" : "\n";
 
-         for (var i = 0; i < num; i++) {
 
-             indent += str;
 
-         }
 
-         return indent;
 
-     }
 
-     var indentStr;
 
-     if (space) {
 
-         if (typeof space === "string") {
 
-             indentStr = space;
 
-         } else if (typeof space === "number" && space >= 0) {
 
-             indentStr = makeIndent(" ", space, true);
 
-         } else {
 
-             // ignore space parameter
 
-         }
 
-     }
 
-     // Copied from Crokford's implementation of JSON
 
-     // See https://github.com/douglascrockford/JSON-js/blob/e39db4b7e6249f04a195e7dd0840e610cc9e941e/json2.js#L195
 
-     // Begin
 
-     var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
 
-         escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
 
-         meta = { // table of character substitutions
 
-         '\b': '\\b',
 
-         '\t': '\\t',
 
-         '\n': '\\n',
 
-         '\f': '\\f',
 
-         '\r': '\\r',
 
-         '"' : '\\"',
 
-         '\\': '\\\\'
 
-     };
 
-     function escapeString(string) {
 
- // If the string contains no control characters, no quote characters, and no
 
- // backslash characters, then we can safely slap some quotes around it.
 
- // Otherwise we must also replace the offending characters with safe escape
 
- // sequences.
 
-         escapable.lastIndex = 0;
 
-         return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
 
-             var c = meta[a];
 
-             return typeof c === 'string' ?
 
-                 c :
 
-                 '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
 
-         }) + '"' : '"' + string + '"';
 
-     }
 
-     // End
 
-     function internalStringify(holder, key, isTopLevel) {
 
-         var buffer, res;
 
-         // Replace the value, if necessary
 
-         var obj_part = getReplacedValueOrUndefined(holder, key, isTopLevel);
 
-         if (obj_part && !isDate(obj_part)) {
 
-             // unbox objects
 
-             // don't unbox dates, since will turn it into number
 
-             obj_part = obj_part.valueOf();
 
-         }
 
-         switch(typeof obj_part) {
 
-             case "boolean":
 
-                 return obj_part.toString();
 
-             case "number":
 
-                 if (isNaN(obj_part) || !isFinite(obj_part)) {
 
-                     return "null";
 
-                 }
 
-                 return obj_part.toString();
 
-             case "string":
 
-                 return escapeString(obj_part.toString());
 
-             case "object":
 
-                 if (obj_part === null) {
 
-                     return "null";
 
-                 } else if (isArray(obj_part)) {
 
-                     checkForCircular(obj_part);
 
-                     buffer = "[";
 
-                     objStack.push(obj_part);
 
-                     for (var i = 0; i < obj_part.length; i++) {
 
-                         res = internalStringify(obj_part, i, false);
 
-                         buffer += makeIndent(indentStr, objStack.length);
 
-                         if (res === null || typeof res === "undefined") {
 
-                             buffer += "null";
 
-                         } else {
 
-                             buffer += res;
 
-                         }
 
-                         if (i < obj_part.length-1) {
 
-                             buffer += ",";
 
-                         } else if (indentStr) {
 
-                             buffer += "\n";
 
-                         }
 
-                     }
 
-                     objStack.pop();
 
-                     if (obj_part.length) {
 
-                         buffer += makeIndent(indentStr, objStack.length, true)
 
-                     }
 
-                     buffer += "]";
 
-                 } else {
 
-                     checkForCircular(obj_part);
 
-                     buffer = "{";
 
-                     var nonEmpty = false;
 
-                     objStack.push(obj_part);
 
-                     for (var prop in obj_part) {
 
-                         if (obj_part.hasOwnProperty(prop)) {
 
-                             var value = internalStringify(obj_part, prop, false);
 
-                             isTopLevel = false;
 
-                             if (typeof value !== "undefined" && value !== null) {
 
-                                 buffer += makeIndent(indentStr, objStack.length);
 
-                                 nonEmpty = true;
 
-                                 key = isWord(prop) ? prop : escapeString(prop);
 
-                                 buffer += key + ":" + (indentStr ? ' ' : '') + value + ",";
 
-                             }
 
-                         }
 
-                     }
 
-                     objStack.pop();
 
-                     if (nonEmpty) {
 
-                         buffer = buffer.substring(0, buffer.length-1) + makeIndent(indentStr, objStack.length) + "}";
 
-                     } else {
 
-                         buffer = '{}';
 
-                     }
 
-                 }
 
-                 return buffer;
 
-             default:
 
-                 // functions and undefined should be ignored
 
-                 return undefined;
 
-         }
 
-     }
 
-     // special case...when undefined is used inside of
 
-     // a compound object/array, return null.
 
-     // but when top-level, return undefined
 
-     var topLevelHolder = {"":obj};
 
-     if (obj === undefined) {
 
-         return getReplacedValueOrUndefined(topLevelHolder, '', true);
 
-     }
 
-     return internalStringify(topLevelHolder, '', true);
 
- };
 
 
  |