﻿jQuery.extend({
    parseJSON: function(data) {
		if(!data || typeof data !== "string") {
			return null;
        }
		// Make sure leading/trailing whitespace is removed (IE can't handle it)
		var adaptedData = jQuery.trim(data);

		// Attempt to parse using the native JSON parser first
        if (window.JSON && window.JSON.parse) {
        	try {
            	return window.JSON.parse(adaptedData);
        	}
        	catch (e) {
        		var rCFinvalidplus	= /("[^"\\\r\n]*"\s*:|\[)\s*(\+)(\d+)\s*(,|})/g;
        		var rCFinvalid0		= /("[^"\\\r\n]*"\s*:|\[)\s*(0{2,})\s*(,|})/g;
        		var rCFinvalidDot	= /("[^"\\\r\n]*"\s*:|\[)\s*(\d+\.)\s*(,|})/g;
        		adaptedData = adaptedData.replace(rCFinvalidplus, "$1$3$4").replace(rCFinvalid0, "$1\"$2\"$3").replace(rCFinvalidDot, "$1\"$2\"$3");
                try {
                	return window.JSON.parse(adaptedData);
                }
                catch (e) {
                }
        	}
        }

		var rvalidchars = /^[\],:{}\s]*$/;
		var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;
		var rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g;
		var rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g;

		if (rvalidchars.test(adaptedData.replace(rvalidescape, "@").replace( rvalidtokens, "]" ).replace( rvalidbraces, ""))) {
        	return (new Function("return " + adaptedData))();
        }
		
        if('onerror' in window && 'function' === typeof window.onerror) {
            window.onerror("JSON parse error. Original JSON: " + data + ", Adapted JSON: " + adaptedData, document.URL, "?");
        } else {
            throw new Error("JSON parse error. Original JSON: " + data + ", Adapted JSON: " + adaptedData);
        }
    }
});

$.ajaxSetup({converters: {"* text": window.String, "text html": true, "text json": jQuery.parseJSON, "text xml": jQuery.parseXML}});