/* core/base.js */
if (!Function.prototype.apply){
	Function.prototype.apply = function(object, parameters){
		var parameterStrings = [];
		if (!object)	object = window;
		if (!parameters)	parameters = [];   
		for (var i=0; i<parameters.length; i++)
			parameterStrings[i] = "parameters[" + i + "]";   
		object.__apply__ = this;
		var result = eval("object.__apply__(" + parameterStrings.join(", ") + ")");
		object.__apply__ = null;
   
		return result;
	}
}

var Class = {
	create: function(){
		return function(){
			this.initialize.apply(this, arguments);
		}
	},
	
	extend: function(destination, source){
		for (property in source) {
    		destination[property] = source[property];
  		}	
		return destination;
	}
}

var Delegate = {
	create: function (obj, func){
		var f = function()	{
			var target = arguments.callee.target;
			var func = arguments.callee.func;
			return func.apply(target, arguments);
		}
		f.target = obj;
		f.func = func;
		return f;
	}
};

var isFunction = function(a){ return typeof a == "function"; };
var isNull     = function(a){ return typeof a == "object" && !a; };
var isNumber   = function(a){ return typeof a == "number" && isFinite(a);};
var isObject   = function(a){ return (a && typeof a == "object") || isFunction(a);};
var isString   = function(a){ return typeof a == "string";};
var isArray    = function(a){ return isObject(a) && a.constructor == Array; };
var isUndef    = function(a){ return typeof a == "undefined";};
var DoUnchanged= function(a){ return a;}
var DoNothing  = function(){};

var $ = function(){
	var elements = [];
	for (var i = 0; i < arguments.length; i++){
    		var element = arguments[i];
		if (isString(element))
			element = document.getElementById(element);

	
    		if (arguments.length == 1) {
			return element;
		}
    		elements.push(element);
  	}

  	return elements;
};

var $E = function(){
	var elements = [];
	for (var i=0; i<arguments.length; i++){
    	var element = arguments[i];
		if (isString(element))
			element = document.getElementsByName(element);
		
		if (arguments.length == 1)
			return element;
    	elements.push(element);
	}
	return elements;
}

var $P = function(parameter, url){
	url = url || window.location.href;
	return URL.getParameter(parameter, url);
};

/* core/browser.js */
var Browser = {
	getCookie: function(label){
		return isNull(document.cookie.match(new RegExp("(^"+label+"| "+label+")=([^;]*)"))) ? "" : decodeURIComponent(RegExp.$2);
	},
	
	setCookie: function(label, value, expireTime,isBaseDomain){
		if(arguments.length>2){
			var expireDate=new Date(new Date().getTime()+expireTime*1000);
			if(isBaseDomain != undefined && isBaseDomain == 1){
				document.cookie = label + "=" + encodeURIComponent(value) + "; path=/; domain=xunlei.com; expires=" + expireDate.toGMTString() ;
			}else{
				document.cookie = label + "=" + encodeURIComponent(value) + "; path=/; domain=xunlei.com; expires=" + expireDate.toGMTString() ;
			}
		}else
			document.cookie = label + "=" + encodeURIComponent(value) + "; path=/; domain=xunlei.com";
	},
	
	clearCookie: function(label){
		Browser.setCookie(label, "");
	}
};

Browser.isFireFox = (window.navigator.appName == "Netscape");
Browser.isOpera = (window.navigator.userAgent.indexOf("opera") != -1);
Browser.isSaf = ((window.navigator.userAgent.indexOf("applewebkit") != -1) || (navigator.vendor == 'Apple Computer, Inc.'));
Browser.isMSIE = ((window.navigator.userAgent.toLowerCase().indexOf("msie") != -1) && (!Browser.isOpera) && (!Browser.isSaf));	
Browser.getnocacheurl = function(urlstr){
	var returnurl = "http://i.xunlei.com";
	var cachetime = new Date().getTime();
	 var index = urlstr.indexOf("cachetime=");
	 var param = urlstr.indexOf("?");
	 if(index == -1){
		 if(param == -1){
			 returnurl = urlstr + "?cachetime=" + cachetime;
		 }else{
			 returnurl = urlstr + "&cachetime=" + cachetime;
		 }
	 }else{
		 if(param == -1){
			 returnurl = urlstr.substring(0,index) + "?cachetime=" + cachetime;
		 }else{
			 returnurl = urlstr.substring(0,index) + "&cachetime=" + cachetime;
		 }
	 }
	 return returnurl.replace('&&','&').replace('?&','?');
};
/* core/enumerable.js */
var $break    = new Object();
var $continue = new Object();

var Enumerable = {
	each: function(iterator){
		var index = 0;
		try {
			this._each(function(value){
				try {
					iterator(value, index++);
				}catch (e){
					if (e != $continue) throw e;
				}
			});
		}catch (e){
			if (e != $break) throw e;
		}
	},
	
	all: function(iterator){
		var result = true;
		this.each(function(value, index){
			result = result && !!(iterator || DoUnchanged)(value, index);
			if (!result)
				throw $break;
		});
		return result;
	},
	
	any: function(iterator){
		var result = true;
		this.each(function(value, index){
			if (result = !!(iterator || DoUnchanged)(value, index)) 
				throw $break;
		});
		return result;
	},
	
	map: function(iterator){
		var results = [];
		this.each(function(value, index){
			results.push(iterator(value, index));
		});
		return results;
	},
	
	find: function(iterator){
		var result;
		this.each(function(value, index){
			if (iterator(value, index)){
				result = value;
				throw $break;
			}
		});
		return result;
	},
	
	select: function(iterator){
		var results = [];
		this.each(function(value, index){
			if (iterator(value, index))
				results.push(value);
    	});
    	return results;
	},
	
	grep: function(pattern, iterator){
		var results = [];
		this.each(function(value, index){
			var stringValue = value.toString();
			if (stringValue.match(pattern))
				results.push((iterator || DoUnchanged)(value, index));
		});
    	return results;
	},
	
	include: function(element){
		var found = false;
		this.each(function(value){
			if (value == element){
				found = true;
				throw $break;
			}
		});
		return found;
	},
	
	pluck: function(property){
		var results = [];
		this.each(function(value, index){
			results.push(value[property]);
		});
		return results;
	},
	
	max: function(iterator){
		var result;
		this.each(function(value, index){
			value = (iterator || DoUnchanged)(value, index);
			if (value >= (result || value))
				result = value;
		});
		return result;
	},
	
	min: function(iterator){
		var result;
		this.each(function(value, index){
			value = (iterator || DoUnchanged)(value, index);
			if (value <= (result || value))
				result = value;
		});
		return result;
	},  
	
	toArray: function(){
		return this.map(DoUnchanged);
	}
}
/* core/array.js */
var $A = function(iterable){
	if (!iterable) 
		return [];
	if (iterable.toArray)
    	return iterable.toArray();
	if (isString(iterable) || isUndef(iterable.length))
		return [iterable];
		
	var results = [];
	for (var i=0; i<iterable.length; i++)
		results.push(iterable[i]);
	return results;
}

if (!Array.prototype.push){
	Array.prototype.push = function(){
		var len = this.length; 
		for (var i=0; i<arguments.length; i++) { 
			this[len + i] = arguments[i]; 
		} 
		return this.length; 
	}
}

if (!Array.prototype.pop){
	Array.prototype.pop = function(){
		var returnValue = this[this.length - 1]; 
		this.length--; 
		return returnValue; 
	}
}

if (!Array.prototype.splice){
	Array.prototype.splice = function(start, deleteCount){
		var len = arguments.length - 2; 
		var returnValue = this.slice(start); 
		for (var i = 0; i < len; i++) { 
			this[start + i] = arguments[i + 2]; 
		} 
		for (var i = 0; i < returnValue.length - deleteCount; i++) { 
			this[start + len + i] = returnValue[deleteCount + i]; 
		} 
		this.length = start + len + returnValue.length - deleteCount; 
		returnValue.length = deleteCount; 
		return returnValue; 	
	}
}

Class.extend(Array.prototype, Enumerable);
Class.extend(Array.prototype, {
	_each: function(iterator){
		for (var i=0; i<this.length; i++)
			iterator(this[i]);
	},

	indexOf: function(element){
		var index = -1;
		this.each(Delegate.create(this, function(value, i){
			if (this[i] == element){
				index = i;
				throw $break;
			}
		}));
		return index;
	},
	
	contain: function(element){
		return this.indexOf(element) != -1;
	},
	
	clear: function(){
		this.length = 0;
	},
	
	insert: function(position){
		for (var i=arguments.length-1; i>0; i--)
			this.splice(position, 0, arguments[i]);
	},
	
	remove: function(position, count){
		count = isUndef(count) ? 1 : count;
		this.splice(position, count);
	},
	
	exclude: function(element){
		var position = this.indexOf(element);
		if (position == -1)
			return;
		this.remove(position);
	},
	
	empty: function(){
		return this.length == 0;
	},
	
	first: function(){
		return this[0];
	},
	
	last: function(){
		return this[this.length - 1];
	},
	
	clone: function(){
		return this.slice(0);
	},
	
	shuffle: function(){
		var result = [];
		var source = this.clone();
		var index;
		this.each(function(){
			index = Math.floor(Math.random()*source.length);
			result.push(source[index]);
			source.remove(index);
		});
		return result;
	}	
});

