/*
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 2.8.1
*/
(function () { var l = YAHOO.lang, isFunction = l.isFunction, isObject = l.isObject, isArray = l.isArray, _toStr = Object.prototype.toString, Native = (YAHOO.env.ua.caja ? window : this).JSON, _UNICODE_EXCEPTIONS = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, _ESCAPES = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, _VALUES = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, _BRACKETS = /(?:^|:|,)(?:\s*\[)+/g, _UNSAFE = /^[\],:{}\s]*$/, _SPECIAL_CHARS = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, _CHARS = { "\b": "\\b", "\t": "\\t", "\n": "\\n", "\f": "\\f", "\r": "\\r", '"': '\\"', "\\": "\\\\" }, UNDEFINED = "undefined", OBJECT = "object", NULL = "null", STRING = "string", NUMBER = "number", BOOLEAN = "boolean", DATE = "date", _allowable = { "undefined": UNDEFINED, "string": STRING, "[object String]": STRING, "number": NUMBER, "[object Number]": NUMBER, "boolean": BOOLEAN, "[object Boolean]": BOOLEAN, "[object Date]": DATE, "[object RegExp]": OBJECT }, EMPTY = "", OPEN_O = "{", CLOSE_O = "}", OPEN_A = "[", CLOSE_A = "]", COMMA = ",", COMMA_CR = ",\n", CR = "\n", COLON = ":", COLON_SP = ": ", QUOTE = '"'; Native = _toStr.call(Native) === "[object JSON]" && Native; function _char(c) { if (!_CHARS[c]) { _CHARS[c] = "\\u" + ("0000" + (+(c.charCodeAt(0))).toString(16)).slice(-4); } return _CHARS[c]; } function _revive(data, reviver) { var walk = function (o, key) { var k, v, value = o[key]; if (value && typeof value === "object") { for (k in value) { if (l.hasOwnProperty(value, k)) { v = walk(value, k); if (v === undefined) { delete value[k]; } else { value[k] = v; } } } } return reviver.call(o, key, value); }; return typeof reviver === "function" ? walk({ "": data }, "") : data; } function _prepare(s) { return s.replace(_UNICODE_EXCEPTIONS, _char); } function _isSafe(str) { return l.isString(str) && _UNSAFE.test(str.replace(_ESCAPES, "@").replace(_VALUES, "]").replace(_BRACKETS, "")); } function _parse(s, reviver) { s = _prepare(s); if (_isSafe(s)) { return _revive(eval("(" + s + ")"), reviver); } throw new SyntaxError("JSON.parse"); } function _type(o) { var t = typeof o; return _allowable[t] || _allowable[_toStr.call(o)] || (t === OBJECT ? (o ? OBJECT : NULL) : UNDEFINED); } function _string(s) { return QUOTE + s.replace(_SPECIAL_CHARS, _char) + QUOTE; } function _indent(s, space) { return s.replace(/^/gm, space); } function _stringify(o, w, space) { if (o === undefined) { return undefined; } var replacer = isFunction(w) ? w : null, format = _toStr.call(space).match(/String|Number/) || [], _date = YAHOO.lang.JSON.dateToString, stack = [], tmp, i, len; if (replacer || !isArray(w)) { w = undefined; } if (w) { tmp = {}; for (i = 0, len = w.length; i < len; ++i) { tmp[w[i]] = true; } w = tmp; } space = format[0] === "Number" ? new Array(Math.min(Math.max(0, space), 10) + 1).join(" ") : (space || EMPTY).slice(0, 10); function _serialize(h, key) { var value = h[key], t = _type(value), a = [], colon = space ? COLON_SP : COLON, arr, i, keys, k, v; if (isObject(value) && isFunction(value.toJSON)) { value = value.toJSON(key); } else { if (t === DATE) { value = _date(value); } } if (isFunction(replacer)) { value = replacer.call(h, key, value); } if (value !== h[key]) { t = _type(value); } switch (t) { case DATE: case OBJECT: break; case STRING: return _string(value); case NUMBER: return isFinite(value) ? value + EMPTY : NULL; case BOOLEAN: return value + EMPTY; case NULL: return NULL; default: return undefined; } for (i = stack.length - 1; i >= 0; --i) { if (stack[i] === value) { throw new Error("JSON.stringify. Cyclical reference"); } } arr = isArray(value); stack.push(value); if (arr) { for (i = value.length - 1; i >= 0; --i) { a[i] = _serialize(value, i) || NULL; } } else { keys = w || value; i = 0; for (k in keys) { if (keys.hasOwnProperty(k)) { v = _serialize(value, k); if (v) { a[i++] = _string(k) + colon + v; } } } } stack.pop(); if (space && a.length) { return arr ? OPEN_A + CR + _indent(a.join(COMMA_CR), space) + CR + CLOSE_A : OPEN_O + CR + _indent(a.join(COMMA_CR), space) + CR + CLOSE_O; } else { return arr ? OPEN_A + a.join(COMMA) + CLOSE_A : OPEN_O + a.join(COMMA) + CLOSE_O; } } return _serialize({ "": o }, ""); } YAHOO.lang.JSON = { useNativeParse: !!Native, useNativeStringify: !!Native, isSafe: function (s) { return _isSafe(_prepare(s)); }, parse: function (s, reviver) { return Native && YAHOO.lang.JSON.useNativeParse ? Native.parse(s, reviver) : _parse(s, reviver); }, stringify: function (o, w, space) { return Native && YAHOO.lang.JSON.useNativeStringify ? Native.stringify(o, w, space) : _stringify(o, w, space); }, dateToString: function (d) { function _zeroPad(v) { return v < 10 ? "0" + v : v; } return d.getUTCFullYear() + "-" + _zeroPad(d.getUTCMonth() + 1) + "-" + _zeroPad(d.getUTCDate()) + "T" + _zeroPad(d.getUTCHours()) + COLON + _zeroPad(d.getUTCMinutes()) + COLON + _zeroPad(d.getUTCSeconds()) + "Z"; }, stringToDate: function (str) { var m = str.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{3}))?Z$/); if (m) { var d = new Date(); d.setUTCFullYear(m[1], m[2] - 1, m[3]); d.setUTCHours(m[4], m[5], m[6], (m[7] || 0)); return d; } return str; } }; YAHOO.lang.JSON.isValid = YAHOO.lang.JSON.isSafe; })(); YAHOO.register("json", YAHOO.lang.JSON, { version: "2.8.1", build: "19" });