(function(window,document,location,navigator){
function _is(o,c){if(typeof c=="function"){return o instanceof c?c:Function}else{return typeof o}}
_is.o=function(o){return _is(o)=="object"};
_is.f=function(o){return _is(o)=="function"};
_is.s=function(o){return _is(o)=="string"};
_is.n=function(o){return _is(o)=="number"};
_is.b=function(o){return _is(o)=="boolean"};
_is.u=function(o){return _is(o)=="undefined"};
_is.a=function(o){return _is(o,Array)==Array};
_is.d=function(o){return _is(o,Date)==Date};
_is.e=function(o){return _is.o(o)&&o.nodeType==1};
function _arr(obj){var a=[];if(_is.o(obj)&&_is.n(obj.length)){for(var i=0,l=obj.length;i<l;i++)a.push(obj[i])}return a}
function _ext(obj,exts,overwrite){exts=_is.o(exts)?exts:{};overwrite=_is.b(overwrite)?overwrite:false;for(var n in exts){if(!(n in obj) || overwrite){try{obj[n] = exts[n]}catch(e){}}}obj.valueOf=exts.valueOf;obj.toString=exts.toString;return obj}
function _format(template,hash){hash=hash||{};return template.replace(/{@([a-zA-Z0-9]+)?}/g,function(match,name){return hash[name]||match})}
function _func(pro){var f=function(){};f.prototype=pro;return f}
function _class(className){
	var args = _arr(arguments).slice(1);
	var parents = [], paramName = [];
	for(var i=0,l=args.length;i<l;i++){
		if(_is.f(args[i])){
			parents.push(args[i]);
			var newParam = args[i].toString().replace(/^.+?\((.*?)\)[\s\S]+$/,"$1").split(/\s*,\s*/);
			for(var j = 0; j < newParam.length; j ++){
				paramName[j]=newParam[j];
			}
			newParam = null;
		}
		else if(_is.o(args[i])){
			parents.push(_func(args[i]));
		}
	}
	var result = eval(_format(
		"(function(){return function {@className}({@params}){for(var i=0,l=parents.length;i<l;i++){parents[i].apply(this,arguments)}}})()",
		{className:className,params:paramName.join(", ")}
	));
	for(var i=0;i<parents.length;i++){
		_ext(result.prototype, parents[i].prototype, true);
	}
	return result;
}

/* developer mode start */
function _xhr(){
	var xhr = {};
	try{
		xhr = new XMLHttpRequest();
	}
	catch(e){
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}
	return xhr;
}
function matchPath(path){return /^[a-zA-Z]\w*?(\.[a-zA-Z]\w*)*$/.test(path)}
function checkPath(path,context){
	if(matchPath(path)){
		path=path.split(".");
		context=context||window;
		while(path.length){
			context=context[path.shift()];
			if(context instanceof NameSpace){}
			else{return false;}
		}
		return true;
	}
	else{
		console.log("Illegal path.");
		return false;
	}
}
function _loadResource(path){
	var loader = _xhr();
	loader.open("GET", "./JSFX/" + path + ".js?t="+new Date().getTime(), false);
	loader.send(null);
	var scr = document.createElement("script");
	scr.type = "text/javascript";
	scr.text = 
	"(function(window,document,location,navigator,Jtails){eval(Jtails.getShortName());var _ns_path_=\""+path+"\",base=registerNameSpace(_ns_path_),registerClass=function(className){return Jtails.registerClass.apply(base,[className,base].concat(_arr(arguments).slice(1)))},registerMethod=function(name,method){return Jtails.registerMethod.apply(base,[name,base].concat(_arr(arguments).slice(1)))};"+
	loader.responseText +
	"})(window,document,location,navigator,Jtails);";
	var head=document.getElementsByTagName("head")[0]||document.documentElement;
	head.insertBefore(scr,head.firstChild);
	document.createDocumentFragment().appendChild(scr);
	//console.log("Loaded:" + path);
}
function _using(path){
	//console.log(_format("Check '{@path}'.",{path:path}));
	if(matchPath(path)){
		path = path.split(".");
		var s = [];
		while(path.length){
			s[s.length] = path.shift();
			if(checkPath(s.join("."))){
				//console.log(s.join(".") + " already exists.");
			}
			else{
				_loadResource(s.join("."));
			}
		}
	}
}
/* developer mode end */
	var console = {
		messages : [],
		log : function(){
			if(top.console){
				top.console.log(arguments[0]);
			}
			else{
				this.messages.push(arguments[0]);
			}
		},
		clear : function(){}
	};
	function NameSpace(path, context){
		if(/^[a-z]\w*?(\.[a-z]\w*)*$/i.test(path?path:"")){
			var nsa = path.split("."), cpath = [];
			if(context instanceof NameSpace){
				path = context.getPath().split(".").concat(nsa);
			}
			else{
				context = window;
				path = path.split(".");
			}
			var co = context, cn = nsa.shift();
			var i = 10;
			while(nsa.length && i){
				cpath.push(cn);
				switch(_is(co[cn])){
					case "object" :
						if(co[cn] instanceof NameSpace){
							co = co[cn];
							cn = nsa.shift();
						}
						else{
							nsa = [];
							//console.log(cpath.join(".") + " not match [Object Jtails.NameSpace].");
							return new Error(cpath.join(".") + " not match [Object Jtails.NameSpace].");
						}
					break;
					case "undefined" :
						co = new NameSpace(cn, co);
						cn = nsa.shift();
					break;
					default :
						nsa = [];
						//console.log(cpath.join(".") + "is " + _is(co[cn]));
						return new Error(cpath.join(".") + "is " + _is(co[cn]));
					break;
				}
			}
			this.Name = cn;
			this.Path = path.join(".");
			co[cn] = this;
			this.toString = function(){
				return "[NameSpace " + path.join(".") + "]";
			};
			this.getPath = function(){
				return path.join(".");
			};
			this.getType = function(){
				return "NameSpace";
			};
		}
		else{
			//console.log("namespace path illegal.");
			return context||window;
		}
	}
	NameSpace.prototype.getShortName = function(){
		var result = [];
		for(var n in this){
			if(!/^(toString|valueOf|getPath|getShortName|getType|Name|Path)$/.test(n)){
				result[result.length]=_format("var {@name}={@path}.{@name};",{name:n,path:this.Path});
			}
		}
		return result.join("\r\n");
	};
	var sys = new NameSpace("Jtails", window);
	sys.console = console;
	sys.registerNameSpace = function(path, context){
		return new NameSpace(path, context);
	};
	sys.registerClass = function(path, context){
		if(/^[a-zA-Z]\w*?(\.[a-zA-Z]\w*)*$/.test(path?path:"")){
			path = path.split(".");
			var cn = path.pop();
			var ns = sys.registerNameSpace(path.join("."), context);
			//console.log([cn].concat(path));
			ns[cn] = _class.apply(ns, [cn].concat(_arr(arguments).slice(2), [
				{
					toString : function(){
						return "[Class " + this.getType() + "]";
					},
					getType : function(){
						return (ns instanceof NameSpace?ns.getPath() + ".":"") + cn;
					}
				}
			]));
			return ns[cn];
		}
		else{
			return new Error("className illegal.");
		}
	};
	sys.registerMethod = function(path, context, method){
		if(/^[a-zA-Z]\w*?(\.[a-zA-Z]\w*)*$/.test(path?path:"")){
			path = path.split(".");
			var cn = path.pop();
			var ns = sys.registerNameSpace(path.join("."), context);
			//console.log([cn].concat(path));
			method.toString().replace(/^.+?\((.*?)\)[\s\S]+$/, "$1").split(/\s*,\s*/);
			ns[cn] = eval(_format(
				"(function(){return function {@methodName}({@params}){return method.apply(context, arguments)}})()",
				{methodName:cn,params:method.toString().replace(/^.+?\((.*?)\)[\s\S]+$/, "$1").split(/\s*,\s*/)}
			));
			return ns[cn];
		}
		else{
			return new Error("methodPath illegal.");
		}
	}
var ie,firefox,safari,opera,chrome;
ie=firefox=safari=opera=chrome=NaN;
if(typeof ActiveXObject=="function"){ie=6+(typeof XMLHttpRequest=="object"?1:0)+(typeof XDomainRequest=="object"?1:0)}
else if(/AppleWebKit\/\d+\.\d+/i.test(navigator.appVersion)){
if(typeof openDatabase=="function"){safari=parseFloat(navigator.appVersion.replace(/^[\s\S]*?Version.(\d+\.\d+)[\s\S]*$/i,"$1"))}
if(typeof MessageEvent=="function"){chrome = parseFloat(navigator.appVersion.replace(/^[\s\S]*?chrome.(\d+\.\d+)[\s\S]*$/i,"$1"))}
}
else if(typeof document.getBoxObjectFor=="function"){firefox=parseFloat(navigator.userAgent.replace(/^[\s\S]*?Firefox\/(\d+\.\d+)[\s\S]*$/i, "$1"))}
else if(typeof opera=="object"){opera=parseFloat(navigator.appVersion.replace(/^(\d+\.\d+)[\s\S]*$/i,"$1"))}
else{ie=6}
sys.box=ie?(document.compatMode=="BackCompat"?false:true):true;
sys.ie=ie,sys.firefox=firefox,sys.safari=safari,sys.opera=opera,sys.chrome=chrome,sys._is=_is,sys._arr=_arr,sys._fn=function(){};
sys.using=_using;
});
