jQuery.json = {
    encode:function(value, replacer, space) {
  var i;
  gap = '';
  var indent = '';
  
  if (typeof space === 'number') {
   for (i = 0; i < space; i += 1) {
    indent += ' ';
   }
   
  } else if (typeof space === 'string') {
   indent = space;
  }
  
  rep = replacer;
  if (replacer && typeof replacer !== 'function' &&
    (typeof replacer !== 'object' ||
     typeof replacer.length !== 'number')) {
   throw new Error('JSON.encode');
  }
  
  return this.str('', {'': value});
    },
    
    decode:function(text, reviver) {
	  var j;
	  var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
	  
	  function walk(holder, key) {
	   var k, v, value = holder[key];
	   
	   if (value && typeof value === 'object') {
		for (k in value) {
		 if (Object.hasOwnProperty.call(value, k)) {
		  v = walk(value, k);
		  if (v !== undefined) {
		   value[k] = v;
		  } else {
		   delete value[k];
		  }
		 }
		}
	   }
	   return reviver.call(holder, key, value);
	  }
	  
	  cx.lastIndex = 0;
	  
	  if (cx.test(text)) {
	   text = text.replace(cx, function (a) {
		return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
	   });
	  }
	  
	  if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
	   j = eval('(' + text + ')');
	   return typeof reviver === 'function' ? walk({'': j}, '') : j;
	  }
	  
	  throw new SyntaxError('JSON.parse');
 },
 
    f:function(n) {
        return n < 10 ? '0' + n : n;
    },
 
 DateToJSON:function(key) {
  return this.getUTCFullYear() + '-' + this.f(this.getUTCMonth() + 1) + '-' + this.f(this.getUTCDate())      + 'T' + this.f(this.getUTCHours())     + ':' + this.f(this.getUTCMinutes())   + ':' + this.f(this.getUTCSeconds())   + 'Z';
 },
 
 StringToJSON:function(key) {
  return this.valueOf();
    },
    
    quote:function(string) {
        var meta = {'\b': '\\b','\t': '\\t','\n': '\\n','\f': '\\f','\r': '\\r','"' : '\\"','\\': '\\\\'};
        var escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
        
        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 + '"';
    },
    
    str:function(key, holder) {
        var indent='', gap = '', i, k, v, length, mind = gap, partial, value = holder[key];
        
        if (value && typeof value === 'object') {
            switch((typeof value)) {
             case 'date':
              this.DateToJSON(key);
              break;
             default:
              this.StringToJSON(key);
              break;
            }
        }
        
        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }
        switch (typeof value) {
         case 'string':
             return this.quote(value);
   case 'number':
             return isFinite(value) ? String(value) : 'null';
   case 'boolean':
   case 'null':
             return String(value);
         case 'object':
    if (!value) {
     return 'null';
    }
    gap += indent;
    partial = [];
    
    if (Object.prototype.toString.apply(value) === '[object Array]') {
     length = value.length;
     
     for (i = 0; i < length; i += 1) {
      partial[i] = this.str(i, value) || 'null';
     }
 
     v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']';
     gap = mind;
     return v;
    }
     
    if (rep && typeof rep === 'object') {
     length = rep.length;
     for (i = 0; i < length; i += 1) {
      k = rep[i];
      if (typeof k === 'string') {
       v = this.str(k, value);
       if (v) {
        partial.push(this.quote(k) + (gap ? ': ' : ':') + v);
       }
      }
     }
    } else {
     for (k in value) {
      if (Object.hasOwnProperty.call(value, k)) {
       v = this.str(k, value);
       if (v) {
        partial.push(this.quote(k) + (gap ? ': ' : ':') + v);
       }
      }
     }
    }

    v = partial.length === 0 ? '{}' :
     gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
       mind + '}' : '{' + partial.join(',') + '}';
    gap = mind;
    return v;
  }
 }
};

