/**
 * Extensions of "jQuery" framework
 * Author 2007-2008 Oleg V. Lubarsky aka Dr.LOV
 * Copyright (c) 2008 CREATIVE ZONE Studio (http://www.cz-site.com/)
 */




/** 
 * Errors v1.03 : handling and triggering errors
 *
 */
(function() { 
	var $$ = $.errors = {
		index     : "index.php",
		log       : [],
		debug     : true,
		trigger   : function (errno, errmsg) {
			if (!errno) errno = $$.UNKNOWN;
			if (errno==$$.UNKNOWN || !errmsg) errmsg = "In the site has occurred error";
			if (errno==$$.WARNING || errno==$$.NOTICE) {
				var s = "Warning!\n\n";
				s += errmsg+"\n\n";
			} else {
				var s = "ERROR!\n\n";
				s += "[ "+errmsg+" ]\n\n";
				if (errno==$$.FATAL) s += "Attention - the site will reload.\n";
				else  s += "Attention - the site may work incorrectly.\n";
			}
			alert(s);
			$$.log.push({errno:errno, errmsg:errmsg});
			if (errno==$$.FATAL) top.window.location=$$.index;
		},
		_onerror : function (errmsg, errfile, errline) {
			var s = '"'+errmsg +'" in file "'+errfile+'" [line:'+errline+']';
			$$.trigger($$.PARSE,s)
		}
	};
	$$.UNKNOWN   = 1;
	$$.PARSE     = 2;
	$$.ERROR     = 4;
	$$.FATAL     = 8;
	$$.WARNING   = 16;
	$$.NOTICE    = 32;
	if (!$$.debug) window.onerror = function(errmsg, errfile, errline){$$._onerror(errmsg, errfile, errline); return true;};
})();



/**
 * Misc func
 */
(function(){
 	$.min = function (){
		var r = Infinity;
		for( var i=0; i<arguments.length; i++ ) {
			var n = arguments[i];
			if (n && n<r) r = n;
		}
		return r;
	}
 	$.max = function (){
		var r = -Infinity;
		for( var i=0; i<arguments.length; i++ ) {
			var n = arguments[i];
			if (n && n>r) r = n;
		}
		return r;
	}

	$.debugalert = function(o) {
		var s="";
		if (typeof o == "object") {
			try { 
				for (var i in o) {
					try { 
						s+= i+" : "+o[i]+"\n";
					} catch(e) {
						 s+= i+" : **error**\n";
					}
				}
			} catch(e) {
				 s+= "\n**error**\n";
			}
		} else s = o;
		alert(s);
	}

	$._trim = $.trim;
	$.trim_re  = new RegExp('^[ \t\n\r]*|[ \t\n\r]*$',"g");
	$.ltrim_re = new RegExp('^[ \t\n\r]*',"g");
	$.rtrim_re = new RegExp('[ \t\n\r]*$',"g");
	$.trim = function(s,chars)	{
		s = s || "";
		if (!chars) return s.replace($.trim_re, "");
		return $.rtrim($.ltrim(s,chars),chars);
	}
	$.ltrim = function(s,chars) {
		var re;
		s = s || "";
		if (!chars) re = $.ltrim_re;
		else re = new RegExp('^['+chars+']*',"g");
		return s.replace(re, "");
	}
	$.rtrim = function(s,chars) {
		var re;
		s = s || "";
		if (!chars) re = $.rtrim_re;
		else re = new RegExp('['+chars+']*$',"g");
		return s.replace(re, "");
	}
	
	$.addslashes = function (s) {
		s = s.replace(/\'/g,'\\\'');
		s = s.replace(/\"/g,'\\"');
		//s = s.replace(/\\/g,'\\\\');
		s = s.replace(/\0/g,'\\0');
		return s;
	}
	$.stripslashes = function (str) {
		s = s.replace(/\\'/g,'\'');
		s = s.replace(/\\"/g,'"');
		//s = s.replace(/\\\\/g,'\\');
		s = s.replace(/\\0/g,'\0');
		return s;
	}	
	
	$.dec2hex = function(dec) {
		var h = "0123456789ABCDEF";
		if (dec==null) return "00";
		dec = parseInt(dec);
		if (dec==0 || isNaN(dec)) return "00";
		dec = Math.max(0, dec);
		dec = Math.min(dec, 255);
		return h.charAt((dec - dec%16) / 16) + h.charAt(dec%16);
	};

	$.color2hex = function(color) {
		if (!color) { return false; }
		if (color.search('rgb') > -1) {
			color = color.substr(4,color.length-5).split(', ');
			color = $.dec2hex(color[0]) + $.dec2hex(color[1]) + $.dec2hex(color[2]);
		}
		color = color.replace('#','');
		if (color.length < 6) {
			color = color.substr(0, 1) + color.substr(0, 1) + color.substr(1, 1) + color.substr(1, 1) + color.substr(2, 1) + color.substr(2, 1);
		}
		return color;
	};

    $.Utf8_encode = function (str) {
        str = str.replace(/\r\n/g,"\n");
        var utftext = "";
        for (var n = 0; n < str.length; n++) {
            var c = str.charCodeAt(n);
            if (c < 128) {
                utftext += String.fromCharCode(c);
            } else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            } else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }
        }
        return utftext;
    };

    $.Utf8_decode = function (utftext) {
        var str = "";
        var i = 0;
        var c = c1 = c2 = 0;
        while ( i < utftext.length ) {
            c = utftext.charCodeAt(i);
            if (c < 128) {
                str += String.fromCharCode(c);
                i++;
            } else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                str += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            } else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                str += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }
        }
        return str;
    };

	$.fn.extend({
		swapClass: function(c1, c2) {
			return this.each(function() {
				if ($(this).is("."+c1))
					$(this).removeClass(c1).addClass(c2);
				else if ($(this).is("."+c2))
					$(this).removeClass(c2).addClass(c1);
			});
		},
		replaceClass: function(c1, c2) {
			return this.each(function() {
				if ($(this).is("."+c1))
					$(this).removeClass(c1).addClass(c2);
			});
		},
		setClass: function(c) {
			return this.each(function() {
				this.className = c;
			});
		}
	});

})();

(function(){
	var $$ = $.Timemeter = {
		_arr  : [],
		push  : function (){
			$$._arr.push((new Date()).getTime());
		},
		pop   : function (){
			if ($$._arr.length==0) return 0;
			return (new Date()).getTime()-$$._arr.pop();
		}
	}
})();






/**
 * Browser v1.01 : Extend jQuery's browser detection
 * 
 * Based on:
 *   jQBrowser v0.2 (http://davecardwell.co.uk/geekery/javascript/jquery/jqbrowser/)
 */
(function(){
	var $b = $.browser;
	$.extend($b, {id:"Unknown", name:"Unknown", langid:"en", version:0.0, url:"about:blank"});
	var $p = $.platform = {id:"Unknown", name:"Unknown", url:"about:blank"};
	var ua = navigator.userAgent, ve = navigator.vendor, pl = navigator.platform;
	var bdata = [
                {           url: "http://www.microsoft.com/windows/ie/",
                             id: 'msie',
                           name: 'Internet Explorer',
                        browser: function() { return /msie/i.test(ua) && !/opera/i.test(ua) },
                        version: function() { return ua.match(/MSIE (\d+(?:\.\d+)+(?:b\d*)?)/) }
                },
                {          url: "http://www.opera.com/",
                          name: 'Opera',
                       browser: function() { return /opera/i.test(ua) }
                },
                {           url: "http://www.mozilla.org/",
                           name: "Mozilla",
                        browser: function() { return /mozilla/i.test(ua) && !/(compatible|webkit)/i.test(ua) }
                        /*version: function() { return ua.match(/rv:(\d+(?:\.\d+)+)/) }*/ // includide for compatibility 
                },
                {           url: "http://www.mozilla.com/firefox/",
                           name: 'Firefox',
                        browser: function() { return /Firefox/i.test(ua) }
                },
                {          url: "http://www.apple.com/safari/",
                          name: "Safari",
                       browser: function() { return /Apple/i.test(ve) }
                },
                {           url: "http://www.icab.de/",
                           name: "iCab",
                        browser: function() { return /iCab/i.test(ve) }
                },
                {           url: "http://www.konqueror.org/",
                           name: "Konqueror",
                        browser: function() { return /KDE/i.test(ve) }
                },
                {           url: "http://downloads.channel.aol.com/browser/",
                             id: "aol",
                           name: "AOL Explorer",
                        browser: function() { return /America Online Browser/i.test(ua) },
                        version: function() { return ua.match(/rev(\d+(?:\.\d+)+)/) }
                },
                {           url: "http://www.flock.com/",
                           name: "Flock",
                        browser: function() { return /Flock/i.test(ua) }
                },
                {           url: "http://www.caminobrowser.org/",
                           name: "Camino",
                        browser: function() { return /Camino/i.test(ve) }
                },
                {           url: "http://browser.netscape.com/",
                           name: "Netscape",
                        browser: function() { return /Netscape/i.test(ua) }
                }
			];
	var odata = [
                {           url: "http://www.microsoft.com/windows/",
                             id: "win",
                           name: "Windows",
                             OS: function() { return /Win/i.test(pl) }
                },
                {           url: "http://www.apple.com/macos/",
                           name: "Mac",
                             OS: function() { return /Mac/i.test(pl) }
                },
                {           url: "http://www.linux.org/",
                           name: 'Linux',
                             OS: function() { return /Linux/i.test(pl) }
                }
			];
	var lang = navigator.language || navigator.userLanguage || "en";
	lang = lang.match(/([a-z]{2})/);
	if (lang) $b.langid = lang[1];
	for (var i=0; i<bdata.length; i++) {
		var id = bdata[i].id ? bdata[i].id : bdata[i].name.toLowerCase();
		$b[id] = false;
		if (bdata[i].browser()) {
			$b[id] = true;
			$b.name = bdata[i].name;
			$b.id = id;
			$b.url = bdata[i].url;
			var ver;
			if (bdata[i].version && (ver=bdata[i].version())) {
				ver = ver[1];
			} else {
				var re = new RegExp(bdata[i].name + '(?:\\s|\\/)(\\d+(?:\\.\\d+)+(?:(?:a|b)\\d*)?)');
				ver = ua.match(re);
				if (ver) ver = ver[1]
            }
			if (ver) $b.version = parseFloat(ver);
		}
	}
	$b.msie6 = ($.browser.msie && $.browser.version<7.0);
	for (var i=0; i<odata.length; i++) {
		var id = odata[i].id ? odata[i].id : odata[i].name.toLowerCase();
		$p[id] = false;
		if (odata[i].OS()) {
			$p[id] = true;
			$p.name = odata[i].name;
			$p.id = id;
			$p.url = odata[i].url;
        }
    }
})();