/* core/string.js */
Class.extend(String.prototype, {
	trim: function(){
		return this.replace(/(^\s+)|(\s+$)/g, "");	
	},
	
	bytes: function(){
		return this.replace(/[^\x00-\xff]/g, "  ").length;
	},
	
	truncate: function(bytes, tail){
		tail = tail || "";
		var result;
		for (var i=0; i<this.length; i++){
			if ((result=this.substr(0, i)).bytes() >= bytes)
				return result + tail;
		}
		return this.substr(0);
	},
	
	strip: function(){
		var temp = this;
		temp = temp.replace(/&/ig, "&amp;"); 
		temp = temp.replace(/</ig, "&lt;");
		temp = temp.replace(/>/ig, "&gt;");
		temp = temp.replace(/\"/ig, "&quot;");
		temp = temp.replace(/\'/ig, "&#39;");
		temp = temp.replace(/ /ig, "&nbsp;");
		temp = temp.replace(/(\r?\n)|\r/ig, "<br />");
		return temp;
	},
	
	revert: function(){
		var temp = this;
		temp = temp.replace(/&apos;/ig, "\'");
		temp = temp.replace(/&quot;/ig, "\"");
		temp = temp.replace(/&gt;/ig, ">");
		temp = temp.replace(/&lt;/ig, "<");
		temp = temp.replace(/&nbsp;/ig, " ");
		temp = temp.replace(/&amp;/ig, "&");
		temp = temp.replace(/<br.*?>|<\/p><p(\s*|\s+.+?)>/ig, "\n").replace(/<\/?p(\s*|\s+.+?)>/ig,"");
		return temp;
	},
		
	camelize: function(){
		var result = this.replace(new RegExp("(\\W)+", "g"), "");
		return result.charAt(0).toLowerCase() + result.substr(1);
	},
	replaceAll: function(s1,s2){    
		return this.replace(new RegExp(s1,"gm"),s2);    
	} 
})/* core/event.js */
var Events = function(){};
Events.prototype = {
	addEventListener: function(evt, handler){
		if (isUndef(this.__listeners__[evt]))
			this.__listeners__[evt] = [];
		else
			this.removeEventListener(evt, handler);
		this.__listeners__[evt].push(handler);		
	},
	
	removeEventListener: function(evt, handler){
		if (!isUndef(this.__listeners__[evt]))
			this.__listeners__[evt].exclude(handler);
	},
	
	dispatchEvent: function(evtObj){
		if (isString(evtObj))
			evtObj = {type:evtObj, target:this};
		if (!evtObj.type)	return;
		if (isUndef(evtObj.target))
			evtObj.target = this;
		//usage 1 : e.g. function clickHandler(evt){}
		(this[evtObj.type+"Handler"] || DoNothing)(evtObj);
		var queue = this.__listeners__[evtObj.type];
		if (!isUndef(queue)){
			for (var i=0; i<queue.length; i++){
				//usage 2 : e.g. this.addEventListener("click", function(evt){});
				if (isFunction(queue[i]))
					queue[i](evtObj);
				else if (isObject(queue[i])){
					var o = queue[i];
					//usage 3 : e.g. this.addEventListener("click", listener);
					//listener.handleEvent = function(evt){}
					(o.handleEvent || DoNothing)(evtObj);	
					//usage 4 : e.g. this.addEventListener("click", listener);
					//listener.click = function(evt){}
					(o[evtObj.type] || DoNothing)(evtObj);	
				}else{
					//error!	
				}
			}
		}
	}
};

Class.extend(Events, {
	initialize: function(object){
		if (isUndef(this._dispatcher))
			this._dispatcher = new Events();
		object.addEventListener    = this._dispatcher.addEventListener;
		object.removeEventListener = this._dispatcher.removeEventListener;
		object.dispatchEvent       = this._dispatcher.dispatchEvent;
		object.__listeners__ = {};
	},
	
	KEY_BACKSPACE: 8,
	KEY_TAB:       9,
	KEY_RETURN:   13,
	KEY_ESC:      27,
	KEY_LEFT:     37,
	KEY_UP:       38,
	KEY_RIGHT:    39,
	KEY_DOWN:     40,
	KEY_DELETE:   46,
	
	element: function(event){
		return event.target || event.srcElement;
	},
	
	isLeftClick: function(event){
		return (((event.which) && (event.which == 1)) || ((event.button) && (event.button == 1)));
	},
	
	pointerX: function(event){
		return event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
	},

	pointerY: function(event){
		return event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
	},
	
	stop: function(event){
		if (event.preventDefault){ 
			event.preventDefault(); 
			event.stopPropagation(); 
		}else{
			event.returnValue = false;
			event.cancelBubble = true;
		}
	},
	
	findElement: function(event, tagName){
		var element = Events.element(event);
		while (element.parentNode && (!element.tagName || (element.tagName.toUpperCase() != tagName.toUpperCase())))
			element = element.parentNode;
		return element;
	},
	
	__listeners__: [],
	
	addListener: function(obj, evt, handler, useCapture){
		if (evt == "keypress" && (obj.attachEvent || navigator.appVersion.match(/Konqueror|Safari|KHTML/)))
			evt = "keydown";
		useCapture = useCapture || false;
		Events.__listeners__.push([obj, evt, handler, useCapture]);
		if (obj.addEventListener)
			obj.addEventListener(evt, handler, useCapture);
		else if (obj.attachEvent)
			obj.attachEvent("on"+evt, handler);
	},
	
	removeListener: function(obj, evt, handler, useCapture){
		if (evt == "keypress" && (obj.attachEvent || navigator.appVersion.match(/Konqueror|Safari|KHTML/)))
			evt = "keydown";
		useCapture = useCapture || false;
		if (obj.removeEventListener)
			obj.removeEventListener(evt, handler, useCapture);
		else if (obj.detachEvent)
			obj.detachEvent("on"+evt, handler);
	},
	
	unloadListeners: function(){
		var listeners = Events.__listeners__;
		if (listeners.empty()) return;
		listeners.each(function(l){
			Events.removeListener.apply(this, l);
			l[2] = null;
		});
		listeners.clear();
	}
});

Events.addListener(window, "unload", Events.unloadListeners);

/* core/dom.js */
var Element = {
	visible: function(element){
		return $(element).style.display != "none";
	},
	
	toggle: function(){
		for (var i=0; i<arguments.length; i++){
			var element = $(arguments[i]);
			Element[Element.visible(element) ? "hide" : "show"](element);
		}
 	},
	
	hide: function(){
		for (var i=0; i<arguments.length; i++){
			$(arguments[i]).style.display = "none";
		}
	},
	
	show: function(){
		for (var i=0; i<arguments.length; i++){
			$(arguments[i]).style.display = "";
		}
	},
	
	remove: function(element){
		element = $(element);
		element.parentNode.removeChild(element);
	},
	
	classNames: function(element){
		return new Element.ClassNames(element);
	},
	
	hasClassName: function(element, className){
		if (!(element = $(element)))
			return;
		return Element.classNames(element).include(className);
	},
	
	addClassName: function(element, className){
		if (!(element = $(element))) 
			return;
		return Element.classNames(element).add(className);
	},

	removeClassName: function(element, className){
		if (!(element = $(element))) 
			return;
		return Element.classNames(element).remove(className);
	},
	
	replaceClassName: function(element, classNameSrc, classNameDest){
		if (!(element = $(element))) 
			return;
		return Element.classNames(element).replace(classNameSrc, classNameDest);
	},
	
	getStyle: function(element, style){
		return $(element).style[style];
	},
	
	setStyle: function(element, style){
		element = $(element);
		for (name in style) 
			element.style[name] = style[name];
	}
};


Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
	initialize: function(element){
		this.element = $(element);
	},
	
	_each: function(iterator){
		this.element.className.split(/\s+/).select(function(name){
			return name.length > 0;
		})._each(iterator);
	},
	
	set: function(className){
		this.element.className = className;
	},
  
	add: function(classNameToAdd){
		if (this.include(classNameToAdd)) 
			return;
		this.set(this.toArray().concat(classNameToAdd).join(" "));
	},
  
	remove: function(classNameToRemove){
		if (!this.include(classNameToRemove)) 
			return;
		this.set(this.select(function(className){
			return className != classNameToRemove;
		}).join(" "));
	},
	
	replace: function(classNameSrc, classNameDest){
		this.set(this.select(function(className){
			return className != classNameSrc && className != classNameDest;
		}).concat(classNameDest).join(" "));
	},
	
	toString: function(){
		return this.toArray().join(" ");
	}
}

Class.extend(Element.ClassNames.prototype, Enumerable);

if (window.HTMLElement){	
	if (!window.HTMLElement.prototype.insertAdjacentElement){
		window.HTMLElement.prototype.insertAdjacentElement = function(where, element){
			switch (where){
				case "beforeBegin":
					this.parentNode.insertBefore(element, this);
					break;
				case "afterBegin":
					this.insertBefore(element, this.firstChild);
					break;
				case "beforeEnd":
					this.appendChild(element);
					break;
				case "afterEnd":
					if(this.nextSibling)
						this.parentNode.insertBefore(element, this.nextSibling);
					else
						this.parentNode.appendChild(element);
					break;
            }
		}
	}
	
	if (!window.HTMLElement.prototype.insertAdjacentHTML){
		window.HTMLElement.prototype.insertAdjacentHTML = function(where, htmlText){
			var rng = this.ownerDocument.createRange();
			rng.setStartBefore(this);
			this.insertAdjacentElement(where, rng.createContextualFragment(htmlText));
		}
	}
}

var Insertion = {
	_insertContent: function(element, content, where){
		element = $(element);
		if (isString(content)){
			element.insertAdjacentHTML(where, content);
			return;
		}
		if (isObject(content)){
			element.insertAdjacentElement(where, content);
			return;
		}
	},
	
	before: function(element, content){
		Insertion._insertContent(element, content, "beforeBegin");
	},
	
	top: function(element, content){
		Insertion._insertContent(element, content, "afterBegin");
	},
	
	bottom: function(element, content){
		Insertion._insertContent(element, content, "beforeEnd");
	},
	
	after: function(element, content){
		Insertion._insertContent(element, content, "afterEnd");
	}	
};


/* core/form.js */
var Field = {
	clear: function(){
		for (var i=0; i<arguments.length; i++)
    		$(arguments[i]).value = "";
	},
	
	focus: function(element){
    	$(element).focus();
  	},
  
  	present: function(){
    	for (var i=0; i<arguments.length; i++)
      		if ($(arguments[i]).value == "") return false;
    	return true;
  	},
  
  	select: function(element){
    	$(element).select();
  	},
   
  	activate: function(element) {
    	element = $(element);
    	element.focus();
    	if (element.select)
      		element.select();
  	}
}

var Form = {	
	serialize: function(form){
		var elements = Form.getElements($(form));
		var query = [];
		var q;
		for (var i = 0; i < elements.length; i++) {
			if (!isUndef(q = Form.Element.serialize(elements[i])))
				query.push(q);
    	}    
    	return query.join('&');
	},

	getElements: function(form){
		form = $(form);
		var elements = [];
		for (var tagName in Form.Element.Serializers){
		  	var tagElements = form.getElementsByTagName(tagName);
		  	for (var j = 0; j < tagElements.length; j++)
				elements.push(tagElements[j]);
		}
		return elements;
	},
	
	getInputs: function(form, typeName, name){
		form = $(form);
		var inputs = form.getElementsByTagName("input");
		if (isUndef(typeName) && isUndef(name))
			return inputs;
			
		var matchingInputs = [];
		for (var i=0; i<inputs.length; i++){
			var input = inputs[i];
			if ((typeName && input.type != typeName) || (name && input.name != name)) 
				continue;
			matchingInputs.push(input);
		}
    	return matchingInputs;		
	},
	
	disable: function(form){
    	var elements = Form.getElements(form);
    	for (var i=0; i<elements.length; i++){
      		var element = elements[i];
      		element.blur();
      		element.disabled = true;
    	}
  	},

  	enable: function(form){
    	var elements = Form.getElements(form);
    	for (var i=0; i<elements.length; i++){
      		var element = elements[i];
	      	element.disabled = false;
    	}
  	},
	
	reset: function(form){
    	$(form).reset();
  	},

	create : function (attr) {
		
		var form=document.createElement("form");
		for( name in attr )
			eval("form."+name+"='"+attr[name]+"'");
		return form;

	},

	addfield : function (form, data) {

		for( name in data ) {

			var input = document.createElement("input");
			input.type = "text";
			input.name = name;
			input.value = data[name];
			form.appendChild(input);

		}

	}
};

Form.Element = {
	serialize: function(element){
		element = $(element);
		var method = element.tagName.toLowerCase();
    	var parameter = Form.Element.Serializers[method](element);
		if (!isNull(parameter)){
			var key = encodeURIComponent(parameter[0]);
			if (key.length == 0) 
				return;
			if (!isArray(parameter[1]))
        		parameter[1] = [parameter[1]];
			return parameter[1].map(function(value) {
				return key + '=' + encodeURIComponent(value);
		  	}).join("&");
		}
	},
	
	getValue: function(element){
		element = $(element);
		var method = element.tagName.toLowerCase();
		var parameter = Form.Element.Serializers[method](element);
		if (!isNull(parameter))
			return parameter[1];
	}
}

Form.Element.Serializers = {
	input: function(element){
		switch (element.type.toLowerCase()){
			case "submit":
			case "hidden":
			case "password":
			case "text":
				return Form.Element.Serializers.textarea(element);
			case "checkbox":  
			case "radio":
				return Form.Element.Serializers.inputSelector(element);
		}
		return null;
  	},
	
  	textarea: function(element){
    	return [element.name, element.value];
  	},
	
  	inputSelector: function(element){
    	if (element.checked)
      		return [element.name, element.value];
  	},
	
	select: function(element){
    	return Form.Element.Serializers[element.type == "select-one" ? "selectOne" : "selectMany"](element);
  	},
  
  	selectOne: function(element){
    	var value = "";
		var opt;
		var index = element.selectedIndex;
    	if (index >= 0){
      		opt = element.options[index];
      		value = opt.value;
      		if (!value && !("value" in opt))
        		value = opt.text;
    	}
    	return [element.name, value];
  	},
  
  	selectMany: function(element){
    	var value = [];
    	for (var i=0; i<element.length; i++){
      		var opt = element.options[i];
      		if (opt.selected){
        		var optValue = opt.value;
        		if (!optValue && !('value' in opt))
          			optValue = opt.text;
        		value.push(optValue);
      		}
    	}
    	return [element.name, value];
  	}
}

var $F = Form.Element.getValue;















/* core/url.js */
var URL = {
	getParameter: function(parameter, url){
		var value = isNull(url.match(new RegExp("[?#&]"+parameter+"=(.*?)(?:[#&]|$)", "i"))) ? "" : RegExp.$1;
		return value.strip();
	},
	
	getSuffix: function(url){
		var dot = url.lastIndexOf(".");
		return dot==-1 ? "" : url.substr(dot+1);
	},
	
	getProtocol: function(url){
		return isNull(url.match(/^(\w+):\/\//)) ? "" : RegExp.$1;
	},
	
	getHost: function(url){
		return isNull(url.match(/:\/\/([a-zA-Z0-9.]+)/)) ? "" : RegExp.$1;
	},
	
	getHostPort : function(url){
		return isNull(url.match(/:\/\/([a-zA-Z0-9.:]+)/)) ? "" : RegExp.$1;
	},
	
	isValid: function(url){
		//if (!isNull())
		return true;
	},
	
	isLocal: function(url){
		return !isNull(url.match(/(^file|^[A-Za-z]):/i));
	}
}
/* core/xml.js */
var XML = {};
XML.Parser = {
	parseFromString: function(xmlStr, ignoreWhite){
		if (Browser.isFireFox && (isUndef(ignoreWhite) ? true : ignoreWhite)){
			var reg = /<!\[CDATA\[(.*?)\]\]>/ig;
			var reg2 = /<!\[CDATA\[\.\]\]>/i;
			var ret = $A(xmlStr.match(reg));
			xmlStr = xmlStr.replace(reg, "<![CDATA[.]]>").replace(/>\s+?</g, "><");
			for (var i=0; i<ret.length; i++){
				xmlStr = xmlStr.replace(reg2, ret[i]);
			}			
		}
		
		var xmlDoc = null;
		try{
			if (window.DOMParser){
				xmlDoc = new DOMParser().parseFromString(xmlStr, "text/xml");
				return xmlDoc;
			}else{
				var XMLDOM = ["MSXML4.DOMDocument",
							   "MSXML3.DOMDocument",
							   "MSXML2.DOMDocument",
							   "MSXML.DOMDocument",
							   "Microsoft.XmlDom"];
				var parser = null;
				for (var i=0; i<XMLDOM.length; i++){
					try{
						parser = new ActiveXObject(XMLDOM[i]);
						break;
					}catch(e){}
				}
				if (!parser) throw "init dom parser error!";
				parser.loadXML(xmlStr);
				return parser;
			}
		}catch(e){ 
			//alert(isString(e) ? e : e.message);	
		}
		return null;
	},
	
	parseToObject: function(xmlDoc){
		var isTextNode = function(node){
			return (node)&&(node.nodeType == 3 || node.nodeType == 4);
		};
		var parse = function(element){
			if (isTextNode(element))
				throw "xml format error!";
									
			var obj = {};
			for (var i=0; i<element.attributes.length; i++){
				var attr = element.attributes[i];
				obj[attr.nodeName] = attr.nodeValue;
			}
			
			if (!element.hasChildNodes())
				return obj;
			
			for (var i=0; i<element.childNodes.length; i++){
				var child = element.childNodes[i];
				if (isTextNode(child))
					return child.nodeValue;
								
				var node = obj[child.nodeName];
				var result = parse(child);				
				if (isUndef(node)) obj[child.nodeName] = result;
				else{
					isArray(node) ? obj[child.nodeName].push(result) 
						: (obj[child.nodeName] = [node, result]);
				}				
			}
						
			return obj;
		}
		return parse(xmlDoc.documentElement);
	}
}
/* core/ajax.js */
var Ajax = {
	getTransport: function(){
		if (window.XMLHttpRequest)	
			return new XMLHttpRequest();
		var XMLHTTP = ["Msxml2.XMLHTTP.6.0",
					   "Msxml2.XMLHTTP.5.0",
					   "Msxml2.XMLHTTP.4.0",
					   "Msxml2.XMLHTTP.3.0",
					   "Msxml2.XMLHTTP.2.6",
					   "Microsoft.XMLHTTP.1.0",
					   "Microsoft.XMLHTTP.1",
					   "Microsoft.XMLHTTP"];
		for (var i=0; i<XMLHTTP.length; i++){
			try{
				return new ActiveXObject(XMLHTTP[i]);
			}catch (e){}
		}
		return null;
	}
};

Ajax.Response = function(){};
Ajax.Response.prototype = {
	getResponseXML: function(){},
	getResponseText: function(){},
	getResponseObject: function(){},
	getResponseJSON: function(){}
};

Ajax.Request = Class.create();
Ajax.Request.Events = ["Uninitialized", "Loading", "Loaded", "Interactive", "Complete"];
Ajax.Request.prototype = {
	initialize: function(url, options){
		this._url     = url;
		this._options = {};
		Class.extend(this._options, options || {});		
		this._request = this.makeRequest();		
	},
	
	makeRequest: function(){
		if (URL.getHost(this._url) == URL.getHost(window.location.href)
						|| URL.isLocal(window.location.href)){
			return new Ajax.XMLHttpRequest(this._url, this._options);
		}
		
		return new Ajax.IFrameBridgeRequest(this._url, this._options);
	},
	
	cancel: function(){
		this._request.cancelRequest();
	}
}


Ajax.Base = function(){};
Ajax.Base.prototype = {
	makeRequest: function(){},
	cancelRequest: function(){},
	initResponse: function(){},
	dispatchEvents: function(){},
	setOptions: function(options){
		var opt = {
			method:"GET", 	//GET.POST
			async: true, 	//false
			parameters: "", 
			headers: [],
			response: null, //Text.XML.Object.JSON
			responseHeaders: [], 
			bridge: "/web/bridge.htm"
		};
		Class.extend(opt, options || {});
		opt.method = opt.method.toUpperCase();
		return opt;
	},
	
	setListener: function(options){
		Events.initialize(this);
		for (var opt in options){
			if (!isNull(opt.match(new RegExp("^on"))) && isFunction(options[opt])){
				this._response[opt] = this._options[opt];
				this.addEventListener(opt, this._response);
			}
		}
	},
		
	success: function(){
		return isUndef(this._transport.status) ||
				this._transport.status == 0 ||
				(this._transport.status >= 200 && this._transport.status < 300);
	}	
}


Ajax.XMLHttpRequest = Class.create();
Ajax.XMLHttpRequest.prototype = Class.extend(new Ajax.Base(), {
	initialize: function(url, options){
		this._url       = url;
		this._options   = this.setOptions(options);
		this._transport = Ajax.getTransport();
		this._response  = new Ajax.Response();
		this._alreadyResponse = false;
		this.initResponse();
		this.setListener(options);
		this.makeRequest();
	},
		
	setRequestHeaders: function(){
		var headers = this._options.headers;
		if (this._options.method == "POST")
			headers.push({label:"Content-type", value:"application/x-www-form-urlencoded"});
		if (this._transport.overrideMimeType)
			headers.push({label:"Connection", value:"close"});
			
		for (var i=0; i<headers.length; i++){
			this._transport.setRequestHeader(headers[i].label, headers[i].value);	
		}
	},
	
	initResponse: function(){
		this._response.getResponseXML = Delegate.create(this, function(){	
			return !Browser.isFireFox ? this._transport.responseXML : 
					XML.Parser.parseFromString(this._transport.responseText);
		}),
		
		this._response.getResponseText = Delegate.create(this, function(){
			return this._transport.responseText;
		}),
		
		this._response.getResponseObject = Delegate.create(this, function(){
			return XML.Parser.parseToObject(this._response.getResponseXML());
		}),
		
		this._response.getResponseJSON = Delegate.create(this, function(){
			return eval("(" + this._transport.responseText + ")");
		})
	},
	
	makeRequest: function(){
		try{
			if (this._options.method == "GET" && this._options.parameters.length > 0)
				this._url += (this._url.indexOf("?") == -1 ? "?" : "&") + this._options.parameters;
			
			if (this._options.async){
				this._transport.onreadystatechange = Delegate.create(this, this.dispatchEvents);					
			}
			this._transport.open(this._options.method, this._url, this._options.async);
			this.setRequestHeaders();
			this._transport.send(this._options.method == "POST" ? this._options.parameters : null);
		}catch(e){
			alert(isString(e)?e:e.message);
			this.dispatchEvent({type:"onException", exception:e});
		}		
	},
	
	dispatchEvents: function(){
		var evt = Ajax.Request.Events[this._transport.readyState];
		if (evt != "Complete")
			this.dispatchEvent("on"+evt);
		else{
			this._transport.onreadystatechange = DoNothing;
			var allHeaders = this._transport.getAllResponseHeaders();
			this.dispatchEvent({type:"onComplete", status:this._transport.status, headers:allHeaders});
			this._alreadyResponse = true;
			
			var evtObj = {type:"on"+this._transport.status, headers:allHeaders};
			var headers = this._options.responseHeaders;
			for (var i=0; i<headers.length; i++)
				evtObj[headers[i].camelize()] = this._transport.getResponseHeader(headers[i]);
			this.dispatchEvent(evtObj);	
	
			if (!this.success())
				this.dispatchEvent("onFailure");
			else{
				evtObj.type = "onSuccess";
				try{
					evtObj.response = (this._response["getResponse" + this._options.response] || DoNothing)();
					this.dispatchEvent(evtObj);
				}catch(e){
					this.dispatchEvent({type:"onException", exception:e});
				}
			}
			
			this._options   = null;
			this._response  = null;
			this._transport = null;			
		}
	},
	
	cancelRequest: function(){
		if (!this._alreadyResponse){
			this._transport.abort();
			this.dispatchEvent("onCancel");
		}
	}
});


Ajax.IFrameBridgeRequest = Class.create();
Ajax.IFrameBridgeRequest.prototype = Class.extend(new Ajax.Base(), {
	initialize: function(url, options){
		this._url      = url;
		this._options  = this.setOptions(options);
		this._content  = null;
		this._request  = null;
		this._response = new Ajax.Response();
		this._cancel   = false;
		this._bridge   = "bridge_" + URL.getHost(this._url).replace(/\./g, "_");
		this.setListener(options);
		this.checkBridge();		
	},
	
	checkBridge: function(){
		this._transport = $(this._bridge);
		if (!this._transport){
			this.initBridge();
		}else{
			if (this._transport.getAttribute("loaded")){
				this.makeRequest();
			}else{
				var interval = setInterval(Delegate.create(this, function(){
					if (this._transport.getAttribute("loaded")){
						clearInterval(interval);
						this.makeRequest();
					}
				}), 50);
			}
		}
	},
	
	initBridge: function(){
		var iframe = document.createElement("iframe");
		iframe.id = this._bridge;
		iframe.width = iframe.height = 0;	
		iframe.style.visibility = "hidden";
		document.body.appendChild(iframe);
		this._transport = iframe;
		Events.addListener(iframe, Browser.isMSIE ? "readystatechange" : "load", Delegate.create(this, this.onBridgeLoaded));
		//iframe[Browser.isMSIE ? "onreadystatechange" : "onload"] = Delegate.create(this, this.onBridgeLoaded);
		iframe.src = "http://" + URL.getHostPort(this._url) + this._options.bridge;
	},
	
	onBridgeLoaded: function(){
		if (Browser.isMSIE && this._transport.readyState != "complete")		return;
		//this._transport[Browser.isMSIE ? "onreadystatechange" : "onload"] = null;
		this._transport.setAttribute("loaded", "loaded");
		this.makeRequest();
	},
	
	makeRequest: function(){
		this._content = this._transport.contentWindow;
		var options = {events:[], dispatcher:{}};
		Events.initialize(options.dispatcher);
		for (var opt in this._options){
			if (opt.match(new RegExp("^on")) && isFunction(this._options[opt])){
				options.events.push(opt);
				options.dispatcher.addEventListener(opt, this._response);
			}else{
				options[opt] = this._options[opt];
			}
		}
		try{
			if (!this._cancel)
				this._request = this._content.makeRequest(this._url, options);
		}catch(e){}
	},
	
	cancelRequest: function(){
		this._cancel = true;
		if (this._request) this._request.cancelRequest();
	}
});

/*
Ajax.IFrameRequest = Class.create();
Ajax.IFrameRequest.prototype = Class.extend(new Ajax.Base(), {
	initialize: function(url, options){
		this._url       = url;
		this._transport = null;
		this._options   = this.setOptions(options);
		this._response  = new Ajax.Response();
		this.initResponse();
		this.setListener(options);
		this.makeRequest();
	},
	
	initResponse: function(){
		this._response.getResponseText = Delegate.create(this, function(){
			return this._transport.responseText;
		}),
		
		this._response.getResponseJSON = Delegate.create(this, function(){
			return eval("(" + this._transport.responseText + ")");
		})		
	},
	
	makeRequest: function(){
		var iframe = document.createElement("iframe");
		iframe.width = iframe.height = 0;		
		iframe.style.visibility = "hidden";
		document.body.appendChild(iframe);
		this._transport = iframe;
		iframe.onreadystatechange = Delegate.create(this, this.dispatchEvents);
		iframe.src = this._url;
	},
	
	dispatchEvents: function(){
		if (this._transport.readyState == "complete"){	
			this.dispatchEvent("onComplete");
			try{
				this._transport.responseText = this._transport.contentWindow.document.body.innerHTML;
				var evtObj = {type:"onSuccess"};
				evtObj.response = (this._response["getResponse" + this._options.response] || DoNothing)();
				this.dispatchEvent(evtObj);
			}catch(e){
				this.dispatchEvent({type:"onException", exception:e});
			}	
		}
	}
});

Ajax.XDomainScriptRequest = Class.create();
Ajax.XDomainScriptRequest.prototype = Class.extend(new Ajax.Base(), {
	initialize: function(url, options){
		this._url       = url;
		this._transport = null;
		this._options   = this.setOptions(options);
		this._response  = new Ajax.Response();
		this.initResponse();
		this.setListener(options);
		this._script = this.makeRequest();
	},
	
	initResponse: function(){
		this._response.getResponseText = Delegate.create(this, function(){
			return this._transport.responseObject;
		}),
		
		this._response.getResponseJSON = Delegate.create(this, function(){
			return eval("(" + this._transport.responseObject + ")");
		}),
		
		this._response.getResponseObject = Delegate.create(this, function(){
			return this._transport.responseObject;
		})
	},
	
	makeRequest: function(){
		var script = document.createElement("script");
	//	document.getElementsByTagName("head")[0].appendChild(script);
		document.body.appendChild(script);
		this._transport = script;
		script.onreadystatechange = Delegate.create(this, this.dispatchEvents);
		script.type = "text/javascript";
		script.src = this._url;
	},
	
	dispatchEvents: function(){
		if (this._transport.readyState == "loaded" || this._transport.readyState == "complete"){
			this.dispatchEvent("onComplete");
			try{
			//	alert(this._options.variable);
				setTimeout(Delegate.create(this, function(){
					this._transport.responseObject = eval(this._options.variable);
			//		alert(this._options.variable + "   = \n" + this._transport.responseObject);
					var evtObj = {type:"onSuccess"};
					evtObj.response = (this._response["getResponse" + this._options.response] || DoNothing)();
					this.dispatchEvent(evtObj);
				}), 1);				
			}catch(e){
				this.dispatchEvent({type:"onException", exception:e});
			}
		}
	}
});
*/
/* core/table.js */
var TABLE = {
	
	getRows : function (tableid) {
		return $(tableid).rows?$(tableid).rows:$(tableid).firstChild.childNodes;
	},

	deleteRow : function (tableid, rownum) {
		$(tableid).deleteRow(rownum);
	}

}
/* core/iframe.js */
var IFrame = {

	create : function (attr) {
		
		var ifr=null;

		if( Browser.isMSIE ) {
				
			var attr_str="";
			for( name in attr )
				attr_str+=(" "+name+"='"+attr[name]+"' ");
			ifr=document.createElement("<iframe "+attr_str+" />");

		}
		else {
				
			ifr=document.createElement("iframe");
			for( name in attr )
				eval("ifr."+name+"='"+attr[name]+"'");

		}

		return ifr;

	}

};/* core/json.js */
var Json = {

};

Json.Request = Class.create();

Json.Request.prototype = {
	initialize: function(url, options){
		this._ifr = null;
		this._form = null;
		this._url = url;
		this._domain_success_instance = null;
		this._data_success_instance = null;
		this._options = { method: "GET", domain: "http://i.xunlei.com/domain.html" };
		Class.extend(this._options, options || {});		
		this.makeRequest();		
	},
	
	makeRequest: function(){
		var ifr_name="poster_iframe_"+(new Date().getTime())+"_"+parseInt(Math.random()*100000);
		this._ifr = IFrame.create( {name:ifr_name,
										width: "0",
										height: "0",
										id: ifr_name} );
		Element.setStyle(this._ifr, {visibility: "hidden"});
		document.body.appendChild(this._ifr);

		if( this._options.method=="GET" ) {
			
			if( this._options.parameters )
				this._ifr.src=(this._url+"?"+this._options.parameters);
			else
				this._ifr.src=this._url;
			this._data_success_instance=Delegate.create(this, this.dataLoadSuccess);
			Events.addListener( this._ifr, "load",  this._data_success_instance );

		}
		else {

			this._ifr.src=this._options.domain;
			this._domain_success_instance=Delegate.create(this, this.domainLoadSuccess);
			Events.addListener( this._ifr, "load", this._domain_success_instance );

		}
		
	},

	removeRequest: function () {
		
		if(this._ifr) document.body.removeChild(this._ifr);
		if(this._form) document.body.removeChild(this._form);

	},
	
	domainLoadSuccess : function () {

		Events.removeListener(this._ifr, "load", this._domain_success_instance);//remove event listener
			
		this._form=Form.create( 
								{ 
									method: "post",
									target: this._ifr.name,
									action: this._url
								} 
							  );
		Element.setStyle(this._form, {display: "none"});
		Form.addfield( this._form, this.getPostData() );
		document.body.appendChild(this._form);

		this._data_success_instance=Delegate.create(this, this.dataLoadSuccess);
		Events.addListener(this._ifr, "load",  this._data_success_instance);

		this._form.submit();

	},
	
	dataLoadSuccess : function () {
	
		if( this._options.onSuccess ) 
			this._options.onSuccess(this._ifr);
		
		this.removeRequest();

	},

	getPostData : function () {
		
		var data={};
		var param=this._options.parameters;
		if( !param || param.length==0 ) return data;

		var arr=param.split("&");
		for(var i=0; i<arr.length; i++) {

			var pos=arr[i].indexOf("=");
			if(pos<0) continue;
			
			var name=arr[i].substring(0, pos);
			var value=decodeURIComponent( arr[i].substr(pos+1) );
			data[name]=value;

		}

		return data;

	}
}


/* utils/animation.js */
var Motion = Class.create();
Motion.prototype = {
	initialize: function(obj, prop, func, begin, finish, duration){
		this.obj = obj;
		this.prop = prop;
		this.func = func;
		this.begin = begin;
		
		this.isPlaying = false;
		this.prevTime = 0;
		this.prevPosition = 0;
		this.looping = false;		

		this.change = 0;
		this._fps = 25;
		this._time = 0;
		this._finish = 0;
		this._duration = 0;
		this._position = 0;
		this._startTime = 0;
		this._intervalID = 0;
		
		Events.initialize(this);
		
		this.setDuration(duration);
		this.setPosition(begin);
		this.setFinish(finish);				
	},
	
	setTime: function(t){
		this.prevTime = this._time;
		if (t > this._duration){
			if (this.looping){
				this.rewind (t - this._duration);
				this.dispatchEvent("onMotionLoop");
			}else{
				this._time = this._duration;
				this.stop();
				this.dispatchEvent("onMotionFinish");
			}
		}else if(t < 0){
			this.rewind();
		}else{
			this._time = t;
		}
	},
	
	setDuration: function(d){
		this._duration = (!d || d <= 0) ? Infinity : d;
	},
	
	setFPS: function(fps){
		var oldIsPlaying = this.isPlaying;
		this.stopMotion();
		this._fps = fps;
		if (oldIsPlaying){
			this.startMotion();
		}
	},
	
	setPosition: function(p){
		this.prevPosition = this._position;
		this.obj[this.prop] = this._position = p;
		this.dispatchEvent({type:"onMotionChange", position:this._position});
	},
	
	getPosition: function(t){
		t = t || this._time;
		return this.func(t, this.begin, this.change, this._duration);
	},
	
	setFinish: function(f){
		this.change = f - this.begin;
	},
	
	getFinish: function(){
		return this.begin + this.change;
	},
	
	start: function(){
		this.rewind();
		this.startMotion();
		this.dispatchEvent("onMotionStart");
	},
	
	stop: function(){
		this.stopMotion();
		this.dispatchEvent("onMotionStop");
	},

	resume: function(){
		this.fixTime();
		this.startMotion();
		this.dispatchEvent("onMotionResume");
	},

	rewind: function(t){
		this._time = t || 0;
		this.fixTime();
		this.update();
	},
	
	startMotion: function(){
		this._intervalID = setInterval(Delegate.create(this, function(){
			this.onTicktack();														  
		}), 1000 / this._fps);
		this.isPlaying = true;
	},
	
	stopMotion: function(){
		clearInterval(this._intervalID);
		this.isPlaying = false;
	},
	
	onTicktack: function(){
		this.setTime((new Date().getTime() - this._startTime) / 1000);
		this.update();
	},
	
	fixTime: function(){
		this._startTime = new Date().getTime() - this._time*1000;
	},
	
	update: function(){
		this.setPosition(this.getPosition(this._time));
	},
	
	continueTo: function(finish, duration){
		this.begin = this.getPosition();
		this.setFinish(finish);
		if (!isUndef(duration))
			this.setDuration(duration);
		this.start();
	},
	
	yoyo: function(){
		this.continueTo(this.begin, this.time);
	}
};

var Easing = {};
Easing.None = {
	easeNone: function(t, b, c, d){
		return c*t/d + b;
	},
	
	easeIn: function(t, b, c, d){
		return c*t/d + b;
	},
	
	easeOut: function(t, b, c, d){
		return c*t/d + b;
	},
	
	easeInOut: function(t, b, c, d){
		return c*t/d + b;
	}
};

Easing.Strong = {
	easeIn: function(t, b, c, d){
		return c*(t/=d)*t*t*t*t + b;
	},
	
	easeOut: function(t, b, c, d){
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	
	easeInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	}
}

Easing.Regular = {
	easeIn: function(t, b, c, d){
		return c*(t/=d)*t + b;
	},
	
	easeOut: function(t, b, c, d){
		return -c *(t/=d)*(t-2) + b;
	},
	
	easeInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	}
}

Easing.Bounce = {
	easeOut: function(t, b, c, d){
		if ((t/=d) < (1/2.75)) return c*(7.5625*t*t) + b;
		if (t < (2/2.75)) 	return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		if (t < (2.5/2.75)) return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;		
	},
	
	easeIn: function(t, b, c, d){
		return c - Easing.Bounce.easeOut(d-t, 0, c, d) + b;
	},
	
	easeInOut: function(t, b, c, d){
		if (t < d/2) return Easing.Bounce.easeIn(t*2, 0, c, d) * .5 + b;
		else return Easing.Bounce.easeOut (t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
}

Easing.Back = {
	easeIn: function(t, b, c, d, s){
		s = s || 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	
	easeOut: function(t, b, c, d, s){
		s = s || 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	
	easeInOut: function(t, b, c, d, s){
		s = s || 1.70158; 
		if ((t/=d/2) < 1) 	return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	}
};

Easing.Elastic = {
	easeIn: function(t, b, c, d, a, p){
		if (t==0) return b;  
		if ((t/=d)==1) return b+c;  
		if (!p) p=d*.3;
		if (!a || a < Math.abs(c)) { a=c; 	var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	
	easeOut: function(t, b, c, d, a, p){
		if (t==0) return b;  
		if ((t/=d)==1) return b+c;  
		if (!p) p=d*.3;
		if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
	},
	
	easeInOut: function(t, b, c, d, a, p){
		if (t==0) return b;  
		if ((t/=d/2)==2) return b+c;  
		if (!p) p=d*(.3*1.5);
		if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	}
};


/* utils/flash.js */
var Flash = Class.create();
Flash.prototype = {
	initialize: function(src, options){
		this._attributes = [];
		this._variables = {};
		this._parameters = {};
		this.installedVersion = Flash.getPlayerVersion();
		if (src) this.setAttribute("src", src);
		if (options.id) this.setAttribute("id", options.id);
		if (options.width) this.setAttribute("width", options.width);
		if (options.height) this.setAttribute("height", options.height);
		this.setAttribute("version", options.version || "8.0.22");
		this.addParameter("quality", options.quality || "high");
		this.addParameter("allowScriptAccess", options.allowScriptAccess || "always");
		
		if (!Flash.created){
			Flash.created = true;
			//prevent memory leaks in ie!
			Events.addListener(window, "unload", Flash.clear);
		}
	},
	
	setAttribute: function(name, value){
		this._attributes[name] = value;
	},
	
	getAttribute: function(name){
		return this._attributes[name];
	},
	
	addParameter: function(name, value){
		this._parameters[name] = value;
	},
	
	getParameters: function(){
		return this._parameters;
	},
	
	addVariable: function(name, value){
		this._variables[name] = value;
	},
	
	getVariable: function(name){
		return this._variables[name];
	},
	
	getVariables: function(){
		return this._variables;
	},
	
	getVariablePairs: function(){
		var pairs = [];
		var name;
		for (name in this._variables)
			pairs.push(name + "=" + this._variables[name]);
		return pairs;
	},
	
	getHTML: function(){
//		var src = + (pairs ? "?"+pairs : "");
		var src = this.getAttribute("src");
		var pairs = this.getVariablePairs().join("&").trim();
		if (pairs) this.addParameter("flashvars", pairs);
		var embed = '<embed type="application/x-shockwave-flash" src="' + src 
					+ '" width="'+ this.getAttribute("width") + '" height="' + this.getAttribute("height") + '" ';
		var param = '<param name="movie" value="' + src + '" />';
		var parameters = this.getParameters();
		for(var name in parameters){
			param += '<param name="' + name + '" value="' + parameters[name] + '" />';
			embed += name + '="' + parameters[name] + '" '; 
		}

		embed += "/>";
		var html = '<object id="'+ this.getAttribute("id") +'" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000"' 
				+ ' width="' + this.getAttribute("width") + '" height="' + this.getAttribute("height") + '">'
				+ param + embed + "</object>";
		return html;
	},

	write: function(target){
		if (this.installedVersion.isValid(this.getAttribute("version")))
			$(target).innerHTML = this.getHTML();
	}
};

Flash.PlayerVersion = Class.create();
Flash.PlayerVersion.prototype = {
	initialize: function(version){
		this.major = (version[0] && !isNaN(parseInt(version[0]))) || 0;
		this.minor = (version[1] && !isNaN(parseInt(version[1]))) || 0;
		this.rev   = (version[2] && !isNaN(parseInt(version[2]))) || 0;
	},
	
	isValid: function(fv){
		if(this.major < fv.major) return false;
		if(this.major > fv.major) return true;
		if(this.minor < fv.minor) return false;
		if(this.minor > fv.minor) return true;
		if(this.rev < fv.rev) return false;
		return true;
	}
};

Flash.getPlayerVersion = function(){
	var version = new Flash.PlayerVersion([0, 0, 0]);
	var axo = null;
	if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length){
		var plugin = navigator.plugins["Shockwave Flash"];
		if(plugin && plugin.description) {
			version = new Flash.PlayerVersion
					(plugin.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
		}
	}else{
		var shockwaveFlash = ["ShockwaveFlash.ShockwaveFlash.9",
							  "ShockwaveFlash.ShockwaveFlash.8",
							  "ShockwaveFlash.ShockwaveFlash.7",
							  "ShockwaveFlash.ShockwaveFlash"];
		for (var i=0; i<shockwaveFlash.length; i++){
			try{
				axo =  new ActiveXObject(shockwaveFlash[i]);
				break;
			}catch (e){}
		}		
		if (axo != null){
			version = new Flash.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
		}
	}
	return version;
};

Flash.clear = function(){
	$A(document.getElementsByTagName("OBJECT")).each(function(obj){
		if (obj.classid.toUpperCase() == "CLSID:D27CDB6E-AE6D-11CF-96B8-444553540000"){
			for (var i in obj){
				if (isFunction(obj[i])) obj[i] = null;
			}
		}
	});
}

/* utils/html_repeater.js */
var HtmlRepeater = function(id) {
	this._id=id;//div之id
	this._value_map={};//基本变量替换
	this._arr_map={};//循环体对应数组
	this._callback_map={};//循环体的callback
	
	
	this._out_html="";
	this.TEMPLATE=document.getElementById(this._id).innerHTML;//第一次保存原始模板

	this.HTML_PARAM_MARK_BEGIN="<!--%";
	this.HTML_PARAM_MARK_END="%-->";
	
	this.HTML_REPEATER_BEGIN="<!--%$";
	this.HTML_REPEATER_END="_begin$%-->";
};

HtmlRepeater.getInstance = function(id) {
		if ( !this._pool )
			this._pool={};
		if ( !this._pool[id] )
		{
			this._pool[id]=new HtmlRepeater(id);
		}
		
		return this._pool[id];
}

HtmlRepeater.prototype = {
	
	run : function (method) {
		
		var index_begin=0, index_end=0;
		var repeater_begin=0, repeater_end=0;
		var tag="";
		var end_tag="";//<!--%$xxx_end$%-->
		
		while(1)
		{
			index_end=this.TEMPLATE.indexOf(this.HTML_REPEATER_BEGIN, index_begin);
			if ( index_end<0 )
			{
				this.doTemplate(this.TEMPLATE.substr(index_begin));
				break;
			}
			else
				this.doTemplate(this.TEMPLATE.substr(index_begin, index_end-index_begin));//前面的自由块
			
			repeater_begin=index_end+this.HTML_REPEATER_BEGIN.length;
			repeater_end=this.TEMPLATE.indexOf(this.HTML_REPEATER_END, repeater_begin);
			if ( repeater_end<0 )
				break;
			tag=this.TEMPLATE.substr(repeater_begin, repeater_end-repeater_begin);
			
			repeater_begin=repeater_end+this.HTML_REPEATER_END.length;
			end_tag="<!--%$"+tag+"_end$%-->";
			repeater_end=this.TEMPLATE.indexOf(end_tag, repeater_begin);
			
			this.doRepeat(this.TEMPLATE.substr(repeater_begin, repeater_end-repeater_begin), tag);
			
			index_begin=index_end=repeater_end+end_tag.length;
		}
		
		if ( !method )
		{
			document.getElementById(this._id).innerHTML=this._out_html;
		}
		else if ( method=="head" )//在头部添加
		{
			var tmp=this._out_html+document.getElementById(this._id).innerHTML;
			document.getElementById(this._id).innerHTML=tmp;
		}
		else if ( method=="tail" )//尾部添加
		{
			document.getElementById(this._id).innerHTML+=this._out_html;
		}
		else
			document.getElementById(this._id).innerHTML=this._out_html;
		
		document.getElementById(this._id).style.display="block";
		this.clear();//清空这次数据
	},
	
	clear : function (){
		this._out_html="";
		this._value_map={};
		this._arr_map={};
		this._callback_map={};
	},
	
	insertValue : function (name ,value) {
		this._value_map[name]=value;
		this._value_map[name+"_encode"]=encodeURIComponent(value);
	},
	
	insertArray : function (name, arr, callback) {
		this._arr_map[name]=arr;

		if(callback)
			this._callback_map[name]=callback;
	},
	
	inserObjectValue : function (obj) {
		for(var name in obj)
			this.insertValue(name, obj[name]);
	},

	insertObjectValue : function (obj) {
		for(var name in obj)
			this.insertValue(name, obj[name]);
	},

	doTemplate : function (p){
		var reg=null;
		for (var name in this._value_map)
		{
			reg=new RegExp("(&lt;|%3C|<)(%21|!)--%"+name+"%--(&gt;|>|%3E)", "g");
			p=p.replace(reg, this._value_map[name]);
		}
		this._out_html+=p;
	},
	
	doRepeat : function (p, name) {
		var arr=this._arr_map[name];
		if ( typeof(arr)=="undefined" )//没有设置此循环模板对应数组
		{
			return;
		}
		
		//如果设置了回调
		if(this._callback_map[name])
			return this._callback_map[name](this, p, this._arr_map[name]);

		for (var i=0; i<arr.length; i++ )
		{
			this.inserObjectValue(arr[i]);
			/*for (var name in arr[i])
				this.insertValue(name, arr[i][name]);*/
				
			this.doTemplate(p);
		}
	},

	getTemplate : function (p, begin, end) {
		var pBegin, pEnd;
		if(begin=="")
			pBegin=0;
		else
			pBegin=p.indexOf(begin);
		
		if(end=="")
			pEnd=p.length;
		else
			pEnd=p.indexOf(end);

		if(pBegin<0 || pEnd<0 || pBegin>pEnd)
			return "";
		
		pBegin+=begin.length;
		return p.substr(pBegin, pEnd-pBegin);
	}
};

/*//////////////////////////////////////testing///////////////////////////////////////////////
var g_arr = {
	head: {uin:"supergui", test1:"test1", test2:"test2"},
	list:[
	{uin:"yezhihui", i:"1"},
	{uin:"yezhihui", i:"2"},
	{uin:"yezhihui", i:"3"},
	{uin:"yezhihui", i:"4"},
	{uin:"yezhihui", i:"5"}
	],
	list2:[
	
	{uin:"fuck", i:"1"},
	{uin:"fuck", i:"2"},
	{uin:"fuck", i:"3"},
	{uin:"fuck", i:"4"},
	{uin:"fuck", i:"5"}
	
	]
};

function test()
{
	var Repeater = RepeaterManager.getInstance("test");
	
	//设置变量
	Repeater.insertValue("uin", g_arr.head.uin);
	Repeater.insertValue("test1", g_arr.head.test1);
	Repeater.insertValue("test2", g_arr.head.test2);
	
	//设置循环体对应数组
	Repeater.insertArray("list", g_arr.list);
	Repeater.insertArray("list2", g_arr.list2);
	
	Repeater.run();
}


<div id="test">
<p>大家好，我是<!--%uin%-->。靠，不是吧，我<!--%test1%-->不相信<!--%test2%-->啊</p>

<div>
<!--%$list_begin$%-->
这个一个列表啊<!--%uin%--><!--%i%-->
<!--%$list_end$%-->
</div>

<div>
<!--%$list2_begin$%-->
这是第二个列表啊<!--%uin%--><!--%i%-->
<!--%$list2_end$%-->
</div>


</div>

*//* utils/popup.js */
var Popup = Class.create();
Popup.prototype = {
	initialize: function(html){
		this._html = html;
		this._mask = null;
		this._popup = null;

		this._needdrag = true;
		this._startX = 0;
		this._startY=0;
		this._startTop = 0;
		this._startLeft = 0;
		this._mousedown = false;
	},
	destory:function(){
		if(this._popup)
			document.body.removeChild(this._popup);
		if(this._mask)
			document.body.removeChild(this._mask);
		Events.removeListener(window, "resize", Delegate.create(this, this._adjust));
		if( this._needdrag )  this._cleardrag();
	},
	show: function(module, needdrag){
		if (this._popup)
			Element.show(this._popup);
		else{
			this._popup = document.createElement("div");
			this._popup.id = "pop_div_"+(new Date().getTime());
			this._popup.innerHTML = this._html;
			Insertion.bottom(document.body, this._popup);
			Element.setStyle(this._popup, {
				position: "absolute",
				zIndex: 1001
			});

			Element.setStyle(this._popup.firstChild, {
				position: "relative",
				left: "0px",
				top: "0px",
				zIndex: 100
			});

		}
		//default use mask
		if (isUndef(module) || module){
			if (this._mask)
				Element.show(this._mask);
			else{
				this._mask = document.createElement("div");
				Insertion.bottom(document.body, this._mask);
				Element.setStyle(this._mask, {
					backgroundColor: "Black",
					filter: "alpha(opacity=40)",
					MozOpacity: "0.4",
					opacity: "0.4",
					position: "absolute",
					left: "0px",
					top: "0px",
					zIndex: 1000
				});
			}
		}
		
		//default use drag effect
		//if( !isUndef(needdrag) ) this._needdrag=needdrag;
		//if( this._needdrag ) this._setdrag();
		
		this._adjust();
		Events.addListener(window, "resize", Delegate.create(this, this._adjust));
		Events.addListener(window, "scroll", Delegate.create(this, this._adjust));
	},
	hide: function(){
		if (this._popup)
			Element.hide(this._popup);
		if (this._mask)
			Element.hide(this._mask);
		
		if( this._needdrag ) this._cleardrag();
	},
	_adjust: function(){

		Element.setStyle(this._mask, {
			width:  document.body.scrollWidth+"px",
			height: document.documentElement.scrollHeight+"px"
		});
		
		Element.setStyle(this._popup,{
			left: (parseInt(document.body.clientWidth)/2-parseInt(this._popup.firstChild.style.width)/2)+"px",
			top: (parseInt(document.documentElement.clientHeight/3))+"px"
		});

	},
	_setdrag: function () {
		Events.addListener(document.body, "mousedown", Delegate.create(this, this._onmousedown));
		Events.addListener(document.body, "mousemove", Delegate.create(this, this._onmousemove));
		Events.addListener(document.body, "mouseup", Delegate.create(this, this._onmouseup));
	},
	_cleardrag : function () {
		Events.removeListener(document.body, "mousedown", Delegate.create(this, this._onmousedown));
		Events.removeListener(document.body, "mousemove", Delegate.create(this, this._onmousemove));
		Events.removeListener(document.body, "mouseup", Delegate.create(this, this._onmouseup));
	},
	_checkmouse : function (event) {
		var element=Events.element(event);
		while(element && element.id!=this._popup.id && element.tagName!="BODY")element=element.parentNode;
		if( !element || element.tagName=="BODY" || element.id!=this._popup.id) return null;
		
		//now element=this._popup

		var distance=event.clientY-parseInt(Element.getStyle(element, "top"));
		//alert(distance);
		var range=40;//parseInt(parseInt(Element.getStyle(element, "height"))*20/100 )
		if(	distance > range )
			return null;
		else
			return element;
	},
	_onmousedown : function (event) {
		var element=this._checkmouse(event);
		if( !element ) return;

		this._mousedown = true; 
		this._startX = event.clientX; 
		this._startY = event.clientY; 
		this._startLeft = Element.getStyle(element, "left");
		this._startTop = Element.getStyle(element, "top");
	},
	_onmousemove : function (event) {
		var element=this._checkmouse(event);
		if( !element ){
			Element.setStyle(this._popup, { cursor: ""} );
		}
		else{
			if( Browser.isMSIE )
				Element.setStyle(this._popup, { cursor: "move"} );
			else
				Element.setStyle(this._popup, { cursor: "pointer"} );
		}

		if (this._mousedown){ 
			var cur_left=(parseInt(this._startLeft)+event.clientX-this._startX);
			var cur_top=(parseInt(this._startTop)+event.clientY-this._startY);
			Element.setStyle(this._popup,{
				left: cur_left+"px",
				top:  cur_top+"px"
			});
		}
	},
	_onmouseup : function () {
		this._mousedown = false; 
	}
	
};/* utils/thunder.js */
var Thunder = {
	getInstance: function(){
		//check webthunder first,then thunder5  
		var opt = [Thunder.WebThunder, Thunder.Thunder5];
		//var opt = [Thunder.Thunder5, Thunder.WebThunder];
		for (var i=0; i<opt.length; i++){
			try{
				return opt[i].getInstance();
			}catch(e){
				continue;
			}
		}
		throw "迅雷初始化失败";
	},
	
	setParameter: function(cid, url, refer, stat){
		var inputs = ["thunder_cid", "thunder_down_url", "thunder_down_pageurl", "thunder_stat_pageurl"];
		for (var i=0; i<inputs.length; i++){
			var input = $(inputs[i]);		
			if (isUndef(input) || isNull(input)){
				input = document.createElement("input");
				input.type = "hidden";
				input.id = inputs[i];
				document.body.appendChild(input);
			}
			input.value = arguments[i];
		}
	},
	
	download: function(cid, url, refer, name, stat){
		this.getInstance().download(cid, url, refer, name, stat);
	},
	
	batchDownload: function(data, stat){
		this.getInstance().batchDownload(data, stat);
	}
}

Thunder.WebThunder = Class.create();
Thunder.WebThunder.getInstance = function(){
//	if (isUndef(this._thunder))
//		this._thunder = new Thunder.WebThunder();
//	return this._thunder;
	return new Thunder.WebThunder();
}
Thunder.WebThunder.prototype = {	
	initialize: function(){
		this.__thunder = new ActiveXObject("ThunderServer.webThunder.1");
	},
	
	getVersion: function(){
		return parseInt(this.__thunder.GetVersion().split(".")[3]);
	},
	
	download: function(cid, url, refer, name, stat){
		this.__thunder.CallAddTask(url, name, refer, 1, cid, stat);
		return 0;
	},
	
	batchDownload: function(data, stat){
		var batchTask = this.__thunder.BeginBatchTask();
		if(batchTask == 0){
			alert("批量下载初始化失败");
			return;
		}
		
		var version = this.getVersion();
		for(var i=0; i<data.length; i++){
			if (version < 43)
				this.__thunder.AddTaskToBatch(batchTask, data[i].url, data[i].name, data[i].refer);
			else if (version < 54)
				this.__thunder.AddTaskToBatch(batchTask, data[i].url, data[i].name, data[i].refer, data[i].cid);	
			else
				this.__thunder.AddTaskToBatch(batchTask, data[i].url, data[i].name, data[i].refer, data[i].cid, stat);	
		}
		this.__thunder.EndBatchTask(batchTask);	
	}
}

Thunder.Thunder5 = Class.create();
Thunder.Thunder5.getInstance = function(){
	if (isUndef(this._thunder))
		this._thunder = new Thunder.Thunder5();
	return this._thunder;
}
Thunder.Thunder5.prototype = {
	initialize: function(){
		this.__thunder = new ActiveXObject("ThunderAgent.Agent.1");
	},
	
	download: function(cid, url, refer, name, stat){
		try{
			this.addTask(cid, url, refer, name, stat);
			this.commitTasks();
		}catch(e){
			alert(e.message);
		}
	},
	
	batchDownload: function(data, stat){
		try{
			for(i=0; i<data.length; i++)
				this.addTask(data[i].cid, data[i].url, data[i].refer, data[i].name, stat);
			this.commitTasks();
		}catch(e){
			alert(e.message);
		}
//		delete this.__thunder;
	},
	
	addTask: function(cid, url, refer, name, stat){
		var _addTask = [
			Delegate.create(this, function(){this.__thunder.AddTask4(url, "", "", name, refer, -1, 0, -1, "", cid, stat);}),
			Delegate.create(this, function(){this.__thunder.AddTask3(url, "", "", name, refer, -1, 0, -1, "", cid);}),
			Delegate.create(this, function(){this.__thunder.AddTask2(url, "", "", name, refer, -1, 0, -1, "");}),
			Delegate.create(this, function(){this.__thunder.AddTask(url, "", "", name, refer, -1, 0, -1);})
		];
		for (var i=0; i<_addTask.length; i++){
			try{
				_addTask[i]();
				return;
			}catch(e){	
			}
		}
		throw "不支持此方法，请安装最新的迅雷客户端";
	},
	
	commitTasks: function(){
		var _commitTasks = [
			Delegate.create(this, function(){this.__thunder.CommitTasks2(1);}),
			Delegate.create(this, function(){this.__thunder.CommitTasks();})
		];
		for (var i=0; i<_commitTasks.length; i++){
			try{
				_commitTasks[i]();
				return;
			}catch(e){
			}
		}
		throw "不支持此方法，请安装最新的迅雷客户端";
	}
}
/* utils/ejs.js */

var ejs={selectone:{},radio:{},checkbox:{}}

ejs._check_type = function(eObject, sType)
{
	return (!eObject||!(eObject.type)||sType!=eObject.type.toLowerCase())?false:true;
}

ejs.selectone.checkType=function(oSelect)
{
	return ejs._check_type(oSelect,"select-one");
//	return (!oSelect||!(oSelect.type)||"SELECT-ONE"!=oSelect.type.toUpperCase())?false:true;
}

ejs.selectone.clear=function(oSelect)
{
	if(!this.checkType(oSelect)) return null;
	//clear
	var count = oSelect.options.length;
	while((count--)>0)
	{
		oSelect.removeChild(oSelect.options[0]);
	}
	return oSelect;
}

ejs.selectone.push=function(oSelect,sText,sValue)
{
	if(!this.checkType(oSelect)) return;
	var oOption = new Option(sText,sValue);
	oSelect.options.add(oOption);
}

ejs.selectone.fill=function(oSelect,aData,sTextField,sValueField)
{
	if(!this.checkType(oSelect)) return;
	if(!sTextField||""==sTextField)sTextField="text";
	if(!sValueField||""==sValueField)sValueField="value";
	try
	{
		if(aData.length||0==aData.length)
		{
			for(var i=0;i<aData.length;i++)
				eval("this.push(oSelect,aData[i]."+sTextField+",aData[i]."+sValueField+");");
		}
		else
			for(key in aData)
				eval("this.push(oSelect,aData[key]."+sTextField+",aData[key]."+sValueField+");");
	}catch(ex){}
}

ejs.selectone.get=function(oSelect)
{
	if(!this.checkType(oSelect)) return;
	if(oSelect.selectedIndex<0) return null;
	var obj = new Object();
	obj.value = oSelect.options[oSelect.selectedIndex].value;
	obj.text = oSelect.options[oSelect.selectedIndex].innerHTML;
	return obj;
}

ejs.selectone.set=function(oSelect,oSelectedOption,isText)
{
	if(!this.checkType(oSelect)) return;
	if(!oSelectedOption)return;
	var sJudge = "if(oSelect.options[i].";
	if(isText)
	{
		sJudge += "innerHTML==";
		sJudge += (oSelectedOption.text)?"oSelectedOption.text":"oSelectedOption";
	}
	else
	{
		sJudge += "value==";
		sJudge += (oSelectedOption.text)?"oSelectedOption.value":"oSelectedOption";
	}
	sJudge += "){try{oSelect.options[i].selected=true;}catch(e){try{oSelect.options.selectedIndex=i;}catch(e2){alert('ejs.selectone.set');}}}else{oSelect.options[i].selected=false;}"

	for(var i=0;i<oSelect.options.length;i++)
		eval(sJudge);
}

ejs.selectone.setIndex=function(oSelect,iIdx)
{
	if(!this.checkType(oSelect)) return;
	iIdx = parseInt(iIdx);
	if(isNaN(iIdx)||iIdx<0||iIdx>=oSelect.options.length)return;
	for(var i=0;i<oSelect.options.length;i++)
		if(i==iIdx)
		{
			try{oSelect.options[i].selected=true;}catch(e){try{oSelect.options.selectedIndex=i;}catch(e2){alert('ejs.selectone.setIndex');}}
		}
}

/*
ejs.radio.set=function(oForm,name,target_value)
{
	if(!oForm)return;
	eval("var radio = oForm."+name+";")
	if(!radio)return;
	if(!target_value)return;
	for(var i=0;i<radio.length;i++)
	{
		if(radio[i].value==target_value.toString())
			radio[i].checked=true;
		else
			radio[i].checked=false;
	}
}

ejs.radio.get=function(oForm,name)
{
	if(!oForm)return null;
	eval("var radio = oForm."+name+";")
	if(radio==null)return;
	for(var i=0;i<radio.length;i++)
	{
		if(radio[i].checked==true)
		{
			return radio[i].value;
		}
	}
	return null;
}*/
ejs.radio.checkType = function(oRadio)
{
	return ejs._check_type(oRadio,"radio");
}

ejs.radio.set = function(oRadio,target_value)
{
	if(!this.checkType(oRadio)||!oRadio.name) return;
	if(!target_value)return;
	var radio_list = $A($E(oRadio.name));
	for(var i=0;i<radio_list.length;i++)
	{
		if(radio_list[i].value==target_value.toString())
			radio_list[i].checked=true;
		else
			radio_list[i].checked=false;
	}
}

ejs.radio.get = function(oRadio)
{
	if(!this.checkType(oRadio)||!oRadio.name) return null;
	var radio_list = $A($E(oRadio.name));
	for(var i=0;i<radio_list.length;i++)
	{
		if(radio_list[i].checked==true)
			return radio_list[i].value;
	}
	return null;
}

//可能要作废，请勿使用
ejs.checkbox.set=function(oForm,name,target_values)
{
	if(!oForm)return;
	eval("var chkbox = oForm."+name+";")
	if(!chkbox)return;
	if(!target_values)return;
	target_values = $A(target_values);
	for(var i=0;i<chkbox.length;i++)
	{
		for(var j=0;j<target_values.length;j++)
		{
			if(chkbox[i].value==target_values[j].toString())
				chkbox[i].checked=true;
		}
	}
}

ejs.checkbox.checkType = function(oCheckbox)
{
	return ejs._check_type(oCheckbox,"checkbox");
}

ejs.checkbox.isCheck = function(oCheckbox)
{
	if(!this.checkType(oCheckbox)) return null;
	return oCheckbox.checked;
}

ejs.checkbox.setCheck = function(oCheckbox)
{
	if(!this.checkType(oCheckbox)) return;
	oCheckbox.checked = true;
}

ejs.checkbox.setUnCheck = function(oCheckbox)
{
	if(!this.checkType(oCheckbox)) return;
	oCheckbox.checked = false;
}
/* utils/anchor.js */
var Anchor = {
	// 转换为数字
	_intval:function(v)
	{
		v = parseInt(v);
		return isNaN(v) ? 0 : v;
	},
	// 获取元素信息
	_getPos:function(e)
	{
		var l = 0;
		var t  = 0;
		var w = this._intval(e.style.width);
		var h = this._intval(e.style.height);
		var wb = e.offsetWidth;
		var hb = e.offsetHeight;
		while (e.offsetParent){
			l += e.offsetLeft + (e.currentStyle?this._intval(e.currentStyle.borderLeftWidth):0);
			t += e.offsetTop  + (e.currentStyle?this._intval(e.currentStyle.borderTopWidth):0);
			e = e.offsetParent;
		}
		l += e.offsetLeft + (e.currentStyle?this._intval(e.currentStyle.borderLeftWidth):0);
		t  += e.offsetTop  + (e.currentStyle?this._intval(e.currentStyle.borderTopWidth):0);
		return {x:l, y:t, w:w, h:h, wb:wb, hb:hb};
	},
	// 获取滚动条信息
	_getScroll:function() 
	{
		if (document.documentElement && document.documentElement.scrollTop) {
			var de = document.documentElement;
			return { t: de.scrollTop, l: de.scrollLeft, w: de.scrollWidth, h: de.scrollHeight };
		} else if (document.body) {
			var b = document.body;
			return { t: b.scrollTop, l: b.scrollLeft, w: b.scrollWidth, h: b.scrollHeight };
		}
		return { t: 0, l: 0, w: 0, h: 0 };
	}, 
	// 锚点(Anchor)间平滑跳转
	scroll:function(el, duration)
	{
		if(typeof el != 'object') { el = document.getElementById(el); }
	 
		if(!el) return;
	 
		var z = Anchor.scroll;
		z.el = el;
		z.p = this._getPos(el);
		z.s = this._getScroll();
		z.clear = function(){window.clearInterval(z.timer);z.timer=null};
		z.t=(new Date).getTime();
	 
		z.step = function(){
			var t = (new Date).getTime();
			var p = (t - z.t) / duration;
			if (t >= duration + z.t) {
				z.clear();
				window.setTimeout(function(){z.scroll(z.p.y, z.p.x)},13);
			} else {
				st = ((-Math.cos(p*Math.PI)/2) + 0.5) * (z.p.y-z.s.t) + z.s.t;
				sl = ((-Math.cos(p*Math.PI)/2) + 0.5) * (z.p.x-z.s.l) + z.s.l;
				z.scroll(st, sl);
			}
		};
		z.scroll = function (t, l){window.scrollTo(l, t)};
		z.timer = window.setInterval(function(){z.step();},13);
	}
};
 /* utils/md5.js */
/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

/*
 * Perform a simple self-test to see if the VM is working
 */
function md5_vm_test()
{
  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length
 */
function core_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;

    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);

}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
 * Calculate the HMAC-MD5, of a key and some data
 */
function core_hmac_md5(key, data)
{
  var bkey = str2binl(key);
  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  return str;
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}
/* utils/buffered_loader.js */
/*depend on class Ajax*/
function BufferedLoader(url,callback)
{
	this._url=url;
	this._callback=callback;
}

BufferedLoader.prototype = {
	_msg:false,
	_exist:false,
	_resp:null,
	start_msg:function()
	{
		this._msg = true;
	},
	stop_msg:function()
	{
		this._msg = false;
	},
	msg:function(str)
	{
		if(this._msg)
			alert(str)
	},
	load:function()
	{
		if(!this._url)return;
		if(this._exist&&this._resp)
		{
			if(this._callback)
				this._callback(this._resp);
			else
				this.msg("No Callback is Assigned.!");
			return;
		}

		var url = this._url;
		url += (this._url.indexOf("?")>=0?"&":"?")+"refresh_time="+new Date().getTime();
		this.msg("URL:"+url);
		var this_obj = this;
		new Ajax.Request(url, 
		{
			response: "Object",
			onSuccess: Delegate.create(this, function(evt){
				this_obj.msg("we did it!");
				if(evt&&evt.response)
				{
					this_obj._exist = true;
					this_obj._resp = evt.response;
					this_obj.msg("before calling it(the callback)!");
					this_obj._callback(evt.response);
				}
			}),
			on404: function(evt){
				this_obj.msg("404 Err:["+this_obj._url+"]");
			}
		});
	},
	reload:function()
	{
		this.clear();
		this.load();
	},
	setCallback:function(callback)
	{
		this._callback = callback;
	},
	setURL:function(sURL)
	{
		this._url = sURL;
	},
	clear:function()
	{
		this._exist = false;
		this._resp = null;
	}
};
/* utils/object_info.js */
/**
 * @class ObjectInfo
 * @brief 完成页面数据的"加载"/"验证"/"保存"等功能
 * ObjectInfo.Init()		//初始化
 * ObjectInfo.Load()		//触发加载
 * ObjectInfo.OnLoad()		//成功加载时调用
 * ObjectInfo.Validate()	//验证提交数据合法化
 * ObjectInfo.Serialize()	//序列化为POST数据
 * ObjectInfo.Save()		//提交(POST方式)
 * {
 *	  //1.this.Validate()
 *	  //2.this.Serialize()
 *	  //3.POST the data...
 * }
 */
function ObjectInfo(){}
ObjectInfo.prototype={
	//属性
	//-----------------------------------------------------------------
	_title:"",
	_loader:null,
	_properties:[],
	_load_url:"",
	_save_url:"",
	_init_done:false,
	_default_failed_msg:"",
	_default_succeeded_msg:"",
	_pdm: null,
	_btn_save_id: null,
	_allow_multiple_exception:false,
	_exceptions:[],
	
	//私有方法
	//-----------------------------------------------------------------
	/**
	 * @brief 单步初始化
	 */
	_First:function()
	{
		if(this._init_done)return;
		this._init_done = true;
		if(!this._pdm)this._pdm = new PropertyDealerManager();
		this.Init();
	},
	/**
	 * @brief 添加待处理的Property
	 */
	_AppendProperty:function(sName, sCtrl_id, sCn_name, sParam_name, bIs_nullable, exValid)
	{
		this._properties.push({
			name:sName, 
			ctrl_id:sCtrl_id, 
			cn_name:sCn_name, 
			param_name:((!sParam_name||''==sParam_name)?sName:sParam_name),
			is_nullable:bIs_nullable,
			ex_valid:(exValid)?exValid:null
			});
	},
	/**
	 * @brief 连接URL参数
	 */
	_JoinParam:function(param_name,param_value)
	{
		return "&"+param_name+"="+encodeURIComponent(param_value);
	},
	/**
	 * @brief 默认的数据加载触发方式
	 * 【一定要先调用this._First(),否则无法初始化】
	 */
	_Load:function()
	{
		if(!this._loader)
			this._loader = new BufferedLoader(this._load_url, Delegate.create(this,this.OnLoad));
		if(this._load_url&&this.OnDoingMsg) this.OnDoingMsg("正在加载,请稍后...");
		this._loader.load();
	},
	/**
	 * @brief 默认检验合法性(针对this._properties)
	 */
	_Validate:function()
	{
		for(var i=0;i<this._properties.length;i++)
		{
			try
			{
				this._pdm.Validate(this._properties[i]);
			}catch(ex)
			{
				if(this._allow_multiple_exception)
					this._exceptions.push({ctrl_id:this._properties[i].ctrl_id, msg:ex});
				else throw(ex);
			}
		}
	},
	/**
	 * @brief 默认序列化(针对this._properties)
	 */
	_Serialize:function()
	{
		var str = "";
		for(var i=0;i<this._properties.length;i++)
			str += this._pdm.Serialize(this._properties[i]);
		return str;
	},
	
	
	//公开方法(除Save()外，均可改写)
	//-----------------------------------------------------------------
	/**
	 * @brief 初始化函数
	 * @remark 具体使用时,可改写
	 */
	Init:function(){},
	/**
	 * @brief 触发数据加载
	 * @remark 具体使用时,可改写
	 * 【一定要先调用this._First(),否则无法初始化】
	 */
	Load:function()
	{
		this._First();
		this._Load();
	},
	Reload:function()
	{
		this._loader.clear();
		this._Load();
	},
	/**
	 * @brief 成功加载后,调用
	 * @remark 具体使用时,可改写
	 */
	OnLoad:function(rr)
	{
		alert("Need Implementation For Loading");
	},
	/**
	 * @brief 获得Loader的拷贝
	 * @remark 具体使用时,可改写
	 */
	CopyLoader:function()
	{
		return this._loader;
	},
	/**
	 * @brief 序列化数据前，检验指定数据的合法性
	 * @remark 具体使用时,可改写
	 */
	Validate:function()
	{
		this._Validate();
	},
	/**
	 * @brief 保存前，把指定的属性序列化为POST数据
	 * @remark 具体使用时,可改写
	 */
	Serialize:function()
	{
		return this._Serialize();
	},
	/**
	 * @brief 保存成功后调用显示
	 * @remark 具体使用时,可改写
	 */
	OnSucceededMsg:function(msg)
	{
		if(""==this._default_succeeded_msg)
			alert(msg);
		else
			alert("OK::"+this._default_succeeded_msg);
	},
	/**
	 * @brief 保存失败后调用显示
	 * @remark 具体使用时,可改写
	 */
	OnFailedMsg:function(msg)
	{
		if(""==this._default_failed_msg)
			alert(msg);
		else
			alert("FAILED::"+this._default_failed_msg);
	},
	OnFailedMultiMsg:function(exceptions)
	{
		if(exceptions.length>0)
			alert("出现"+exceptions.length+"处异常.");
	},
	/**
	 * @brief 正在处理时调用显示
	 * @remark 具体使用时,可改写
	 */
	OnDoingMsg:function(msg)
	{
		//nothing
	},
	Clear:function()
	{
		for(var i=0;i<this._properties.length;i++)
			this._pdm.Clear(this._properties[i]);
	},
	/**
	 * @brief 保存
	 */
	Save:function(sMETHOD)
	{
		try
		{


			if(sMETHOD)
			{
				sMETHOD = sMETHOD.toUpperCase();
				if("GET"!=sMETHOD&&"POST"!=sMETHOD)sMETHOD = "GET";
			}
			else
				sMETHOD = "GET";
				
			this._exceptions = [];
			
			this.Validate();
			
			if(this._exceptions.length>0)
			{//如果允许，并且出现多个exception
				this.OnFailedMultiMsg(this._exceptions);
				return;
			}
			
			var str_param = this.Serialize();
			if(!str_param||""==str_param)return;
			if(0==str_param.indexOf("&"))str_param = "1=1"+str_param;
			str_param += this._JoinParam("cachetime",new Date().getTime());
			
			if(this.OnDoingMsg) this.OnDoingMsg("正在提交,请稍后...");
			
			if(this._debug)
			{
				alert(this._save_url+"?"+str_param);return;
			}
			

			if(this._btn_save_id&&$(this._btn_save_id))
				$(this._btn_save_id).disabled=true;


			new Ajax.Request(this._save_url, {
				method: sMETHOD,
				parameters: str_param,
				response: "Object",
				onSuccess: Delegate.create(this,function(evt){
					try
					{
						if(this._btn_save_id&&$(this._btn_save_id))
							$(this._btn_save_id).disabled=false;
						var rr = evt.response;
						var msg;
						if(rr.str)msg = rr.str;
						else if(rr.msg)msg = rr.msg;
						else if(rr.errmsg)msg = rr.errmsg;
						else msg = "_保存失败_";
						if(rr.result=="0")
							if(""==this._default_succeeded_msg)
								this.OnSucceededMsg(msg);
							else
								this.OnSucceededMsg(this._default_succeeded_msg);
						else
							throw msg;
					}catch(ex)
					{
						if(""==this._default_failed_msg)
							this.OnFailedMsg(ex);
						else
							this.OnFailedMsg(this._default_failed_msg);
					}
				}),
				onException: Delegate.create(this,function(evt){
//					this.OnFailedMsg("Err:"+evt.exception.message);
//					throw(evt.exception);
					this.OnFailedMsg("系统正处于繁忙状态，请稍后再试。");
				})/**/
			});
		}
		catch(ex)
		{
			this.OnFailedMsg(ex);
		}
	}
};

function ListForm()
{
	/*
	//ListForm(sRpt_tag,sForm_name,sTitle)
	this._static_key=0;
	this._rpt=null;
	this._datas=[];
	this._rpt_tag=sRpt_tag;
	this._form_name=sForm_name;
	this._title=sTitle;*/
};
ListForm.prototype = new ObjectInfo();
ListForm.prototype.Setup = function(eid,objList)
{
	this._datas = objList;
	this._rpt = RepeaterManager.getInstance(eid);
	for(var i=0;i<this._datas.length;i++)
	{
		this._datas[i].key = this._static_key++;
	}
	this.Refresh();
};
ListForm.prototype.Serialize = function()
{
	var str = "1=1";
	var iActual = 0;
	var forms = $A($E(this._form_name));
	for ( var i=0; i<forms.length; i++ )
	{
		var obj = this.Get(forms[i]);
		if(!obj)continue;
		for(property in obj)
			str+=this._JoinParam(property+i,obj[property]);
		iActual++;
	}
	if(0==iActual)return "";
	str+=this._JoinParam("n",iActual);
	return str;
};
ListForm.prototype.Refresh = function()
{
	this._rpt.insertArray(this._rpt_tag,this._datas);
	this._rpt.run();

	var forms = $A($E(this._form_name));
	for ( var i=0; i<forms.length; i++ )
		this.Set(forms[i],this._datas[i]);
};
ListForm.prototype.New = function()
{
	if(!this._rpt)
	{
		alert("rpt尚未初始化");
		return;
	}
	if(this._datas.length>=5)
	{
		alert("您最多能添加5个"+this._title);
		return;
	}
	//清空，保存页面数据
	this._datas.splice(0,this._datas.length);
	var forms = $A($E(this._form_name));
	for ( var i=0; i<forms.length; i++ )
	{
		var obj = this.Get(forms[i]);
		if(!obj)continue;
		this._datas.push(obj);
	}
	var new_obj = this.Get();
	this._datas.push(new_obj);
	this.Refresh();
};
ListForm.prototype.Del = function(oTrigger)
{
	if(!oTrigger)return;
	var form_node = oTrigger.parentNode.parentNode;
	for(var i=0;i<this._datas.length;i++)
	{
		if(form_node["key"].value==this._datas[i].key)
		{
			this._datas.splice(i,1);
			break;
		}
	}
	form_node.parentNode.removeChild(form_node);
};
ListForm.prototype.Get = function(oForm){};
ListForm.prototype.Set = function(oForm,obj){};


/*--------------------------------------------------------*/
function PropertyDealer(){}
PropertyDealer.prototype = {
	_action_name:"填写",
	_JoinParam:function(param_name,param_value)
	{
		return "&"+param_name+"="+encodeURIComponent(param_value);
	},
	_ErrMsg:function(p,prefix)
	{
		return (prefix?prefix:"请")+this._action_name+":"+p.cn_name;
	}
}
function PropertyDealer_text(){}
PropertyDealer_text.prototype = new PropertyDealer();
PropertyDealer_text.prototype._action_name = "填写";
PropertyDealer_text.prototype.Validate = function(p)
{
	var sValue = $(p.ctrl_id).value.trim();
	if(!p.is_nullable&&""==sValue) throw this._ErrMsg(p);
	if(""!=sValue&&p.ex_valid&&!p.ex_valid.exec(sValue)) throw this._ErrMsg(p,"请正确");
};
PropertyDealer_text.prototype.Serialize = function(p)
{
	return this._JoinParam(p.param_name, $(p.ctrl_id).value.trim());
};
PropertyDealer_text.prototype.Clear = function(p)
{
	return $(p.ctrl_id).value = "";
};

function PropertyDealer_password(){}
PropertyDealer_password.prototype = new PropertyDealer();
PropertyDealer_password.prototype._action_name = "填写";
PropertyDealer_password.prototype.Validate = function(p)
{
	var sValue = $(p.ctrl_id).value;
	if(!p.is_nullable&&""==sValue) throw this._ErrMsg(p);
	if(""!=sValue&&p.ex_valid&&!p.ex_valid.exec(sValue)) throw this._ErrMsg(p,"请正确");
};
PropertyDealer_password.prototype.Serialize = function(p)
{
	return this._JoinParam(p.param_name, $(p.ctrl_id).value);
};
PropertyDealer_password.prototype.Clear = function(p)
{
	return $(p.ctrl_id).value = "";
};


function PropertyDealer_select_one(){}
PropertyDealer_select_one.prototype = new PropertyDealer();
PropertyDealer_select_one.prototype._action_name = "选择";
PropertyDealer_select_one.prototype.Validate = function(p)
{
	var selected = ejs.selectone.get($(p.ctrl_id))
	if(!p.is_nullable&&""==selected.value.trim()) throw this._ErrMsg(p);
};
PropertyDealer_select_one.prototype.Serialize = function(p)
{
	var selected = ejs.selectone.get($(p.ctrl_id));
	if(selected)
		return this._JoinParam(p.param_name, selected.text) + this._JoinParam(p.param_name+"_value", selected.value);
	return "";
};
PropertyDealer_select_one.prototype.Clear = function(p)
{
	return ejs.selectone.set($(p.ctrl_id),"");
};

function PropertyDealer_radio(){}
PropertyDealer_radio.prototype = new PropertyDealer();
PropertyDealer_radio.prototype._action_name = "选择",
PropertyDealer_radio.prototype.Validate = function(p)
{
	var selected_value = ejs.radio.get($(p.ctrl_id))
	if( (!p.is_nullable)&&(!selected_value||""==selected_value.trim()) )
		throw this._ErrMsg(p);
};
PropertyDealer_radio.prototype.Serialize = function(p)
{
	var selected_value = ejs.radio.get($(p.ctrl_id));
	if(selected_value)
		return this._JoinParam(p.param_name, selected_value);
	return "";
};
PropertyDealer_radio.prototype.Clear = function(p)
{
	return ejs.radio.set($(p.ctrl_id),"");
};


function PropertyDealer_checkbox(){}
PropertyDealer_checkbox.prototype = new PropertyDealer();
PropertyDealer_checkbox.prototype._action_name = "勾选",
PropertyDealer_checkbox.prototype.Validate = function(p)
{
	var isCheck = ejs.checkbox.isCheck($(p.ctrl_id))
	if( (!p.is_nullable)&&(!isCheck) )
		throw this._ErrMsg(p);
};
PropertyDealer_checkbox.prototype.Serialize = function(p)
{
	var isCheck = ejs.checkbox.isCheck($(p.ctrl_id))
	if(isCheck)
		return this._JoinParam(p.param_name, 'true');
	return "";
};
PropertyDealer_checkbox.prototype.Clear = function(p)
{
	return ejs.checkbox.setUnCheck($(p.ctrl_id));
};


function PropertyDealerManager(){};
PropertyDealerManager.prototype = {
	Validate:function(p)
	{
		var eCtrl = $(p.ctrl_id);
		var sType = this._GetTypeOfCtrl(eCtrl);
		var oDealer = null;
		if(eCtrl&&""!=sType.trim())
		{
			oDealer = this._dealers[sType];
			if(!oDealer)throw("PropertyDealerManager不支持此类型的Validate:"+sType);
			oDealer.Validate(p);
		}
	},
	Serialize:function(p)
	{
		var eCtrl = $(p.ctrl_id);
		var sType = this._GetTypeOfCtrl(eCtrl);
		if(eCtrl&&""!=sType.trim())
		{
			oDealer = this._dealers[sType];
			if(!oDealer)throw("PropertyDealerManager不支持此类型的Serialize:"+sType);
			return oDealer.Serialize(p);
		}
		else return "";
	},
	Clear:function(p)
	{
		var eCtrl = $(p.ctrl_id);
		var sType = this._GetTypeOfCtrl(eCtrl);
		if(eCtrl&&""!=sType.trim())
		{
			oDealer = this._dealers[sType];
			if(!oDealer)throw("PropertyDealerManager不支持此类型的Clear:"+sType);
			return oDealer.Clear(p);
		}
	},
	/**
	 * @brief 获得控件的HTML-INPUT类型
	 */
	_GetTypeOfCtrl:function(eCtrl)
	{
		if(!eCtrl||!eCtrl.type)return "";
		else return eCtrl.type.toLowerCase();
	},
	_dealers:{
		"text":new PropertyDealer_text(),
		"textarea":new PropertyDealer_text(),
		"password":new PropertyDealer_password(),
		"select-one":new PropertyDealer_select_one(),
		"radio":new PropertyDealer_radio(),
		"checkbox":new PropertyDealer_checkbox()
	}
};
/* utils/module_runner.js */
var ModuleRunner = function (){
	this._Module = [];
};

ModuleRunner.getInstance = function(id)
{
	if ( !this._pool )
			this._pool={};
	if ( !this._pool[id] )
	{
		this._pool[id]=new ModuleRunner;
	}
		
	return this._pool[id];
}

ModuleRunner.prototype = {
	addModule : function(m) {
		for(var i=0; i<this._Module.length; i++) {
			if( m.eid==this._Module[i].eid) {
				this._Module.splice(i, 1);
				break;
			}
		}
		this._Module.push(m);
	},

	runAll : function(){
		for(var i=0;i<this._Module.length;i++)
			if(this._Module[i].url!="")
				this._loadXml(i);
	},

	runOne : function(eid){
		for(var i=0;i<this._Module.length;i++) {
			if(this._Module[i].eid==eid) {
				this._loadXml(i);
				return;
			}
		}
	},

	clear : function () {
		this._Module = [];
	},

	_loadXml : function(i){
		var theRunner=this;
		var theModule=this._Module[i];
		
		var url=theModule.url;
		new Ajax.Request(url, {
			response: "Object",
			onSuccess: function(evt){
				var rr = evt.response;

				if (theModule.successCallback)
					theModule.successCallback(i,rr);
				
			},
			onException: function(evt){
				if(theModule.onException)
					theModule.onException(evt);
			}
		});
	}
};