/** 
 * Metadata v1.7: parsing metadata from elements
 * 
 * @usage:
 *   $.metaData.setType("attr", "data"); // set default type metadata source
 *   <p id="one" data="{item_id: 1, item_label: 'Label'}">This is a p</p>
 *   alert ( $("#one").metaData(0).item_id ); // echo 1
 *   alert ( $("#one").metaData().item_id );  // echo 1
 *   $("#one").metaData(0).item_id = 2;
 *   alert ( $("#one").metaData(0).item_id ); // echo 2
 * @usage:
 *   <p id="one" class="some_class {item_id: 1, item_label: 'Label'}">This is a p</p>
 *   alert ( $("#one").metaData(0,"class").item_id ); // echo 1, temporary type source is "class"
 * @usage:
 *   $.metaData.setType("elem","script"); // set default type metadata source
 *   <p id="one"><script>var s={item_id: 1, item_label: 'Label'}</script></p>
 *   alert ( $("#one").metaData(0).item_id ); // echo 1
 *
 * Inspired by:
 *   Metadata - John Resig, Yehuda Katz, Jörn Zaefferer
 */
(function() {
	var $$ = $.metaData = {
		type: "class",
		name: "data", // if type 'attr' name of atrribute
		single: 'metaData',
		setType: function(type,name,single) {
			$$.type = type;
			$$.name = name;
			$$.single = single;
		}
	};
	$.fn.extend({
		metaData: function(index,type,name,single) {
			var _getData = function(s){
				//m = /({.*})/.exec(s);	//if (m) return m ? m[1] : "";
				var sp = s.indexOf("{");
				var ep = s.lastIndexOf("}");
				return (sp>=0 && ep>=0) ? s.substr(sp,ep-sp+1) : "";
			};
			if (typeof(index)=="string") {
				single = name;
				name = type;
				type = index;
				index = 0;
			}
			index = index || 0;
			type = type || $$.type;
			name = name || $$.name;
			single = single || $$.single;
			this.each(function() {
				if (this[single]) return;
				var m, data="";
				if (type == "class") {
					data = _getData(this.className);
				} else if (type == "elem") {
					m = $($(name,this)[0]).html();
					if (m) data = _getData(m);
				} else { // attr
					m = $(this).attr(name);
					if (m) data = m;
				}
				if (data.charAt(0)!="{") data = "{"+data+"}";
				this[single] = $.parseJSON(data,{});
			});
			return this[index][single];
		}
	});
})();


 
/**
 * URL v1.4: Manipulations with url
 * 
 * @func getParam : return GET paramenter if exist in url or null
 * @usage:
 *   $.URL.getParam("myparam");
 *   $.URL.getParam("myparam","www.mylink.com?myparam=123#2"); // return 123
 * @func addParam : add GET parameters
 * @usage:
 *   $.URL.addParam("www.mylink.com?myparam=123#2",{a:654}); // return www.mylink.com?myparam=123&a=654#2
 * @func addUNI : add GET parameter "UNI" with unique number identifier
 * @usage:
 *   $.URL.addUNI("www.mylink.com?myparam=123#2"); // return www.mylink.com?myparam=123&_UNI_=1173290768593#2
 */
(function(){
	var $$ = $.URL = {
		getParam : function (pname, url){
			url = (url || window.location).toString();
			url = unescape(url.split("#")[0]);
			var sret = null, n;
			if ( (n=url.indexOf("?")) > -1 ) {
				var ap = (url.substr(n+1)).split("&");
				for ( var i=0; i<ap.length; i++ ){
					if (ap[i].substr(0,pname.length)==pname) {
						var a = ap[i].split("=");
						if (a.length==2) sret=a[1]; else sret="";
						break;
					}
				}
			}
			return sret;
		},
		addParam : function (url,params){
			var p=[];
			for (var i in params) {
				p.push({name: i, value: params[i]});
			}
			var a = url.toString().split("#");
			a[1] = (a.length==2)?"#"+a[1]:"";
			return a[0]+((a[0].indexOf("?")>0)?"&":"?")+$.param(p)+a[1];
		},
		addUNI : function (url){
			return $$.addParam(url,{"_UNI_":(new Date()).getTime()});
		},
		delHost : function (url,host){
			if (!host) host = location.protocol+"//"+location.host+"/";
			return url.replace(host,"");
		}
	}
})();



/** 
 * Flash v1.61: Flash player detection and embed
 * 
 * @usage:
 *   fo = new $.Flash({url:"myflash.swf",id:"myid",width:"100px",height:"100px"},{myvar1: "some data", myvar2: "same data"})
 *   fo.write("div2");
 *    or
 *   $("#mydivid").Flash({"myflash.swf",id:"myid",width:"100px",height:"100px", version:8, expressinstall:true},{myvar1: "some data", myvar2: "same data"});
 * @return: 
 *   true if write swf html, false if not
 *
 * Inspired by:
 *   SWFObject (http://blog.deconcept.com/swfobject/)
 *   jQuery.Flash (http://jquery.lukelutman.com/plugins/flash)
 */
(function(){
	var $$ = $.Flash = function(a,v) {
		this.attr = $.extend({}, $$.attr, a);
		this.vars = $.extend({}, $$.vars, v);
	};
	$$.attr = {url:"", id:"", width:0, height:0, bgcolor:"#ffffff", menu:false, quality:"high", transparent:false, nocache:false, version:0, expressinstall:false, expressurl:"/framework/media/expressinstall.swf", MMredirectURL:document.location, MMdoctitle:(document.title.slice(0,47)+" - Flash Player Installation")};
	$$.vars = {};
	$$.skipdetect = $.URL.getParam("detectflash")=="false";
	$.fn.extend({
		Flash: function(a,v) {
			return (new $$(a,v)).write(this);
		}
	});
	$$.getVersion = function() {
		try {
			try {
				var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
				try { axo.AllowScriptAccess = "always"; } 
				catch(e) { return [6,0,21]; }				
			} catch(e) {}
			return (new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version").replace(/\D+/g, ",").match(/^,?(.+),?$/)[1]).split(",");
		} catch(e) {
			try {
				if (navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){
					return ((navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1]).split(",");
				}
			} catch(e) {}		
		}
		return [0,0,0];
	};
	$$.isValidVersion = function(rv) {
		if (typeof rv != "object") rv = [rv];
		var cv = $$.getVersion();
		for (var i=0; i<3; i++) {
			rv[i] = parseInt(rv[i] || 0);
			if (cv[i]<rv[i]) return false;
			if (cv[i]>rv[i]) return true;
		}
		return true;
	};
	$$.getHTML = function (a,v) {
		var f = new $$(a,v);
		return f.getHTML();
	};
	$$.setVariable = function (fid, name, val) {
		var flash = $.browser.msie ? window[fid] : document[fid];
		try {
			if (flash && flash.SetVariable) {
				flash.SetVariable(name, val);
			}
		} catch(e){}
	};
	$$.prototype = {
		attr: {},
		vars: {},
		setAttr: function(name, value){
			this.attr[name] = value;
		},
		getAttr: function(name){
			return this.attr[name];
		},
		setVar: function(name, value){
			this.vars[name] = value;
		},
		getVar: function(name){
			return this.vars[name];
		},
		getVarsString: function(v){
			v = v || this.vars;
			var sret = "";
			for (var i in v) sret += (i+"="+v[i]+"&");
			sret = $.rtrim(sret,"&");
			return sret;
		},
		getHTML : function(a,v) {
			a = a || this.attr;
			v = v || this.vars;
			if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {
				var s='<embed type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer" allowScriptAccess="sameDomain" swliveconnect="true" ';
				s+='id="'+a.id+'" name="'+a.id+'" src="'+a.url+'" ';
				s+='width="'+a.width+'" height="'+a.height+'" ';
				s+=(a.bgcolor?'bgcolor="'+a.bgcolor+'" ':'');
				s+='menu="'+(a.menu?"true":"false")+'" ';
				s+=(a.transparent?'wmode="transparent" ':'');
				s+='flashvars="'+this.getVarsString(v)+'" ';
				s+='quality="'+a.quality+'">';
				s+='</embed>';
			} else {
				var s='<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '; //  codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"
				s+='id="'+a.id+'" name="'+a.id+'" '; 
				s+='width="'+a.width+'" height="'+a.height+'" border="0">\n';
				s+='<param name="allowScriptAccess" value="sameDomain"/>\n';
				s+='<param name="movie" value="'+a.url+'"/>\n';
				s+='<param name="quality" value="'+a.quality+'"/>\n';
				s+='<param name="menu" value="'+(a.menu?"true":"false")+'"/>\n';
				s+=(a.bgcolor?'<param name="bgcolor" value="'+a.bgcolor+'"/>\n':'');
				s+=(a.transparent?'<param name="wmode" value="transparent"/>\n':'');
				s+='<param name="flashvars" value="'+this.getVarsString(v)+'"/>\n';
				s+='</object>';
			}
			return s;
		},
		write : function(id) {
			var _attr={}, _vars={}, eiok = false;
			$.extend(_attr, this.attr);
			$.extend(_vars, this.vars);
			if (this.attr.expressinstall && $$.isValidVersion([6,0,65]) && !$$.isValidVersion(this.attr.version)) {
				eiok = true;
				_attr.url = this.attr.expressurl;
				_vars.MMredirectURL = this.attr.MMredirectURL;
				document.title = this.attr.MMdoctitle;
				_vars.MMdoctitle = document.title;
				_vars.MMplayerType = $.browser.msie?"ActiveX":"PlugIn";
			}
			if (this.attr.nocache) _attr.url = $.URL.addUNI(_attr.url);
			if ($$.skipdetect || this.attr.expressinstall && eiok || $$.isValidVersion(this.attr.version)){
				var o = (typeof id=="string") ? $("#"+id) : id;
				o.html(this.getHTML(_attr, _vars));
				return true;
			}
			return false;
		}
	};
	if ($.browser.msie && $$.isValidVersion(8)) {
		$$.cleanup = function() {
			$("OBJECT").each(function() {
				this.style.display = "none";
				for (var i in this) if (typeof this[i] == 'function') this[i] = function(){};
			});
		};
		$$.onUnload = function() {
			__flash_unloadHandler = function(){};
			__flash_savedUnloadHandler = function(){};
			window.attachEvent("onunload", $$.onUnload);
		}
		window.attachEvent("onbeforeunload", $$.onUnload);
	}
})();



/**
 * Cookies v1.33: Client side cookies access
 * 
 * @usage:
 *   $.Cookies.get("mycookie");
 *   $.Cookies.set("mycookie",123);
 *   $.Cookies.set("mycookie",123,{expires:"10", path:"/", domain:"", secure:""});
 *   $.Cookies.del("mycookie");
 */
(function(){
	var $$ = $.Cookies = {
		enable : false,
		get : function(name) {
			var sret = null;
			if (document.cookie) {
				var ac=document.cookie.split(";"), c;
				name+="=";
				for(var i=0;i<ac.length;i++){
					c=$.trim(ac[i]);
					if (c.indexOf(name)==0) {
						sret = c.substring(name.length,c.length);
						break;
					}
				}
			}
			return sret;
		},
		set : function(name,value,options) {
			options = $.extend({expires: 1, path:"", domain:false, secure:false}, options || {});
			var expires = "";
			if (options.expires) {
				var today=new Date();
				today.setTime(today.getTime()+(options.expires*86400000));
				expires="; expires="+today.toGMTString();
			}
			var path = options.path=="" ? "; path="+options.path : "";
			var domain = options.domain ? "; domain="+options.domain : "";
			var secure = options.secure ? "; secure" : "";
			document.cookie=name+"="+value+"; "+expires+path+domain+secure;
		},
		del : function(name){
			this.set(name,"",{expires:-1});
		}
	};
	$$.set("testingcookies","yes");
	if ($$.get("testingcookies")=="yes"){
		$$.enable=true;
		$$.del("testingcookies");
	} else $$.enable=false;
})();



/** 
 * msiefix v5.52: fix PNG & css>opacity & css>fixed & css>min-width/min-height & css>(left & right)|(top &bottom) in MSIE
 * 
 * @usage:
 *   $("*").msiefixPNG();
 *   $("*").msiefixOpacity();
 *   $("*").msiefixFixed();
 *   $("*").msiefix2side();
 *   $("*").msiefixMin();
 *   ' if you use .msiefixFixed() don't use in inline style block position:fixed, only in reference e.g. in <style></style> section
 * @known issues:
 *   not work in same style msiefixPNG() and .msiefixOpacity() simultaneously
 *   .msiefixFixed() currently fixed to document 
 *   .msiefix2side() currently work only with 'px'
 */
 (function(){
	var $$ = $.msiefix = {
		emptygif : "/framework/media/empty1x1.gif",
		doc      :  $.boxModel && document.documentElement || document.body
	};
	$.fn.extend({
		msiefixPNG: function() {
			if ($.browser.msie6) {
				var reimg = new RegExp("\\.png$","i");
				var rebg = new RegExp("url\\(\\\"(.+\\.png)\\\"\\)","i");
				this.each(function() {
					var name = null;
					var width,height;
					if (this.tagName && this.tagName=="IMG") {
						if (reimg.test(this.src)) {
							width = $(this).width();
							height = $(this).height();
							name = this.src;
							this.src = $$.emptygif;
						}
					} else {
						if (this.currentStyle) {
							name = rebg.exec(this.currentStyle.backgroundImage);
							if (name) {
								//width = $(this).width();
								//height = $(this).height();
								name = name[1];
								$(this).css("backgroundImage","none");
							}
						}
					}
					if (name) {
						if (width && height) $(this).css({width:width, height:height});
						$(this).css({"filter":"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true', sizingMethod='crop', src='"+name+"')"});
					}
				});
			}
			return this;
		},

		msiefixOpacity: function() {
			if ($.browser.msie) {
				this.each(function() {
					if (this.currentStyle.opacity) {
						$(this).css("opacity",this.currentStyle.opacity);
					};
				});
			}
			return this;
		},
		
		msiefixFixed: function() {
			if ($.browser.msie6) {
				$._msie6_fixed_left = function(el) {
					var x, ws, elmd = el[$.metaData.single];//$(el).metaData();
					if (elmd._l!="auto") {
						x = elmd._l;
						if (x.indexOf("%")>=0) {
							x = parseInt((elmd._owner.clientWidth*parseInt(x))/100);
						} else x = parseInt(x);
					} else {
						x = elmd._r;
						ws = elmd._owner.clientWidth;
						if (x.indexOf("%")>=0) {
							x = parseInt((ws*parseInt(x))/100);
						} else x = parseInt(x);
						x = ws-el.offsetWidth-x;
					}
					return x+elmd._owner.scrollLeft+"px";
				}
				$._msie6_fixed_top = function(el) {
					var y, ws, elmd = el[$.metaData.single];//$(el).metaData();
					if (elmd._t!="auto") {
						y = elmd._t;
						if (y.indexOf("%")>=0) {
							y = parseInt((elmd._owner.clientHeight*parseInt(y))/100);
						} else y = parseInt(y);
					} else {
						y = elmd._b;
						ws = elmd._owner.clientHeight;
						if (y.indexOf("%")>=0) {
							y = parseInt((ws*parseInt(y))/100);
						} else y = parseInt(y);
						y = ws-el.offsetHeight-y;
					}
					return y+elmd._owner.scrollTop+"px";
				}
				this.each(function() {
					if (this.currentStyle.position == "fixed") {
						var elmd = $(this).metaData();
						elmd._fixfixed = true;
						elmd._t = $(this).css("top");
						elmd._b = $(this).css("bottom");
						elmd._l = $(this).css("left");
						elmd._r = $(this).css("right");
						elmd._owner = $$.doc;
						$(this).css("position","absolute");
						$(this).css("right","auto");
						$(this).css("bottom","auto");
						var s = $(this)[0].style;
						s.setExpression("left", "$._msie6_fixed_left(this)");
						s.setExpression("top", "$._msie6_fixed_top(this)");
					};
				});
			}
			return this;
		},
		
		msiefix2side: function() {
			if ($.browser.msie6) {
				$._msie6_2side_height = function(el) {
					var s, elmd = el[$.metaData.single];
					var ws = elmd._owner.clientHeight;
					s = ws - parseInt(elmd._t) - parseInt(elmd._b);
					return s+"px";
				};
				$._msie6_2side_width = function(el) {
					var s, elmd = el[$.metaData.single];
					var ws = elmd._owner.clientWidth;
					
					s = ws - parseInt(elmd._l) - parseInt(elmd._r);
					return s+"px";
				};
				function _findOwner (t) {
					t = t.parentNode;
					var owner = $$.doc;
					while(t.tagName && t.tagName!="BODY") {
						var cp = t.currentStyle.position;
						if (cp == "absolute" || cp == "relative" || cp == "fixed") {
							owner = t;
							break;
						}
						t = t.parentNode;
					}
					return owner;
				};
				this.each(function() {
					var a = "auto", elmd = $(this).metaData();
					var t = $(this).css("top");
					var b = $(this).css("bottom");
					var l = $(this).css("left");
					var r = $(this).css("right");
					if (t!=a && b!=a) {
						elmd._t = t;
						elmd._b = b;
						elmd._owner = _findOwner(this);
						elmd._fix2sideh = true;
						$(this).css("bottom",a);
						var s = $(this)[0].style;
						s.setExpression("height", "$._msie6_2side_height(this)");
					}
					if (l!=a && r!=a) {
						elmd._l = l;
						elmd._r = r;
						elmd._owner = _findOwner(this);
						elmd._fix2sidew = true;
						$(this).css("right",a);
						var s = $(this)[0].style;
						s.setExpression("width", "$._msie6_2side_width(this)");
					}
				});
			}
			return this;
		},

		msiefixMin: function() {
			if ($.browser.msie6) {
				$._msie6_min = function(e) {
					var el = e.data.el;
					var s, elmd = el[$.metaData.single]; //$(el).metaData();
					//var os = {w:$(elmd._owner).width(), h:$(elmd._owner).height()}; 
					if (elmd._fixminh) {
						if ($(elmd._owner).height() < parseInt(elmd._mh)) s = elmd._mh;
						else s = elmd._h;
						$(el).height(s);
					}
					if (elmd._fixminw) {
						if ($(elmd._owner).width() < parseInt(elmd._mw)) s = elmd._mw;
						else s = elmd._w;
						$(el).width(s);
					}
				};
				function _findOwner (t) {
					t = t.parentNode;
					var owner = window;
					if (t.tagName && t.tagName!="BODY") owner = t;
					return owner;
				};
				this.each(function() {
					var a = "auto", elmd = $(this).metaData();
					var h = $(this).css("minHeight");
					var w = $(this).css("min-width"); // ie hack css name
					if (h!=a && h!=undefined) {
						elmd._fixminh = true;
						//elmd._h = $(this).css("height");
						elmd._h = $(this)[0].currentStyle.height;
						elmd._mh = h;
						elmd._owner = _findOwner(this);
					}
					if (w!=a && w!=undefined) {
						elmd._fixminw = true;
						//elmd._w = $(this).css("width");
						elmd._w = $(this)[0].currentStyle.width;
						elmd._mw = w;
						elmd._owner = _findOwner(this);
					}
					if (elmd._fixminh || elmd._fixminw) {
						$(elmd._owner).bind("resize",{el:this},$._msie6_min);
						$._msie6_min({data:{el:this}});
					}
				});
			}
			return this;
		}

	});
})();



/** 
 * DEPRECATED !!!
 * 
 * Positioning v1.2.1: positioning & dimension of object
 */
(function(){
	$.fn.extend({
		setPos: function(x,y) {
			this.each(function() {
				var elmd = $(this).metaData();
				if (x!=undefined) {
					if (elmd.fixFixed) elmd.left = x;
					else $(this).css("left",x);
				}
				if (y!=undefined) {
					if (elmd.fixFixed) elmd.top = y;
					else $(this).css("top",y);
				}
			});
			return this;
		}

	});
})();



/** 
 * Hijax v2.00: Enable history and bookmarking in Ajax & Flash driven applications
 * Layer on dhtmlHistory (http://code.google.com/p/reallysimplehistory/)
 *
 * @usage:
 * 	 $.Hijax.init(callback);
 * 	 $.Hijax.init(callback); // set default flag for call callback function on $.Hijax.load()
 *   $.Hijax.load(location,somedata);
 *
 * Inspired by:
 *   Hijax theory (http://domscripting.com/blog/display/41)
 *   History (http://www.mikage.to/jquery/jquery_history.html)
 *   History/Remote (http://www.stilbuero.de/jquery/history/)
 */
(function(){
	var $$ = $.Hijax = {
		callback : null,
		init: function (callback) {
			$$.callback = callback;
			window.dhtmlHistory.create({
				toJSON:   function(o) {return $.toJSON(o);},
				fromJSON: function(s) {return $.parseJSON(s);}
			});
			window.dhtmlHistory.initialize();
			window.dhtmlHistory.addListener($$._listener);
			$$._listener($$.getCurrent(),null);  
		},
		getCurrent : function() {
			return window.dhtmlHistory.getCurrentLocation();
		},
		checkLocation : function() {
			var loc = $$.getLocation();
			if (loc) {
				window.location = "http://"+window.location.host+window.location.search+"#"+loc;
				//if (window.location.pathname.length>1)	window.location = "http://"+window.location.host+window.location.search+"#"+window.location.pathname.substr(1,window.location.pathname.length-1);
				//location = "http://"+location.host+location.search+"#"+location.pathname.substr(1,location.pathname.length-1);
				// // location = "http://"+location.host+"?jump"+"#"+location.pathname.substr(1,location.pathname.length-2);
				// // location = $.URL.addParam("http://"+location.host+location.search+"#"+location.pathname.substr(1,location.pathname.length-2), {jump:""});
			}
		},
		getLocation : function() {
			return $.file.delStartSlash(window.location.pathname);
		},
		load: function (loc, data) {
			window.dhtmlHistory.add(loc, data);
			$$._listener(loc, data);
		},
		_listener : function (loc, data) {
			$$.callback(loc, data);
		}
	};
})();
/*
// * Old code need some fix and again to battle!!!! ;)
//
(function(){
	var $$ = $.Hijax = {
		_framename: "hijax_iframe",
		_callback: null,
		_cbonload: true,
		_currhash: "",
		_tid: null,
		_backstack: null,
		_forwardstack: null,
		_isfirst: true,
		_dontcheck: false,
		init: function (callback,cbonload) {
			$$._callback = callback;
			if (cbonload != undefined) $$._cbonload = cbonload;
			$$._currhash = location.hash;
			if ($.browser.msie) {
				if ($$._currhash == "") $$._currhash = "#";
				$("body").append('<iframe id="'+$$._framename+'" style="display: none;"></iframe>');
				var iframe = $("#"+$$._framename)[0].contentWindow.document;
				iframe.open();
				iframe.close();
				iframe.location.hash = $$._currhash;
			}
			else if ($.browser.safari) {
				$$._backstack = [];
				$$._backstack.length = history.length;
				$$._borwardstack = [];
				$$._isfirst = true;
				$$._dontcheck = false;
			}
			$$._callback($$._currhash.replace(/#/,""));
			$$._tid = setInterval($$._historyCheck, 200);			
		},
		disable: function () {
			if ($$._tid) {
				clearTimeout($$._tid);
				$$._tid = null;
				$("#"+$$._framename).remove();
			}
		},
		load: function (hash, cbonload) {
			if (cbonload == undefined) cbonload = $$._cbonload;
			if ($.browser.safari) {
				$$._currhash = hash;
				$$._dontcheck = true;
				$$._backstack.push(hash);
				$$._forwardstack.length = 0;
				$$._isfirst = true;
				window.setTimeout(function() {$$._dontCheck=false;}, 200);
				if (cbonload) $$._callback(hash);
				location.hash = $$._currhash;
			} else {
				$$._currhash = "#"+hash;
				location.hash = $$._currhash;
				if ($.browser.msie) {
					var iframe = $("#"+$$._framename)[0].contentWindow.document;
					iframe.open();
					iframe.close();
					iframe.location.hash = $$._currhash;
				}
				if (cbonload) $$._callback(hash);
			}
		},
		_historyCheck: function () {
			if ($.browser.msie) {
				var iframe = $("#"+$$._framename)[0].contentWindow.document;
				var ch = iframe.location.hash;
				if ($$._currhash != ch) {
					$$._currhash = ch;
					location.hash = ch;
					$$._callback($$._currhash.replace(/#/,""));
				}
			} else if ($.browser.safari) {
				if (!$$._dontcheck) {
					var hd = history.length - $$._backstack.length;
					if (hd) {
						$$._isfirst = false;
						if (hd < 0) {
							for (var i=0; i<Math.abs(hd); i++) $$._forwardstack.unshift($$._backstack.pop());
						} else {
							for (var i=0; i<hd; i++) $$._backstack.push($$._forwardstack.shift());
						}
						var ch = $$._backstack[$$._backstack.length-1];
						if (ch != undefined) {
							$$._currhash = location.hash;
							$$._callback(ch);
						}
					} else if ($$._backstack[$$._backstack.length-1] == undefined && !$$._isfirst) {
						if (document.URL.indexOf("#") >= 0) {
							$$._callback(document.URL.split("#")[1]);
						} else {
							$$._callback("");
						}
						$$._isfirst = true;
					}
				}
			} else {
				var ch = location.hash;
				if (unescape($$._currhash) != ch) {
					$$._currhash = ch;
					$$._callback($$._currhash.replace(/#/,""));
				}
			}
		}
	};
})();
*/

/** 
 * Form Valid v1.69:
 * 
 * @usage:
 *
 * $.langs.load({module:"FormValid", langid:"en", type:"php", php_url:"data.langs.php"});
 *
 * $("#form_login").FormValid({onsubmit:function(){
		alert ($(this).serialize());		
		return false; // true
 *	}});
 *
 * Inspired by:
 *   Form Validation (http://jquery.bassistance.de/validate/)
 */
(function(){
	var $$ = $.FormValid = function(options) {
		this.options = $.extend({}, $$.options, options);
	};
	$$.options = {
		md_type        : "class",
		md_name        : "data",
		validonblur    : true,
		onsubmit       : null,
		focuserror     : true,
		onlyfirst      : true,
		noerrormessage : {id:"Ok", alt:"ok"},
		emptymessage   : "&nbsp",
		classerror     : "error",
		errorsingle    : "_error",
		errorcontainer : null,
		errorsplit     : "<br />"
	};
	
	$$.addRules = function(element,rules) {
		$(element).each(function() {
			var md = $(this).metaData($$.options.md_type,$$.options.md_name);
			var data = md;
			if (md.formValid) data = md.formValid;
			for (var rule in rules) {
				data[rule] = rules[rule];
			}
		});
	};
	$$.delRules = function(element,rules) {
		$(element).each(function() {
			var md = $(this).metaData($$.options.md_type,$$.options.md_name);
			var data = md;
			if (md.formValid) data = md.formValid;
			for (var rule in rules) {
				delete data[rule];
			}
		});
	};
	$$.clearRules = function(element) {
		$(element).each(function() {
			var md = $(this).metaData($$.options.md_type,$$.options.md_name);
			var data = md;
			if (md.formValid) data = md.formValid;
			data = {};
			//$(this).metaData($$.options.md_type,$$.options.md_name);
			//this[$.metaData.single] = {};
		});
	};
	
	$.fn.extend({
		FormValid: function(options) {
			return this.each(function() {
				if (this.FormValid) return;
				var _t = new $$(options);
				_t.elements = $(":input:not(:submit):not(:reset)", this);
				_t.clearError();
				if (_t.options.validonblur) {
					_t.elements.blur(function() {
						_t.validateElement(this);
						_t.showErrors(this);
					});
				}
				_t.elements.change(function() {
					_t.clearError(this);
				});
				if ($(this).is("form")) {
					_t.form = this;
					$(this).bind("reset", function(e){
						_t.clearError();
					});
					$(this).bind("submit", function(e) {
						var f = _t.validateForm();
						if (f && _t.options.onsubmit) f = _t.options.onsubmit.apply(this); //_t.options.onsubmit(this);						
						return f;
					});
				}
				this.FormValid = _t;
			});
		}
	});

	$$.prototype = {
		form     : null,
		options  : {},
		elements : {},
		errors   : {},
		validateForm: function(isClear){
			var _t = this, f = true, e;
			if (isClear) _t.clearError();
			for (var i=0; i<_t.elements.length; i++) {
				e = _t.elements[i];
				if (!_t.validateElement(e) && f) {
					f = false;
					if (_t.options.focuserror) {
						if (e.wysiwyg) $.Wysiwyg.Focus(_getId(e));
						else e.focus();
					}
					if (_t.options.onlyfirst) break;
				}
			};
			setTimeout(function(){_t.showErrors();}, 100);
			//_t.showErrors();
			return f;
		},
		validateElement: function(e){
			var _t = this, f = true, rule, param, method, r;
			if (e.wysiwyg) _t.clearError(e);
			var rules = _t.getRules(e);
			for (var i=0; i<rules.length; i++) {
				rule = rules[i].rule;
				param = rules[i].param;
				method = $$.methods[rule];
				if (method) {
					if (!method.force && _t.getErrorStatus(e,rule)==true) continue;
					try {
						r = method.func(e, param, _t, method);
						_t.setErrorStatus(e, rule, r.status, r.message, param);
						if (r.status!=true) {
							f = false;
							break;
						}
					} catch(ee) {
					}
				}
			}
			return f;
		},
		clearError: function(e){
			var _t = this, elements=[];
			if (e==undefined) {
				_t.errors = {};
				elements = _t.elements;
			} else {
				_t.errors[_getId(e)] = {};
				elements[0] = e;
			}
			if (_t.options.errorcontainer) {
				$(_t.options.errorcontainer).html(_t.options.emptymessage).removeClass(_t.options.classerror);
			} else {
				for (var i=0; i<elements.length; i++) {
					var id = _getId(elements[i]);
					$("#"+id+_t.options.errorsingle,_t.form).html(_t.options.emptymessage).removeClass(_t.options.classerror);
				}
			}
		},
		isFormValid: function(){
			var _t = this;
			for (var i in _t.errors) {
				for (var n in _t.errors[i]) {
					if (_t.errors[i][n].status!=true) return false;
				}
			}
			return true;
		},
		getRules: function(e){
			var _t = this, data, md = $(e).metaData(_t.options.md_type,_t.options.md_name);
			var data = md;
			if (md.formValid) data = md.formValid;
			var rules = [];
			for (var rule in data) {
				rules[rules.length] = {rule:rule, param:data[rule]};
			}
			return rules;
		},
		setErrorStatus: function(e,rule,status,message,param){
			var _t = this, id = _getId(e);
			message = message || "";
			param = param || ["",""];
			message = _t.formatMessage(message,param);
			if (_t.errors[id]==undefined) _t.errors[id] = {};
			_t.errors[id][rule] = {status:status, message:message};
		},
		getErrorStatus: function(e,rule){
			var _t = this, id = _getId(e);
			var err = _t.errors[id];
			if (!err || !err[rule]) return undefined;
			return err[rule].status;
		},
		showErrors: function(e){
			var _t = this, s = "", elements=[], dest, msgok = _t.formatMessage(_t.options.noerrormessage);
			if (e==undefined) elements = _t.elements;
			else elements[0] = e;
			for (var i=0; i<elements.length; i++) {
				var element = elements[i];
				if (_t.getRules(element).length==0) continue;
				var id = _getId(element);
				var e = _t.errors[id];
				if (!e) continue;
				var message = msgok;
				for (var rule in e) {
					if (e[rule].status==false) {
						message=e[rule].message;
						break;
					}
				}
				if (message!=msgok && _t.options.errorcontainer) {
					s+=message+_t.options.errorsplit;
				} else {
					dest = $("#"+id+_t.options.errorsingle,_t.form);
					if (message==msgok) {
						dest.removeClass(_t.options.classerror);
					} else {
						dest.addClass(_t.options.classerror);
						if (dest.length==0) alert(message);
					}
					dest.html(message);
				}
				if (_t.options.onlyfirst && message!=msgok) break;
			}
			if (_t.options.errorcontainer) {
				dest = $(_t.options.errorcontainer);
				if (s=="") {
					s = msgok;
					dest.removeClass(_t.options.classerror);
				} else {
					dest.addClass(_t.options.classerror);
				}
				dest.html(s);
			}
		},
		formatMessage: function (message, param) {
			var _t = this;
			return $.langs.get(message.id, message.alt, param);
		}
	};	

	var _getId = function (element) {
		return (/radio|checkbox/i.test(element.type)) ? element.name : element.id;
	};
	var _getAlt = function (element, message) {
		var alt = $(element).attr("formValid");
		if (alt) message = {id:"",alt:alt};
		return message;
	};
	var _getLength = function (element) {
		switch (element.nodeName.toLowerCase()) {
		case "select":
			return $("option:selected", element).length;
		case "input":
			if (/radio|checkbox/i.test(element.type)) 
				return $("[@name="+element.name+"]:checked", element.form || document).length;
		}
		return $(element).val().length;
	};
	
	$$.methods = {};

	$$.addMethod = function(name, func, message, force) {
		$$.methods[name] = {name:name, func:func, message:message, force:force};
	};

	$$.addMethod (
		"ajaxRequest",
		function(e, p, v, m) {
			setTimeout(function(){
				$.ajax({
					type: "POST",
					url: p,
					data: "param="+escape($(e).val()),
					success: function(msg){
						if (msg=="true") v.setErrorStatus(e, m.name, true);
						else v.setErrorStatus(e, m.name, false, _getAlt(e,m.message[1]));
						v.showErrors();
					}
				});		
			}, 150);
			return {status:false, message:m.message[0]};
		},
		[{id:"TEXT_FormValid_ajaxRequest1", alt:"Processing, wait..."},
		 {id:"TEXT_FormValid_ajaxRequest2", alt:"You can't use this value"}]
	);
	$$.addMethod (
		"required",
		function(e, p, v, m) {
			var f = false;
			if (e.wysiwyg) {
				if ($.Wysiwyg.getContent(_getId(e)).length > 0) f = true;
			} else {
				if (e.nodeName.toLowerCase()=="select") {
					var opt = $("option:selected", e);
					var len = (e.type=="select-one")? 1 : opt.length;
					for (var i=0; i<len; i++) {
						if (opt[i].value.length > 0) {f = true; break;}
					}
				} else f = _getLength(e) > 0;
			}
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_required", alt:"This field is required"}
	);
	$$.addMethod (
		"minLength",
		function(e, p, v, m) {
			var val = $(e).val();
			var f = val=="";
			if (!f) f = _getLength(e) >= p;
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_minLength", alt:"Enter a value of at least {0} characters"}
	);
	$$.addMethod (
		"maxLength",
		function(e, p, v, m) {
			var val = $(e).val();
			var f = val=="";
			if (!f) f = _getLength(e) <= p;
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_maxLength", alt:"Enter a value no longer then {0} characters"}
	);
	$$.addMethod (
		"rangeLength",
		function(e, p, v, m) {
			var val = $(e).val();
			var f = val=="";
			if (!f) {		
				var l = _getLength(e);
				f = l >= p[0] && l <= p[1];
			}
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_rangeLength", alt:"Enter a value between {0} and {1} characters long"}
	);
	$$.addMethod (
		"equalLength",
		function(e, p, v, m) {
			var val = $(e).val();
			var f = val=="";
			if (!f) f = _getLength(e) == p;
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_equalLength", alt:"Enter a value {0} characters long"}
	);
	$$.addMethod (
		"equalTo",
		function(e, p, v, m) {
			var f = true;
			if (v.validateElement($(p)[0])) f = ($(e).val() == $(p).val());
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_equalTo", alt:"Enter the same value again"},
		true
	);
	$$.addMethod (
		"email",
		function(e, p, v, m) {
			var val = $(e).val();
			var f = val=="";
			if (!f) f = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/i.test(val);
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_email", alt:"Enter a valid email address"}
	);
	$$.addMethod (
		"url",
		function(e, p, v, m) {
			var val = $(e).val();
			var f = val=="";
			if (!f) f = /^(https?|ftp):\/\/[A-Z0-9](\.?[A-Z0-9][A-Z0-9_\-]*)*(\/([A-Z0-9][A-Z0-9_\-\.]*)?)*(\?([A-Z0-9][A-Z0-9_\-\.%\+=&]*)?)?$/i.test(val);
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_url", alt:"Enter a valid URL"}
	);
	$$.addMethod (
		"digits",
		function(e, p, v, m) {
			var val = $(e).val();
			var f = val=="";
			if (!f) f = /^\d+$/.test(val);
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_digits", alt:"Enter only digits"}
	);
	$$.addMethod (
		"float",
		function(e, p, v, m) {      // \.|,
			var val = $(e).val();
			var f = val=="";
			if (!f) f = (new RegExp("^\\d+["+p+"]?\\d+$")).test(val);
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_float", alt:"Enter a number with \"{0}\""}
	);
	$$.addMethod (
		"minValue",
		function(e, p, v, m) {
			var val = Number($(e).val());
			var f = false;
			if (val.toString()!="Invalid" && val.toString()!="NaN") f = val>=p;
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_minValue", alt:"Enter a number great or equal \"{0}\""}
	);
	$$.addMethod (
		"maxValue",
		function(e, p, v, m) {
			var val = Number($(e).val());
			var f = false;
			if (val.toString()!="Invalid" && val.toString()!="NaN") f = val<=p;
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_maxValue", alt:"Enter a number less or equal \"{0}\""}
	);
	$$.addMethod (
		"date",
		function(e, p, v, m) {
			var val = $(e).val();
			var f = val=="";
			if (!f) f = !/Invalid|NaN/.test(new Date(val));
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_date", alt:"Enter a valid date"}
	);
	$$.addMethod (
		"file",
		function(e, p, v, m) {
			var val = $(e).val();
			var f = val=="";
			if (!f) {
				f = (new RegExp("^[a-z|_]([a-z0-9|_]+|/(?!/)|\\.(?!\\.))+[a-z0-9]$","i")).test(val);
				if (f && p!="") f = (new RegExp("\\."+p.replace(/\||,/,"|\\.")+"$","i")).test(val);
			}
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_file", alt:"Enter a file name with type \"{0}\""}
	);
	$$.addMethod (
		"files",
		function(e, p, v, m) {
			var val = $(e).val();
			var f = val=="";
			if (!f) {
				var arr = val.split(";");
				for (var i=0; i<arr.length; i++) {
					val = arr[i];
					f = (new RegExp("^[a-z|_]([a-z0-9|_]+|/(?!/)|\\.(?!\\.))+[a-z0-9]$","i")).test(val);
					if (f && p!="") f = (new RegExp("\\."+p.replace(/\||,/,"|\\.")+"$","i")).test(val);
					if (!f) break;
				}
			}
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_files", alt:"Enter a file(s) name with type \"{0}\""}
	);
	$$.addMethod (
		"userfunc",
		function(e, p, v, m) {
			var func = eval(p);
			var res = func(e);
			return {status:res.f, message:res.f?"":_getAlt(e,res.m)};
		},
		{}
	);
	$$.addMethod (
		"regexp",
		function(e, p, v, m) {
			var re = new RegExp(p);
			var f = re.test($(e).val());
			return {status:f, message:f?"":_getAlt(e,m.message)};
		},
		{id:"TEXT_FormValid_regexp", alt:"Enter a value like regexp \"{0}\""}
	);
})();



/** 
 * AjaxFileUpload v1.2: 
 * 
 * @usage:
 *
 * Inspired by:
 *   Ajax File Uploader Plugin (http://)
 */
(function(){

	$.extend({
    	ajaxFileUpload : function(s) {
	        s = jQuery.extend({}, jQuery.ajaxSettings, s);
			if (s.data) {
				if (s.processData && typeof s.data != "string")
	    			s.data = jQuery.param(s.data);
			}
			// force append data to url
			s.url += ((s.url.indexOf("?") > -1) ? "&" : "?") + s.data;
			// create unique id
			var id = new Date().getTime();
			var hidden = 'style="position:absolute; top:-1000px; left:-1000px; width:100px; height:100px;"';
			// create frame
			var frameId = 'ajaxUploadFrame' + id;
			var frame = $('<iframe id="'+frameId+'" name="'+frameId+'" '+hidden+' src="javascript:false;document.write(\'\');"></iframe>')[0];
			$("body").append(frame);
			// create form
			var formId = 'ajaxUploadForm' + id;
			var fileId = 'ajaxUploadFile' + id;
			var form = $('<form name="'+formId+'" id="'+formId+'" '+hidden+' action="'+s.url+'" target="'+frameId+'" method="post" enctype="multipart/form-data"></form>')[0];
			var oldElement = $('#' + s.fileid);
			var newElement = $(oldElement).clone();
			var oldfileId = $(oldElement).attr('id');
			$(oldElement).attr('id', fileId);
			$(oldElement).before(newElement);
			$(oldElement).appendTo(form);
			$("body").append(form);
			// jQuery ajax implementation with some fix
	        if (s.global && ! jQuery.active++) jQuery.event.trigger("ajaxStart");
	        var requestDone = false;
	        var xml = {};
	        if (s.global) jQuery.event.trigger("ajaxSend", [xml, s]);
	        var uploadCallback = function(isTimeout) {
				$(newElement).before(oldElement);
				$(oldElement).attr('id', oldfileId);
				$(newElement).remove();
				// get response
	            try {
					if (frame.contentWindow) {
						xml.responseText = frame.contentWindow.document.body ? frame.contentWindow.document.body.innerHTML : null;
	                	xml.responseXML = frame.contentWindow.document.XMLDocument ? frame.contentWindow.document.XMLDocument : frame.contentWindow.document;
					} else if (frame.contentDocument) {
						xml.responseText = frame.contentDocument.document.body ? frame.contentDocument.document.body.innerHTML : null;
	                	xml.responseXML = frame.contentDocument.document.XMLDocument ? frame.contentDocument.document.XMLDocument : frame.contentDocument.document;
					}						
	            } catch(e) {
					jQuery.handleError(s, xml, null, e);
				}
	            if (xml || isTimeout == "timeout") {				
	                requestDone = true;
	                var status;
	                try {
	                    status = isTimeout != "timeout" ? "success" : "error";
	                    if (status != "error") {
	                        var data = jQuery.fileUploadHttpData(xml, s.dataType);
	                        if (s.success) s.success(data, status);
	                        if (s.global) jQuery.event.trigger("ajaxSuccess", [xml, s]);
	                    } else
	                        jQuery.handleError(s, xml, status);
	                } catch(e) {
	                    status = "error";
	                    jQuery.handleError(s, xml, status, e);
	                }
	                if (s.global) jQuery.event.trigger("ajaxComplete", [xml, s]);
	                if (s.global && ! --jQuery.active) jQuery.event.trigger( "ajaxStop" );
	                if (s.complete) s.complete(xml, status);
					// Remove iframe & form
	                jQuery(frame).unbind() 
	                setTimeout(function(){
						try {
							$(frame).remove();
							$(form).remove();
						} catch(e) {
							jQuery.handleError(s, xml, null, e);
						}
					}, 100);
	                xml = null
	            }
	        }
	        if (s.timeout > 0) {
	            setTimeout(function(){
	                if( !requestDone ) uploadCallback( "timeout" );
	            }, s.timeout);
	        }
	        // start
			$(frame).bind("load",uploadCallback);
	        try {
	            $(form).submit();
	        } catch(e) {
	            jQuery.handleError(s, xml, null, e);
	        }
	        return {abort: function () {}};	
	    },

		fileUploadHttpData : function(r, type) {
	        var data = !type;
	        data = type == "xml" || data ? r.responseXML : r.responseText;
	        if (type == "script") jQuery.globalEval(data);
	        if (type == "json")   data = eval("(" + data + ")");
	        //if (type == "html")   jQuery("<div>").html(data).evalScripts();
	        return data;
	    }
	});

})();



/** 
 * XML v1.3: 
 * 
 * @usage:
 *   var dom = $.XML.to("<?xml ?><item>1</item><item>2</item>"); // get dom object from string
 *   var str = $.XML.from(dom); // get string from dom object
 *
 * Inspired by:
 *   XML Serializer (http://dev.jquery.com/wiki/Plugins/toXML)
 */
(function(){
	var $$ = $.XML = {

		ELEMENT_NODE       : 1,  // Node is a DOMElement 
		ATTRIBUTE_NODE     : 2,  // Node is a DOMAttr 
		TEXT_NODE          : 3,  // Node is a DOMText 
		CDATA_SECTION_NODE : 4,  // Node is a DOMCharacterData 
		ENTITY_REF_NODE    : 5,  // Node is a DOMEntityReference 
		ENTITY_NODE        : 6,  // Node is a DOMEntity 
		PI_NODE            : 7,  // Node is a DOMProcessingInstruction 
		COMMENT_NODE       : 8,  // Node is a DOMComment 
		DOCUMENT_NODE      : 9,  // Node is a DOMDocument 
		DOCUMENT_TYPE_NODE : 10, // Node is a DOMDocumentType 
		DOCUMENT_FRAG_NODE : 11, // Node is a DOMDocumentFragment 
		NOTATION_NODE      : 12, // Node is a DOMNotation 
	
		header : true,
		/*			
		function norm (dom) {
			function _norm (node) {
				var a = node.childNodes.length;
				node.normalize();
				//alert(a+" // "+node.childNodes.length);
				for (var i=0; i<node.childNodes.length; i++) {
					if (node.childNodes[i].nodeType == 1) _norm (node.childNodes[i]);
				}
			}
			_norm(dom);
		}
		norm (doc);
		*/
		to : function (str) {
			var doc;
		    try {
	            if (window.ActiveXObject) {
	                doc = new ActiveXObject("Microsoft.XMLDOM");
	                doc.async = "false";
	                doc.loadXML(str);
	            }
	            else {
					//str = str.replace(/[ \t\n\r]*</g, "<"); // patch for mozilla & opera
	                var parser = new DOMParser();
	                doc = parser.parseFromString(str, "text/xml");
					var processor = new XSLTProcessor();
					var xslt = (new DOMParser()).parseFromString('<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:output method="xml" omit-xml-declaration="yes"/><xsl:strip-space elements="*"/><xsl:template match="@*|node()"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:template></xsl:stylesheet>', 'text/xml');
					processor.importStylesheet(xslt);
					doc = processor.transformToDocument(doc);
	            }
	        }
	        catch(e) {
				$.errors.trigger($.errors.ERROR, "Cannot make DOM from xml string [func: $.XML.to]");
	        }
			return (doc);
		},
		from : function (dom) {
			function toXML (node) {
				var cont = '', type, i, attr;
				var ret = '<' + node.nodeName;
		        for (i=0; i<node.attributes.length; i++) {
					attr = node.attributes[i];
					ret += (' '+attr.name+'="'+attr.value+'"');
				}
				if (node.childNodes) {
					for (i=0; i<node.childNodes.length; i++) {
						type = node.childNodes[i].nodeType;
						if (type == $$.ELEMENT_NODE) {
							cont += toXML(node.childNodes[i]);
						} else if (type > $$.ATTRIBUTE_NODE) {
							cont += node.childNodes[i].nodeValue;
						}
					}
				}
				if (cont.length > 0) {
					ret += '>' + cont;
					ret += '</' + node.tagName + '>';
				} else {
					ret += ' />';
				}
				return ret;
			};
			var ret = '';
			if (dom.documentElement) dom = dom.documentElement;
			if (typeof XMLSerializer == "function" || typeof XMLSerializer == "object") {
				var xs = new XMLSerializer();
				ret = xs.serializeToString(dom);
			} else {
				if (dom.xml !== undefined) {
					ret = dom.xml;
				} else {
					ret = toXML(dom);
				}
			}
			return ($$.header?'<?xml version="1.0" encoding="UTF-8" ?>':"")+ret;
		},
		xpath : function(oNodes, sXPath) {
			var nodes = [];
            try {
				if (!$.browser.msie) {
	                var oXpe = new XPathEvaluator();
	                var oNsResolver = oXpe.createNSResolver(oNodes.ownerDocument == null ? oNodes.documentElement : oNodes.ownerDocument.documentElement);
	                var oResult = oXpe.evaluate(sXPath, oNodes, oNsResolver, 0, null);
	                var oRes;
	                while (oRes = oResult.iterateNext()) {
	                    nodes.push(oRes);
	                }
		        } else {
					oNodes.setProperty ("SelectionLanguage", "XPath")
					var nodes = oNodes.documentElement.selectNodes(sXPath);
				}
			} catch (e) { }
			return nodes;
		}
	}
})();



/** 
 * DOM node creation.
 *
 */
$.create = function(tag, attr, child) {
	var elem = document.createElement(tag);
	if (attr) {
		for (var aname in attr) {
			if (aname=="style") {
				var o = {}, a = attr[aname].split(";");
				for (var i=0; i<a.length; i++) {
					o[a[i].split(":")[0]] = a[i].split(":")[1];
				}
				$(elem).css(o);
			} else $(elem).attr(aname, attr[aname]);
		}
	}
	if (child) $(elem).append(child);
	return $(elem);
};



/** 
 * Langs v1.701 : language loading funcs (ajax and php version)
 * based on xml files
 * make global vars with text like this - TEXT_modulename_message
 *
 * @usage:
 * $.langs.load({module:"FormValid", langid:"en", type:"php", path:"langs/", php_url:"data.langs.php"});
 *
 * $.langs.set({langid:"en", type:"php", php_url:"data.langs.php", path:"langs/"});
 * $.langs.load("Grid,EditGrid,FilterGrid,FormValid,FileManager");
 *
 * alert( $.langs.str("<#en#>hello<#ru#>ïðèâåò", "not found lang") );
 * alert( $.langs.get("TEXT_EditGrid_deleterecords", "Delete - {0} records ?", rows.length) );
 * alert( $.langs.getalt("ru", "TEXT_EditGrid_deleterecords", "Delete - {0} records ?", rows.length) );
 */
(function() { 
	var $$ = $.langs = {
		id       : "en",
		errmsg   : "Cannot open or parse the lang xml file [func: $.langs.load]",
		options  : {
					module    : null,
					langid    : null,
					type      : 'php',  // "php" | "xml"
					php_url   : "data.langs.php",
					path      : "framework/langs/",
					isalt     : false
		},
		set : function (options) {
			$$.options.langid = $$.id;
			if (typeof(options)=="object") {
				$.extend($$.options, $$.options, options);
				$$.id = options.langid;
			} else $$.id = options;
		},
		load : function (options) {
			$$.options.langid = $$.id;
			if (typeof(options)=="object") {
				options = $.extend({}, $$.options, options);
			} else options = $.extend({}, $$.options, {module:options});
			var arrModule = options.module.split(",");
			var arrToLoad = [];
			for (var i=0; i<arrModule.length; i++) {
				var module = $.trim(arrModule[i]);
				var initname = "INIT_TEXT_"+module;
				if (options.isalt) initname += "_"+options.langid;
				if (window[initname]!=options.langid) arrToLoad.push(module);
			}
			if (arrToLoad.length>0) {
				if (options.type == "php") {
					var data = {action:"getjslang", module:arrToLoad.join(","), langid:options.langid, path:$.file.addEndSlash(options.path), isalt:options.isalt};
					$.ajax({async: false, type:"POST", dataType: "script", data: data, url: options.php_url, complete:function(xml,status){
						if (status!="success") $.errors.trigger($.errors.WARNING, $$.errmsg);
					}});
				} else if (options.type == "xml") {
					for (var i=0; i<arrToLoad.length; i++) {
						var module = $.trim(arrToLoad[i]);
						var url = $.file.addEndSlash(options.path)+options.langid+"/"+module+".xml";
						$.ajax({async: false, type:"POST", dataType: "xml", url: url, complete:function(xml,status){
							if (status!="success") $.errors.trigger($.errors.WARNING, $$.errmsg);
							else {
								xml = xml.responseXML;
								var texts = $("text",xml);
								for (var n=0; n<texts.length; n++) {
									var name = "TEXT_"+module+"_"+texts[n].getAttribute("id");
									if (options.isalt) name += "_"+options.langid;
									window[name]=texts[n].firstChild.nodeValue;
								}
								var initname = "INIT_TEXT_"+module;
								if (options.isalt) initname += "_"+$$.options.langid;
								window[initname]=options.langid;
							}
						}});
					}					
				}
			}		
		},
		getalt : function (langid,id,alt,param,options) {
			options = $.extend({}, $$.options, options);
			options.langid = langid;
			options.isalt = true;
			options.module = $$._getModuleFromId(id);
			var initname = 'INIT_TEXT_'+options.module;
			if (window[initname]==langid) {
				return $.langs.get(id, alt, param);
			}
			if (window[initname+"_"+langid]!=langid) {
				$.langs.load(options);
			}
			return $.langs.get(id+"_"+langid, alt, param);
		},
		get : function (id,alt,param) {
			var message = (window[id]||(alt||id))||"";
			return $$._format(message, param);
		},
		str : function (str,alt,param) {
			var ps,pe;
			var message = alt;
			if (str.indexOf("<#",0)<0) {
				message = str;
			} else {
				ps=str.indexOf("<#"+$$.id+"#>",0);
				if (ps>=0) {
					pe=str.indexOf("<#",ps+6);
					if (pe==-1) pe=str.length;
					message = str.substring(ps+6,pe); 
				}
			}
			return $$._format(message, param);
		},
		_getModuleFromId : function (id) {
			return (/^TEXT_([a-zA-Z\d]+)_.*/.exec(id))[1];
		},
		_format : function(message, param) {
			if (param != undefined) {
				if (param.constructor==Array) {
					for (var i=0; i<param.length; i++)
						message = message.replace("{"+i+"}", param[i] || "");
				} else message = message.replace("{0}", param || "");
			}
			return message;
		}
		
	};
})();



/** 
 * File v1.21
 */
(function() { 
	var $$ = $.file = {
		value   : null,
		re_file : new RegExp(".+[\.].+[^\/]$", "i"),
		getExt : function (value) {
			value = $.trim(value);
			var pos = value.lastIndexOf("."); 
			return pos<0 ? "" : value.substr(pos+1,value.length);
		},
		swapExt : function (value,newext) {
			value = $.trim(value);
			var pos = value.lastIndexOf("."); 
			return pos<0 ? value : value.substr(0,pos+1)+newext;
		},
		addStartSlash : function (value) {
			return "/"+$$.delStartSlash(value);
		},
		delStartSlash : function (value) {
			return $.ltrim(value,"/ ");
		},
		addEndSlash : function (value) {
			return $$.delEndSlash(value)+"/";
		},
		delEndSlash : function (value) {
			return $.rtrim(value,"/ ");
		},
		addBoundSlash : function (value) {
			return "/"+$$.delBoundSlash(value)+"/";
		},
		delBoundSlash : function (value) {
			return $.trim(value,"/ ");
		},
		isFile: function (value) {
			value = $.trim(value);
			var pos = value.lastIndexOf("/"); 
			var str = pos<0 ? "" : value.substr(pos+1,value.length-1);
			return $$.re_file.test(str);
		},
		parentFolder: function (value) { // todo for file
			value = $.trim(value);
			if (value=="/") return value;
			value = $$.delEndSlash(value);
			var pos = value.lastIndexOf("/");
			return pos<0 ? "" : value.substr(0,pos+1);
		},
		formatPath: function (value) {
			value = $.trim(value);
			//if (value.indexOf("/")>=0) value = $$.addStartSlash(value);
			//if (value.indexOf(":")>=0) value = $$.delStartSlash(value);
			if (!$$.isFile(value)) value = $$.addEndSlash(value);
			return value;
		},
		getPath: function (value) {
			value = $.trim(value);
			if (!$$.isFile(value)) return value;
			var pos = value.lastIndexOf("/"); 
			return pos<0 ? "" : value.substr(0,pos+1);
		},
		getFile: function (value) {
			value = $.trim(value);
			if (!$$.isFile(value)) return "";
			var pos = value.lastIndexOf("/");
			return pos<0 ? value : value.substr(pos+1);
		}
	};

	/*
	slashToBackslash : function (value) {
		$value = trim(is_null($value)?$this->value:$value);		
		return str_replace("/", DIRECTORY_SEPARATOR, $value);
	}
	function backslashToSlash ($value = null) {
		$value = trim(is_null($value)?$this->value:$value);		
		return str_replace(DIRECTORY_SEPARATOR, "/", $value);
	}
	function formatPath ($value = null) {
		$value = trim(is_null($value)?$this->value:$value);
		$value = file::backslashToSlash(file::addEndSlash($value));
		return $value;
	}
	*/
		
})();



/** 
 * interrupt v1.0 : add classic interrupt functional 
 *
 * @usage:
 *   var f = function(id){
 *            alert("handler");
 *            if (*condition*) $.interrupt.stop();
 *   };	
 *
 *   $.interrupt.add("onClickItem,onLoad", f);
 *   $.interrupt.del("onClickItem", f);
 *
 */
(function() {
	var $$ = $.interrupt = {
		arr     : {},
		isStop  : false,
		add   : function (src, dst) {
			var arrSrc = src.split(",");
			for (var n=0; n<arrSrc.length; n++) {
				var src = $.trim(arrSrc[n]);
				$$._add(src, dst);
			}
		},
		_add : function (src, dst) {
			var arr = $$.arr[src];
			var handler = function () {
				$$.isStop = false;
				for (var i=arr.length-1; i>0; i--) {
					var val = arr[i].apply(this, arguments);
					if ($$.isStop) return val;
				}
				return arr[0].apply(this, arguments);
			};			
			if (!arr) {
				try {
					arr = $$.arr[src] = [eval(src)]
					eval(src+" = handler;");
				} catch(e) {
					arr[src] = null;
					return;
				}
			}
			arr.push(dst);
		},
		del : function (src, dst) {
			var arrSrc = src.split(",");
			for (var n=0; n<arrSrc.length; n++) {
				var src = arrSrc[n];
				var arr = $$.arr[src];
				if (arr) {
					for (var i=1; i<arr.length; i++) {
						if (arr[i]==dst) {
							arr.splice(i, 1);
							break;
						}
					}
					if (arr.length==1) {
						eval(src+" = arr[0];");
						delete $$.arr[src];
					}
				}
			}
		},
		stop   : function () {
			$$.isStop = true;
		}
	};
})();



/** 
 *   JSON v1.1
 *   http://www.JSON.org/json2.js
 *
 *	Closure version by Oleg V. Lubarsky aka Dr.LOV 2008 CREATIVE ZONE Studio (http://www.cz-site.com/)
 *	Specially for framework
 *	
 * @usage:
 *	$.toJSON(value,replacer,space);
 *	$.parseJSON(text, reviver);
 *	
**/

(function() { 

    JSON = function () {

        function f(n) {
            return n < 10 ? '0' + n : n;
        }

        Date.prototype.toJSON = function (key) {
            return this.getUTCFullYear()   + '-' +
                  f(this.getUTCMonth() + 1) + '-' +
                  f(this.getUTCDate())      + 'T' +
                  f(this.getUTCHours())     + ':' +
                  f(this.getUTCMinutes())   + ':' +
                  f(this.getUTCSeconds())   + 'Z';
        };

        String.prototype.toJSON =
        Number.prototype.toJSON =
        Boolean.prototype.toJSON = function (key) {
            return this.valueOf();
        }

		var cx = new RegExp("/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/","g");
        var escapeable = new RegExp("/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/","g");
        var gap,indent,
            meta = {
                '\b': '\\b',
                '\t': '\\t',
                '\n': '\\n',
                '\f': '\\f',
                '\r': '\\r',
                '"' : '\\"',
                '\\': '\\\\'
            },
            rep;

        function quote(string) {
            escapeable.lastIndex = 0;
            return escapeable.test(string) ?
                '"' + string.replace(escapeable, function (a) {
                    var c = meta[a];
                    if (typeof c === 'string') {
                        return c;
                    }
                    return '\\u' + ('0000' +
                            (+(a.charCodeAt(0))).toString(16)).slice(-4);
                }) + '"' :
                '"' + string + '"';
        }

        function str(key, holder) {
            var i, k, v, length, mind = gap, partial, value = holder[key];
			if (value && typeof value === 'object' &&
				typeof value.toJSON === 'function') {
                value = value.toJSON(key);
            }
            if (typeof rep === 'function') {
                value = rep.call(holder, key, value);
            }
            switch (typeof value) {
            case 'string':
                return 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 (typeof value.length === 'number' &&
                        !(value.propertyIsEnumerable('length'))) {
                    length = value.length;
                    for (i = 0; i < length; i += 1) {
                        partial[i] = 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 = str(k, value);
                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    }
                } else {
                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = str(k, value);
                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    }
                }
                v = partial.length === 0 ? '{}' :
                    gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                            mind + '}' : '{' + partial.join(',') + '}';
                gap = mind;
                return v;
            }
        }
        return {
            stringify: function (value, replacer, space) {
                var i;
                gap = '';
                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.stringify');
                }
                return str('', {'': value});
            },

            parse: function (text, reviver) {
                var j;
                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');
            }
        };
    }();


	$.toJSON = function(value,replacer,space) {
		if (space==undefined) space = "\t";
		return JSON.stringify(value,replacer,space);
	};

	$.parseJSON = function(text, def) {
		var data = def==undefined ? null : def;
		if (text) {
			try { 
				data = eval("("+text+")");
			} catch(e) {}
		}
		return data;
		//return JSON.parse(text, reviver);
	};
	
})();
