/*  SWAF JavaScript framework, version 1.9a build 080131
*  (c) 2007 Nam,Ki-Hoon (reizes@nate.com)
*
*  For details, see the Swaf web site: http://swaf.sourceforge.net/
*
/*--------------------------------------------------------------------------*/


var swaf={
	NAMESPACE:'swaf',
	version:'2.0',
	build:'080131',
	ScriptRegExp1:/<script[^>]*>([\u0001-\uFFFF]*?)<\/script>/gmi,
	ScriptRegExp2:/<script[^>]*>([\u0001-\uFFFF]*?)<\/script>/mi,
	define:{
		ELEMENT_NODE:1,
		ATTRIBUTE_NODE:2,
		TEXT_NODE:3,
		CDATA_SECTION:4,
		ENTITY_REFERENCE:5,
		ENTITY_NODE:6,
		COMMENT_NODE:8
	},
	ext:{},
	dummy:{},
	_$search:function(obj,regexp) {
		var id,node,matches;
		var ret=[];
		var arr=(obj||document.body).getElementsByTagName('*');
		
		for(var i=0;i<arr.length;i++) {
			if (typeof arr[i].id=='undefined' || !arr[i].id) continue;
			matches=regexp.exec(arr[i].id);
			if (matches&&matches.length>0) {
				ret.push(arr[i]);
			}
		}
		arr=null;
		return ret;
	},
	_$$:function(id) {
	  var elements = [];
		var tmp=id.split('~');
		var findi=tmp[0].indexOf('##');
		if (findi==-1) return document.getElementById(tmp[0]);
		var stopAtError=tmp.length==1?true:false;
		var end=(tmp.length>1)?tmp[1]:-1;
		var pre=tmp[0].substring(0,findi);
		var post=tmp[0].substr(findi+2);

		for(var i=1;true;i++) {
			var num=(i<10?'0':'')+i;
			var name=pre+num+post;
			var el=document.getElementById(name);
			if (el) {
				elements.push(el);
				el=null;
			}
			else {
				if (stopAtError==true) break;
			}
			if (end>0 && i==end) break;
		}
		return elements;
	},
	getElementsByClassName:function(obj,className) {
	  var children = obj.getElementsByTagName('*');
	  var regexp=new RegExp("(^|\\s)" + className + "(\\s|$)");
	  var elements=[];
	  for(var i=0;i<children.length;i++) {
	  	var child=children[i];
	  	if (child.className.match(regexp)) elements.push(child);
	  }
	  children=null;
	  regexp=null;
		return elements;
	},
	getElementFromForm:function(location) {
		var tmp=location.split('.');
		return (tmp.length>1)?document.forms[tmp[0]][tmp[1]]:document.forms[location];
	},
	getElementsFromParent:function(element) {
		var win=window;
		var tmp=$(element);
		var ret=[];
		if (tmp) {
			if (typeof tmp.length=='number') ret=$A(tmp);
			else ret.push(tmp);
		}
		for(;win.parent;win=win.parent) {
			try {
				if (!win.parent.document || !win.parent.document.body || typeof win.parent.swaf=='undefined') break;
				if (win.parent.document.body.tagName!='BODY') break;
				if (window.top==win) break;
			} catch(e) { break;}
			tmp=win.parent.$(element);
			if (typeof tmp.length=='number') ret=ret.concat($A(tmp));
			else ret.push(tmp);
		}
		return ret;
	},
	_selector_sub:{
		35:function(element,root) { // # - tag
			element=(root||document).getElementsByTagName(element);
			if (element.length==1) element=element[0];
			else if (element.length==0) element=undefined;
			return element;
		},
		64 : function(element,root) {// @ - name
			element=document.getElementsByName(element);
			if (element.length==1) element=element[0];
			else if (element.length==0) element=undefined;
			return element;
		},
		46 : function(element,root) { // . - class
			element=swaf.getElementsByClassName((root||document),element);
			if (element.length==1) element=element[0];
			else if (element.length==0) element=undefined;
			return element;
		},
		37 : function(element,root) { // % - form
			return swaf.getElementFromForm(element);
		},
		42 : function(element,root) { // * - node index
			var node=(root||document).firstChild;
			if (node) node=node.nextSibling;
			else return null;
			for(var i=0;node&&i<element;node=node.nextSibling) {
				if (node.nodeType==swaf.define.ELEMENT_NODE) i++;
			}
			return node;
		},
		126 : function(element,root) { // ~ - ##
			return swaf._$$(element);
		},
		43 : function(element,root) { // + - find child frame
			return swaf.gs.$(element);
		},
		94 : function(element,root) { // ^ - find parent frame
			return swaf.getElementsFromParent(element);
		}
	},
	_$ : function(element,root) {
	  if (typeof element == 'string') {
	  	var selectorfn=swaf._selector_sub[element.charCodeAt(0)];
	  	if (selectorfn) element=selectorfn(element.substr(1),root);
	  	else element=document.getElementById(element);
	  }
	  else if (element instanceof RegExp) return swaf._$search(root,element);	// regexp
	  return element; // element
	},
	_set_attribute:function(el,name,value) {
		if (typeof el!='string' && typeof el.length=='number') {
			for (var i=0;i<el.length;i++) {
				if (el[i]) el[i].setAttribute(name,value);
			}
		} else if (el) el.setAttribute(name,value);
	},
	onLoadDocument:function() {
		if (typeof window.main == "function") window.main.call(window);
	},
	onUnloadDocument:function() {
		if (typeof window.exit== "function") window.exit.call(window);
	}
};

swaf.$=function(element,root) {
  if (typeof element !='string' && typeof element.length=='number' && element[0]) {
  	var ret=[];
    for (var i = 0, elements = [], length = element.length; i < length; i++) { ret.push[swaf._$(element[i],root)];}
    return ret;
  }
  return swaf._$(element,root);
};

if (typeof $=='undefined') var $=swaf.$;

swaf.$A=function(obj) {
	var ret=[];
	if (obj.toArray) return obj.toArray();
	if (typeof obj.length=='number') {
		for(var i=0;i<obj.length;i++) { ret[i]=obj[i]; }
	}
	return ret;
};
if (typeof $A=='undefined') var $A=swaf.$A;

swaf.extend=function(destination, source, override) {
  for (var property in source) { 
    if (override==false && typeof destination[property] !='undefined') continue;
    destination[property] = source[property]; 
  }
  return destination;
};
if (typeof $extend=='undefined') var $extend=swaf.extend;

swaf.include=function(url) {
	var head=document.getElementsByTagName("head");
	if (head) {
		var linkel=document.createElement('script');
		linkel.setAttribute('src', url);
		linkel.setAttribute('type', 'text/javascript');
		head[0].appendChild(linkel);
	}
	head=null;
};
if (typeof $include=='undefined') var $include=swaf.include;

swaf.ext.Array={
	find : function(item) {
		for(var i=0;i<this.length;i++) {if (this[i]==item) return i;}
		return -1;
	},
	copy:function() {
		var ret=new Array(this.length);
		for(i=0;i<this.length;i++) {
			var obj=this[i];
			if (obj instanceof Array) ret[i]=this[i].copy();
			else ret[i]=obj;
		}
		return ret;
	},
	// arg : ...
	each : function(fn,optional_arg) {
		var arg=[null,0];
		if (optional_arg) {
			var tmparg=swaf.$A(arguments);
			tmparg.shift();
			arg=arg.join(tmparg);
		}
		for(var i=0;i<this.length;i++) {
			arg[0]=this[i];
			arg[1]=i;
			fn.apply(fn,arg);
		}
		return this;
	},
	remove:function(value) {
		var ret=[];
		for(var i=0;i<this.length;i++) { if (this[i]==value) {ret.push(this[i]);delete this[i]; }}
		return ret;
	},
	removeCompact:function(value) {
		var ret=[];
		for(var i=0;i<this.length;i++) { if (this[i]==value) ret.push(this.splice(i,1)); }
		return ret;
	},
	last:function() {
		return this[this.length-1];
	},
	tryFn:function() {
		for(var i=0;i<this.length;i++) {
			if (typeof this[i]!='function') continue;
			try { return this[i].apply(window,arguments); }
			catch(e) { continue; }
		}
		return null;
	}
};

swaf.ext.String={
	trim : function() {return this.replace(/^\s+|\s+$/g,''); 	},
	ltrim : function() {return this.replace(/^\s*/g,''); 	},
	rtrim : function() {return this.replace(/\s*$/g, ''); 	},
	stripTags : function() { 	 return this.replace(/<\/?[^>]+>/gi, ''); 	},
	stripScripts : function() { 	  return this.replace(swaf.ScriptRegExp1, '');	},
	extractScripts : function() {
		var ret=[];
		var tmp=this.match(swaf.ScriptRegExp1) || [];
		for(var i=0;i<tmp.length;i++) {
			ret.push((tmp[i].match(swaf.ScriptRegExp2) || ['', ''])[1]);
		}
		tmp=null;
		return ret;
	},
  evalScripts: function() {
  	var scripts=this.extractScripts();
  	for(var i=0;i<scripts.length;i++) eval(scrips[i]);
  },
	escapeHTML : function() {	  return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\"/g,'&quot;');	},
	unescapeHTML : function() {		return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&quot;/g,'"');	},
  toArray: function() {
    return this.split('');
  },

	toObject : function() {
		var names=this.split('.');
		var obj=window;
		for(i=0;i<names.length;i++) { obj=obj[names[i]]; }
		names=null;
		return obj;
	},
	_set_param:function(name,value) {
		var regexp=new RegExp('\\{\\$'+name+'\\}','gm');
		return this.replace(regexp, value);
	},
	_set_param_obj:function(object) {
		var str=this;
		for(var property in object) {
			str=str._set_param(property,object[property]);
		}
		return str;
	},
	set:function(name,value) {
		if (typeof name=='object') return this._set_param_obj(name);
		return this._set_param(name,value);
	},
	byteTruncate:function(maxlen,encoding) {
		encoding=encoding?encoding.toLocaleLowerCase():'utf-8';
		var mbl=(encoding=='utf-8')?3:2;
		var len=0;
		var strlen=this.length;
		var ret='';
	  for(var i=0;i<strlen;i++) {
	      var c=this.charAt(i);
	      if (escape(c).length>4) len+=mbl;
	      else len++;
	      if (len<=maxlen) ret+=c;
	      else break;
	  }
	  return ret;
	},
	byteLength:function(encoding) {
		encoding=encoding?encoding.toLocaleLowerCase():'utf-8';
		var mbl=(encoding=='utf-8')?3:2;
		var len=0;
		var strlen=this.length;
	  for(var i=0;i<strlen;i++) {
	      var c=this.charAt(i);
	      if (escape(c).length>4) len+=mbl;
	      else len++;
	  }
	  return len;
	}
};

swaf.ext.Number={
	leadingZero:function(len) {
		var tmp='000000000000'+this;
		return tmp.substr(tmp.length-len,len);
	}
};

// function extension
swaf.ext.Function={
	bind : function() {
	  var __method = this;
	  var args = swaf.$A(arguments);
	  var owner = args.shift();
	  return function() {
	    return __method.apply(owner, args.concat(swaf.$A(arguments)));
	  }
	},
	bindAsEventListener : function() {
	  var __method = this;
	  var args = swaf.$A(arguments);
	  var owner = args.shift();
	  var ret=function(event) {
	  	var evt=event || window.event;
	  	var src=arguments.callee.eventSrc;
	  	if (!evt.target) evt.target=src;
	    return __method.apply(owner, [new swaf.eventObject(evt),src,evt.type].concat(args));
	  };
	  ret.__swaf__bindedAsListener=true;
	  return ret;
	},
	getProxy:function(owner,before,after,exception) {
	    var fn=this;
		if (before&&after&&exception) {
			return function() {
				try {
					before.apply(owner,arguments);
					fn.apply(owner,arguments);
					after.apply(owner,arguments);
				}
				catch(e) {
					exception.call(owner,error,fn,arguments);
				}
			};
		} else if (!before&&after&&exception) {
			return function() {
				try {
					fn.apply(owner,arguments);
					after.apply(owner,arguments);
				}
				catch(e) {
					exception.call(owner,error,fn,arguments);
				}
			};
		} else if (before&&!after&&exception) {
			return function() {
				try {
					before.apply(owner,arguments);
					fn.apply(owner,arguments);
				}
				catch(e) {
					exception.call(owner,error,fn,arguments);
				}
			};
		} else if (before&&after&&!exception) {
			return function() {
				before.apply(owner,arguments);
				fn.apply(owner,arguments);
				after.apply(owner,arguments);
			};
		} else if (!before&&!after&&exception) {
			return function() {
				try {
					fn.apply(owner,arguments);
				}
				catch(e) {
					exception.call(owner,error,fn,arguments);
				}
			};
		} else if (!before&&after&&!exception) {
			return function() {
				fn.apply(owner,arguments);
				after.apply(owner,arguments);
			};
		} else if (before&&!after&&!exception) {
			return function() {
				before.apply(owner,arguments);
				fn.apply(owner,arguments);
			};
		} else {
			return function() {
				fn.apply(owner,arguments);
			};
		}
	}
};

// etc
swaf.ext.Object={
    toQueryString : function(obj) {
      var parts = [];
    	for(var key in obj) {
    		var value=obj[key];
    		parts.push(encodeURIComponent(key)+'='+(value?encodeURIComponent(value):''));
    	}
      return parts.join('&');
    }
};
if (typeof Object.toQueryString == 'undefined') Object.toQueryString=swaf.ext.Object.toQueryString;

swaf.extend(Array.prototype,swaf.ext.Array,false);
swaf.extend(String.prototype, swaf.ext.String,false);
swaf.extend(Number.prototype, swaf.ext.Number,false);
swaf.extend(Function.prototype, swaf.ext.Function,false);

swaf.namespace=function(name,define) {
	var names=name.split('.');
	var obj=window;
	var last=names.length-1;
	var ns='';
	for(i=0;i<last;i++) {
	    if (ns.length>0) ns+='.';
	    ns+=names[i];
		if (typeof obj[names[i]]=='undefined') obj[names[i]]={NAMESPACE:ns};
		obj=obj[names[i]];
	}
	if (!obj[names[last]]) {
		if (define) {
			obj[names[last]]=define;
			(obj[names[last]]).NAMESPACE=name;
		}
		else obj[names[last]]={NAMESPACE:name};
	}
	obj=null;
};

if (typeof $namespace == 'undefined') var $namespace=swaf.namespace;

swaf.attr=function(el,name,value) {
	if (typeof el=='undefined') return null;
	if (value) { swaf._set_attribute(el,name,value); return null;}
	if (typeof el!='string' && typeof el.length=='number') {
		var ret=[];
		for (var i=0;i<el.length;i++) {
			ret.push((el[i])?el[i].getAttribute(name):null);
		}
		return ret;
	}
	return el.getAttribute(name);
};

if (typeof $attr == 'undefined') var $attr=swaf.attr;

swaf.$a=function(el,name,value) {
	return swaf.attr(el,'swaf:'+name,value);
};

if (typeof $a == 'undefined') var $a=swaf.$a;

// browser information
swaf.browser={};
swaf.browser.userAgent=navigator.userAgent.toLowerCase();
swaf.browser.isOpera=(swaf.browser.userAgent.indexOf('opera') != -1);
swaf.browser.isSafari=(swaf.browser.userAgent.indexOf('safari') != -1);
swaf.browser.isIE=(swaf.browser.userAgent.indexOf('msie') != -1 && !swaf.browser.isOpera);
swaf.browser.isFF=(swaf.browser.userAgent.indexOf('firefox') != -1);
swaf.browser._getVersion_ie=function(str) {
	var bit=str.split(';');
	return (bit[1].split(' '))[2];
};
swaf.browser._getVersion_nonie=function(str) {
	var bit=str.split(' ');
	return bit[0];
};
swaf.browser._getVersion=swaf.browser.isIE?swaf.browser._getVersion_ie:swaf.browser._getVersion_nonie;

swaf.browser._getClientRect_non_ie=function() {
	return {width:self.innerWidth,height:self.innerHeight};
};
swaf.browser._getClientRect_ie6_strict=function() {
	return {width:document.documentElement.clientWidth,height:document.documentElement.clientHeight};
};
swaf.browser._getClientRect_other_ie=function() {
	return {width:document.body.clientWidth,height:document.body.clientHeight};
};
swaf.browser._getScrollPosition_non_ie=function() {
	return {x:self.pageXOffset,y:self.pageYOffset};
};
swaf.browser._getScrollPosition_ie6_strict=function() {
	return {x:document.documentElement.scrollLeft,y:document.documentElement.scrollTop};
};
swaf.browser._getScrollPosition_other_ie=function() {
	return {x:document.body.scrollLeft,y:document.body.scrollTop};
};
swaf.browser._getWindowPosition_1=function() {
	return {x:window.screenLeft,y:window.screenTop};
};
swaf.browser._getWindowPosition_2=function() {
	return {x:window.screenX,y:window.screenY};
};

swaf.browser.getVersion=function() {
	var ver=swaf.browser._getVersion(navigator.appVersion);
	return parseFloat(ver);
};
swaf.browser.getClientRect=function() {
    return self.innerHeight?swaf.browser._getClientRect_non_ie():((document.documentElement && document.documentElement.clientHeight)?swaf.browser._getClientRect_ie6_strict():swaf.browser._getClientRect_other_ie());
};
swaf.browser.getScrollPosition=function() {
    return self.pageYOffset?swaf.browser._getScrollPosition_non_ie():((document.documentElement && document.documentElement.scrollTop)?swaf.browser._getScrollPosition_ie6_strict():swaf.browser._getScrollPosition_other_ie());
};
swaf.browser.getWindowPosition=function() {
    return window.screenLeft?swaf.browser._getWindowPosition_1():((window.screenX)?swaf.browser._getWindowPosition_2():(function (){return {x:0,y:0};}));
};


// event
swaf._event={
  listenerCache:null,
  _addListenerSub1:function(element, name, listener, useCapture) {
    element.addEventListener(name, listener, useCapture);
  },
  _addListenerSub2:function(element, name, listener, useCapture) {
    element.attachEvent('on' + name, listener);
  },
  _addListenerSub:function(element, name, listener, useCapture) {
  	element['on' + name]=listener;
  },
  addListener:function(element, name, listener, useCapture) {
  	useCapture = useCapture || false;
    if (!this.listenerCache) this.listenerCache = [];
    var ret=this.listenerCache.length;
  	this.listenerCache.push([element, name, listener, useCapture]);
  	listener.eventSrc=element;
  	swaf._event._addListenerSub(element, name, listener, useCapture);
  	return ret;
  },
  _removeListenerSub1 : function(element, name, listener, useCapture) {
    element.removeEventListener(name, listener, useCapture);
  },
  _removeListenerSub2 : function(element, name, listener, useCapture) {
    try { 
      element.detachEvent('on' + name, listener); 
    } catch (e) {}
	},
  _removeListenerSub : function(element, name, listener, useCapture) {
  	listener.eventSrc=null;
  	delete element['on' + name];
  },
  removeListener : function(handle) {
  	if (handle instanceof Array) {
  		for (var i=0;i<handle.length;i++) {
		    swaf._event._removeListenerSub.apply(this,swaf._event.listenerCache[handle[i]]);
		    this.listenerCache[handle[i]]=null;
  		}
  		handle=null;
  	} else if (swaf._event.listenerCache) {
	    swaf._event._removeListenerSub.apply(this,swaf._event.listenerCache[handle]);
	    this.listenerCache[handle]=null;
	  }
  },
  resetListener:function() {
  	if (swaf._event.listenerCache) {
  		for (var i=0;i<swaf._event.listenerCache.length;i++) {
  			if (swaf._event.listenerCache[i]) {
  				swaf._event.removeListener(i);
  				swaf._event.listenerCache[i]=null;
  			}
  		}
  		swaf._event.listenerCache=null;
  	}
  }
};

if (document.addEventListener) swaf._event._addListenerSub=swaf._event._addListenerSub1;
else if (document.attachEvent) swaf._event._addListenerSub=swaf._event._addListenerSub2;
if (document.removeEventListener) swaf._event._removeListenerSub=swaf._event._removeListenerSub1;
else if (document.detachEvent) swaf._event._removeListenerSub=swaf._event._removeListenerSub2;

swaf.listener=function(element,evttype,listenerFn,owner) {
	if (!element) return null;
	var ret=null;
	if (typeof element.length=='number' && element[0]) {
		var retHandle=[];
		for(var i=0;i<element.length;i++) {
			var listener=owner?listenerFn.bindAsEventListener(owner):(listenerFn.__swaf__bindedAsListener==true?listenerFn:listenerFn.bindAsEventListener(window));
			retHandle.push(swaf._event.addListener(element[i],evttype,listener));
		}
		ret=retHandle;
	} else {
		var listener=owner?listenerFn.bindAsEventListener(owner):(listenerFn.__swaf__bindedAsListener==true?listenerFn:listenerFn.bindAsEventListener(window));
		ret=swaf._event.addListener(element,evttype,listener);
	}
	listener=null;
	return ret;
};

swaf.listener.remove=function(handle) {
	swaf._event.removeListener(handle);
};

swaf.message={
	listenerCache:null,
	addListener:function(object,name,listener) {
		if (!object._swaf_eventMap) {
			object._swaf_eventMap={};
			object._swaf_eventMapCount={};
		}
		if (!object._swaf_eventMap[name]) object._swaf_eventMap[name]=[];
		if (typeof object._swaf_eventMapCount[name]=="undefined") object._swaf_eventMapCount[name]=0;
		var listenerIndex=object._swaf_eventMap[name].length;
		object._swaf_eventMap[name].push(listener);
		object._swaf_eventMapCount[name]++;
		
		if (!this.listenerCache) this.listenerCache = [];
		var retHandle=this.listenerCache.length;
		this.listenerCache.push([object,name,listenerIndex,listener]);
		
		if (!object._swaf_eventTrigger) object._swaf_eventTrigger={};
		if (!object._swaf_eventTrigger[name]) {
			var func=(function(pseudo_evt,src,name) {
				var ret=true;
				var args=swaf.$A(arguments);
				var map=this._swaf_eventMap[name];
				for(var i=0;i<map.length;i++) {
					var item=map[i];
					if (item) {
						if (typeof item=='function'&& item.apply(this,args)==false) { ret=false; break; }
						else if (typeof item=='object' && swaf.message.fireTo.apply(swaf.message,[item].concat(args))==false) {ret=false; break;}
						item=null;
					}
				}
				return ret;
			});
			object._swaf_eventTrigger[name]=func;
			var bElement=(object.addEventListener || object.attachEvent)?true:false;
			if (bElement) {
				// Element object listener 
				if (!object._swaf_eventTriggerHandle) object._swaf_eventTriggerHandle={};
				var func=(function(evt,src,name) {
					var ret=true;
					var map=this._swaf_eventMap[name];
					var args=swaf.$A(arguments);
					for(var i=0;i<map.length;i++) {
						var item=map[i];
						if (item) {
							if (typeof item=='function'&& item.apply(this,args)==false) { ret=false; break; }
							else if (typeof item=='object' && swaf.message.fireTo.apply(swaf.message,[item].concat(args))==false) {ret=false; break;}
							item=null;
						}
					}
					return ret;
				}).bindAsEventListener(object);
				object._swaf_eventTriggerHandle[name]=swaf._event.addListener(object,name,func);
			}
		}
		return retHandle;
	},
	removeListenerSub:function(handle) {
		var data=this.listenerCache[handle];
		var obj=data[0];
		var name=data[1];
		var listenerIndex=data[2];
		if (obj._swaf_eventMap[name]) {
			obj._swaf_eventMap[name][listenerIndex]=null;
			obj._swaf_eventMapCount[name]--;
			if (obj._swaf_eventMapCount[name]==0) {
				obj._swaf_eventMap[name]=null;
				obj._swaf_eventTrigger[name]=null;
				if (obj.addEventListener || obj.attachEvent) {
					swaf._event.removeListener(obj._swaf_eventTriggerHandle[name]);
				}
			}
		}
		this.listenerCache[handle]=null;
		data=null;
	},
	removeListener:function(handle) {
  	if (handle instanceof Array) {
  		for (var i=0;i<handle.length;i++) {
		    swaf.message.removeListenerSub(handle[i]);
  		}
  		handle=null;
  	} else {
  		swaf.message.removeListenerSub(handle);
	  }
	},
	resetListener:function() {
  	if (swaf.message.listenerCache) {
  		for (var i=0;i<swaf.message.listenerCache.length;i++) {
  			if (swaf.message.listenerCache[i]) {
  				swaf.message.removeListener(i);
  				swaf.message.listenerCache[i]=null;
  			}
  		}
  		swaf.message.listenerCache=null;
  	}
	},
	fire:function(evt,src,name) {
		var args=swaf.$A(arguments);
		if (args[0]) {
			args[0].target=src;
			args[0].type=name;
		} else {
			args[0]={
				target:src,
				type:name
			}
		}
        if (src.addEventListener || src.attachEvent) { // if HTML Element
        	var inline=src['on'+name];
        	if (typeof inline=='function') inline.apply(src,args);
        }
	    
		if (src._swaf_eventTrigger && src._swaf_eventTrigger[name]) {
			return src._swaf_eventTrigger[name].apply(src,args);
		}
		return false;
	},
	fireTo:function(target,evt,src,name) {
		var args=swaf.$A(arguments);
		args.shift();
		if (!args[0]) {
			args[0]={
				target:src,
				type:name
			}
		}
	    if (target._swaf_eventTrigger && target._swaf_eventTrigger[name]) {
			return target._swaf_eventTrigger[name].apply(target,args);
		} else {
		    if (typeof target=='object') {
		        var fnName='on'+name.substr(0,1).toUpperCase()+name.substr(1);
		        if (typeof target[fnName]=='function') return target[fnName].apply(target,args);
		    }
	    }
		return false;
	}
};


swaf.event=function(src,map) {
	var ret=[];
	if (map instanceof Array) {
	    for(var i=0;i<map.length;i++) {
    		var tmp=swaf.event(src,map[i]);
    		if (tmp instanceof Array) ret=ret.concat(tmp);
    		else ret.push(tmp);
	    }
	    return ret;
	}
	if (map.isSwafClass==true && map._swaf_event_map_define) {
    	var cls=map;
    	map={};
    	for(var name in cls._swaf_event_map_define) {
    	    map[name]=cls;
    	}
	}
	for(var property in map) {
		var func=map[property];
		if (func instanceof Array) {
			for(var i=0;i<func.length;i++) ret.push(swaf.message.addListener(src,property,func[i]));
		} else {
			ret.push(swaf.message.addListener(src,property,func));
		}
		func=null;
	}
	map=null;
	return ret;
};

swaf.event.remove=function(handle) {
    swaf.message.removeListener(handle);
};

swaf.event.bypass=function(target,arg) {
	var args=swaf.$A(arg);
	args.unshift(target);
	swaf.message.fireTo.apply(target,args);
};

swaf.event.fire=function(target,name) {
	var args=swaf.$A(arguments);
	args.unshift(null);
	swaf.message.fire.apply(swaf.message,args);
};

/* Message Queue 2007.12.27 */
swaf.messageQueue={
		args : [],

		put : function(arrParam) {
		     this.args.push(arrParam);
		     window.setTimeout(this.sendMessage.bind(this),100);
		},
		sendMessage : function() {
		     arg=this.args.shift();
		     if (arg) swaf.event.fire.apply(window,arg);
		     if (this.args.length>0) window.setTimeout(this.sendMessage.bind(this),250);
		}
};

swaf.event.post=function(target,name) {
    swaf.messageQueue.put(swaf.$A(arguments));
};

swaf.listener.fire=function(el,type,evt) {
	if (el.fireEvent) el.fireEvent('on'+type,evt);	// IE
	else if (el.dispatchEvent) {		// FF, NS, Opera ...
		var e;
		// DOM3 Event
		switch(type) {
			case 'focus'	:
			case 'blur'		:
			case 'resize' :
			case 'scroll' :
				e=document.createEvent('UIEvents');
				e.initUIEvent(type,true,true,evt.view,evt.detail);
				break;
			case 'textInput' :
				e=document.createEvent('TextEvent');
				e.initTextEvent(type,true,true,evt.view,evt.detail);			// Լ ǰ developer.mozilla.org . Ф
				break;
			case 'click' :
			case 'mousedown' :
			case 'mouseup' :
			case 'mouseover' :
			case 'mousemove' :
			case 'mouseout' :
				e=document.createEvent('MouseEvents');
				e.initMouseEvent(type,true,true,evt.view,evt.detail,evt.screenX,evt.screenY,evt.clientX,evt.clientY,evt.ctrlKey,evt.altKey,evt.shiftKey,evt.metaKey,evt.button,evt.relatedTarget);
				break;
			case 'keydown' :
			case 'keyup' :
				e=document.createEvent('KeyboardEvent');
				e.initKeyboardEvent(type,true,true,evt.view,evt.detail);			// Լ ǰ developer.mozilla.org . Ф
				break;
			case 'load' :
			case 'unload' :
			case 'abort' :
			case 'error' :
			case 'select' :
			case 'change' :
			case 'submit' :
			case 'reset' :
				e=document.createEvent('Event');
				e.initEvent(type,true,true);
				break;
			
		}
		el.dispatchEvent(e);
	}
};

if (typeof $listener == 'undefined') var $listener=swaf.listener;
if (typeof $event == 'undefined') var $event=swaf.event;


/////////////////////////// singleton factory ////////////////////////////
swaf.factory={_repository:{},_referenceCounter:{}};
swaf.factory.get=function(classname) {
    if (typeof classname=='function' && classname.prototype.CLASSNAME) classname=classname.prototype.CLASSNAME;
    var info=classname.toObject().prototype._singleton_info;
    if (info) {
        var scope=info.scope;
        if (scope=='domain') {
            var respository=swaf.gs('_swaf_factory_repository');
            if (!respository[classname]) {
                eval('var instance=new '+classname);
                instance.isSingleton=true;
                respository[classname]=instance;
            }
            if (swaf.factory._referenceCounter[classname]) swaf.factory._referenceCounter[classname]++;
            else swaf.factory._referenceCounter[classname]=1;
            var reference=swaf.gs('_swaf_factory_referenceCounter');
            if (reference[classname]) reference[classname]++;
            else reference[classname]=1;
            return respository[classname];
        } else {
            if (!swaf.factory._repository[classname]) {
                eval('var instance=new '+classname);
                instance.isSingleton=true;
                swaf.factory._repository[classname]=instance;
            }
            return swaf.factory._repository[classname];
        }
    }
    return null;
};

swaf.factory.regist=function(classDefine,info) {
    if (!info) info={scope:'page',lazyInit:false};
    classDefine.prototype._singleton_info=info;
    var ret=swaf.factory.get(classDefine.prototype.CLASSNAME);
    return ret;
};

swaf.factory.remove=function(classname) {
    if (typeof classname=='function' && classname.prototype.CLASSNAME) classname=classname.prototype.CLASSNAME;
    var scope=classname.toObject().prototype._singleton_info.scope;
    if (scope=='domain') {
        var respository=swaf.gs('_swaf_factory_repository');
        respository[classname]=null;
        swaf.factory._referenceCounter[classname]--;
        var reference=swaf.gs('_swaf_factory_referenceCounter');
        reference[classname]--;
    } else {
        swaf.factory._repository[classname]=null;
    }
};

swaf.factory.unloadPage=function() {
    var reference=swaf.gs('_swaf_factory_referenceCounter');
    for(var classname in swaf.factory._referenceCounter) {
        reference[classname]-=swaf.factory._referenceCounter[classname];
        if (reference[classname]<=0) {
            var respository=swaf.gs('_swaf_factory_repository');
            delete respository[classname];
            delete reference[classname];
        }
    }
};

/////////////////////////// class ////////////////////////////
swaf.dummy._swaf_base_class=function() {};
swaf.dummy._swaf_base_class.prototype={
	CLASSNAME : 'base',
	_inherit_initList:[],
	_inherit_list:['base'],
	isSwafClass:true,
	isSingleton:false,
	init : function() {
	},
	instanceOf:function(cls) {
	    return (this._inherit_list.find(cls.prototype.CLASSNAME)>=0);
	}
};

swaf.dummy._swaf_class_keyword='parent|BASE|EXTEND|NAMESPACE';
swaf.dummy._swaf_class_regexp=/\./g;

swaf.dummy._swaf_process_class_inherit=function(child,parent) {
    /* 20071121 buld inherit list for instanceOf - reizes*/
    child.prototype._inherit_list=parent.prototype._inherit_list;
    child.prototype._inherit_list.push(child.prototype.CLASSNAME);
	for(var property in parent.prototype) {
		if (swaf.dummy._swaf_class_keyword.indexOf(property)>=0) continue;
		if (property=='EVENT_MAP') {
			if (!child.prototype.EVENT_MAP) child.prototype.EVENT_MAP={};
			$extend(child.prototype.EVENT_MAP,parent.prototype.EVENT_MAP);
		} else {
			if (child.prototype[property]) {
			    var arrclsname=parent.prototype.CLASSNAME.split('.');
				var clsname=parent.prototype.CLASSNAME.replace(swaf.dummy._swaf_class_regexp,'_');
				child.prototype['parent$'+property]=parent.prototype[property];
				child.prototype[clsname+'$'+property]=parent.prototype[property];
				if (arrclsname.length>1) child.prototype[arrclsname.last()+'$'+property]=parent.prototype[property];
				if (property=='init') {
					var tmp=parent.prototype._inherit_initList.concat([clsname+'$'+property]);
					if (child.prototype._inherit_initList) child.prototype._inherit_initList=child.prototype._inherit_initList.concat(tmp);
					else child.prototype._inherit_initList=tmp;
				}
			} else {
				child.prototype[property]=parent.prototype[property];
				if (property=='init') {
					var tmp=parent.prototype._inherit_initList.concat([property]);
					if (child.prototype._inherit_initList) child.prototype._inherit_initList=child.prototype._inherit_initList.concat(tmp);
					else child.prototype._inherit_initList=tmp;
				}
			}
		}
	}
};
swaf.dummy._swaf_process_class_extend=function(child,parent) {
	for(var property in parent) {
		if (swaf.dummy._swaf_class_keyword.indexOf(property)>=0) continue;
		if (child.prototype[property]) {
			child.prototype['parent$'+property]=parent[property];
			if (parent.CLASSNAME) child.prototype[parent.CLASSNAME.replace(swaf.dummy._swaf_class_regexp,'_')+'$'+property]=parent[property];
		} else {
			child.prototype[property]=parent[property];
		}
	}
};

swaf.$class=function(define) {
	for(var clsName in define) {
		var cls=define[clsName];
		var retObj=function() {
		    if (arguments.length==50 && arguments[49]==2&& arguments[0]==1) return;
			if (this._swaf_event_map_define && swaf.message) {
			    if (this.EVENT_SRC) {
			        if (typeof this.EVENT_SRC == 'string') swaf.event(swaf.$(this.EVENT_SRC),this._swaf_event_map_define);
			        else if (this.EVENT_SRC instanceof RegExp) swaf.event(swaf.$(this.EVENT_SRC),this._swaf_event_map_define);
			        else swaf.event(this.EVENT_SRC,this._swaf_event_map_define);
			    }
				else swaf.event(this,this._swaf_event_map_define);
			}
			for(var i=0;i<this._inherit_initList.length;i++) {
					this[this._inherit_initList[i]].apply(this,arguments);
			}
			if (this.init) this.init.apply(this,arguments);
		};
	    if (cls.BASE) {
	        var baseCls=null;
	        if (cls.BASE instanceof Array) baseCls=cls.BASE[0];
	        else baseCls=cls.BASE;
	        retObj.prototype=new baseCls(1,0,0,0,0,0,0,0,0,0,
                                        0,0,0,0,0,0,0,0,0,0,
                                        0,0,0,0,0,0,0,0,0,0,
                                        0,0,0,0,0,0,0,0,0,0,
                                        0,0,0,0,0,0,0,0,0,2);
            baseCls=null;                            
        }
		for(var property in cls) {retObj.prototype[property]=cls[property];}
		retObj.prototype.CLASSNAME=cls.NAMESPACE?cls.NAMESPACE.NAMESPACE+'.'+clsName:clsName;
		if (!cls.BASE) cls.BASE=swaf.dummy._swaf_base_class;
		// process extend
		{
			var extList=cls.BASE;
			if (extList instanceof Array && extList.length>1) {
				for(var i=0;i<extList.length;i++) {
					swaf.dummy._swaf_process_class_inherit(retObj,extList[i]);
				}
			} else {
				swaf.dummy._swaf_process_class_inherit(retObj,extList);
			}
			delete cls.BASE;
		}
		if (cls.EXTEND) {
			var extList=cls.EXTEND;
			if (extList instanceof Array && extList.length>1) {
				for(var i=0;i<extList.length;i++) {
					swaf.dummy._swaf_process_class_extend(retObj,extList[i]);
				}
			} else {
				swaf.dummy._swaf_process_class_extend(retObj,extList);
			}
			delete cls.EXTEND;
		}
		if (cls.EVENT_MAP && swaf.message) {
			retObj.prototype._swaf_event_map_define={};
			for(var msg in cls.EVENT_MAP) {
				var item=cls.EVENT_MAP[msg];
				if (item instanceof Array) {
					retObj.prototype._swaf_event_map_define[msg]=[];
					for(var i=0;i<item.length;i++) {
						retObj.prototype._swaf_event_map_define[msg].push(retObj.prototype[item]);
					}
				} else {
					retObj.prototype._swaf_event_map_define[msg]=retObj.prototype[item];
				}
				item=null;
			}
			delete cls.EVENT_MAP;
		}

		retObj.prototype.toString=function() {return this.CLASSNAME;};

	    var singletonObj=null;
		if (typeof cls.SINGLETON !='undefined') {
		    if (cls.SINGLETON==true) {
		        singletonObj={scope:'page',lazyInit:false};
		    } else if (typeof cls.SINGLETON == 'object') { singletonObj=cls.SINGLETON;}
		    if (singletonObj) {
		        retObj.prototype._singleton_info=singletonObj;
		    }
		    delete cls.SINGLETON;
		}

		if (cls.NAMESPACE) {
			cls.NAMESPACE[clsName]=retObj;
			delete cls.NAMESPACE;
		} else {
			window[clsName]=retObj;
		}
		
        if (singletonObj && singletonObj.lazyInit==false) swaf.factory.get(retObj.prototype.CLASSNAME);
		
		retObj=null;
	}
};
if (typeof $class== 'undefined') var $class=swaf.$class;
if (typeof $factory== 'undefined') var $factory=swaf.factory;
swaf.listener(window,"unload",swaf.factory.unloadPage);

// SWAF Frame Independent Global Storage
swaf.gs=function(name,deleteOnUnload) {
	var ret=swaf.gs.get(name);
	if (!ret) {
		if (swaf.gs.enableOpener && swaf.gs.opener) {
			ret=swaf.gs.opener.swaf.globalStorage.create(name);
		} else {
			if (!swaf.gs.window._swaf_gs_storage) swaf.gs.window._swaf_gs_storage={};
			ret=swaf.gs.window._swaf_gs_storage[name]={};
		}
		if (ret) swaf.gs.nameCache[name]=(typeof deleteOnUnload=='undefined')?true:deleteOnUnload;
	}
	return ret;
};
swaf.gs.nameCache={};
swaf.gs.childs=[];
swaf.gs.childsAll=[];
swaf.gs.window=window;
swaf.gs.opener=null;
swaf.gs.enableOpener=false;
swaf.gs.get=function(name) {
	if (swaf.gs.enableOpener && swaf.gs.opener) {
		return swaf.gs.opener.swaf.gs.get(name);
	}
	if (swaf.gs.window && swaf.gs.window._swaf_gs_storage) {
		return swaf.gs.window._swaf_gs_storage[name];
	}
	return null;
};
swaf.gs.remove=function(name,removeMine) {
	if (removeMine==true) {
		if (swaf.gs.nameCache[name]!=true && swaf.gs.nameCache[name]!=false) return;
	}
	if (swaf.gs.enableOpener && swaf.gs.opener) {
		swaf.gs.opener.swaf.gs.remove(name);
	} else if (swaf.gs.window._swaf_gs_storage&&swaf.gs.window._swaf_gs_storage[name]) swaf.gs.window._swaf_gs_storage[name]=null;
	swaf.gs.nameCache[name]=null;
};
swaf.gs.onUnload=function() {
	if (swaf.gs.nameCache) {
		for(selector in swaf.gs.nameCache) {
			if (swaf.gs.nameCache[selector]==true) {
				swaf.gs.window._swaf_gs_storage[name]=null;
			}
		}
	}
	var win=window;
	for(var depth=0;win.parent;depth++,win=win.parent) {
		try {
			if (!win.parent.document || !win.parent.document.body || typeof win.parent.swaf=='undefined') break;
			if (win.parent.document.body.tagName!='BODY') break;
			if (window.top==win) break;
		} catch(e) { break;}
		if (depth==0) {
			win.parent.swaf.gs.childs.removeCompact(win);
		}
		win.parent.swaf.gs.childsAll.removeCompact(win);
	}
};
swaf.gs.onLoad=function() {
	var win=window;
	for(var depth=0;win.parent;depth++,win=win.parent) {
		try {
			if (!win.parent.document || !win.parent.document.body || typeof win.parent.swaf=='undefined') break;
			if (win.parent.document.body.tagName!='BODY') break;
			if (window.top==win) break;
		} catch(e) { break;}
		if (depth==0) {
			win.parent.swaf.gs.childs.push(win);
		}
		win.parent.swaf.gs.childsAll.push(win);
	}
	swaf.gs.window=win;
	try {
		if (win.opener && win.opener.swaf) swaf.gs.opener=win.opener;
	} catch(e) {
	  swaf.gs.opener=null;
	}
};
swaf.gs.$=function(element) {
	var tmp=swaf.$(element);
	var ret=[];
	if (tmp) {
		if (typeof tmp.length=='number') ret=$A(tmp);
		else ret.push(tmp);
	}
	for(var i=0;i<swaf.gs.childsAll.length;i++) {
		tmp=swaf.gs.childsAll[i].swaf.$(element);
		if (tmp) {
			if (typeof tmp.length=='number') ret=ret.concat(swaf.$A(tmp));
			else ret.push(tmp);
		}
	}
	return ret;
};
swaf.gs.getAllWindows=function() {
	return swaf.gs.window.swaf.gs.childsAll;
};

var _global_onLoad=function() {
// init global storage
	swaf.gs.onLoad();
// call init function
	swaf.onLoadDocument();
};
var _global_onUnLoad=function() {
	swaf.onUnloadDocument();
// resource clean
	if (swaf.browser.isIE) {
		swaf._event.resetListener();
		swaf.message.resetListener();
	}
	swaf.gs.onUnload();
};
if (typeof $gs == 'undefined') var $gs=swaf.gs;

swaf.listener(window,"load",_global_onLoad);
swaf.listener(window,"unload",_global_onUnLoad);


// event object
swaf.$class({
	eventObject:{
		NAMESPACE:swaf,
		event:null,
		// constructor
		init : function(evt) {
			this.event=evt;
		},
		// static value
	  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,
	  KEY_HOME:     36,
	  KEY_END:      35,
	  KEY_PAGEUP:   33,
	  KEY_PAGEDOWN: 34,
		// method
	  element: function() { return this.event.target || this.event.srcElement; },
	  isLeftClick: function() { return (((this.event.which) && (this.event.which == 1)) || ((this.event.button) && (this.event.button == 1))); },
	  getX: function() {
	    return this.event.pageX || (this.event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
	  },
	  getY: function() {
	    return this.event.pageY || (this.event.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
	  },
	  keyCode:function() {
	    return this.event.keyCode;
	  },
	  stop: function() {
	    if (this.event.preventDefault) { 
	      this.event.preventDefault(); 
	      this.event.stopPropagation(); 
	    } else {
	      this.event.returnValue = false;
	      this.event.cancelBubble = true;
	    }
	  }
	}
});

swaf.namespace('swaf');

var _swaf_execJS=function(code) {
    return eval(code);
};

swaf._debug={
	debugMode:false,
	autoview:true,
	bInit:false,
	consoleHTML:'<table width="100%" border="0" cellspacing="0" cellpadding="0" id="SwafDebugMessageTable" style="font-family:Verdana Tahoma ü;font-size:12px;font-weight:400;"><tr style="height:15px;background:#ff0000;font-weight:600;">\
			<td id="swaf_debug_dnd_handle"><a onclick="swaf._debug.viewConsole();" style="cursor:pointer;">VIEW</a>&nbsp;<a onclick="swaf._debug.hideConsole();" style="cursor:pointer;">MIN</a>&nbsp;<a onclick="swaf._debug.clearCode();" style="cursor:pointer;">CLEAR1</a>&nbsp;<a onclick="swaf._debug.clearConsole();" style="cursor:pointer;">CLEAR2</a>&nbsp;&nbsp;&nbsp;&nbsp;<a onclick="swaf._debug.hideDebug();" style="cursor:pointer;">HIDE</a></td>\
			</tr><tr style="height:20px;"><td><input type="text" id="swaf_debug_object_path" style="width:490px;background:#e0e0ff" value="window"/></td></tr>\
			<tr style="height:20px;"><td><input type="text" id="swaf_debug_objects1" style="width:150px;" value="window" readonly/>&nbsp;<select id="swaf_debug_objects2" style="width:200px;" onchange="swaf._debug.onChangeObject2();"></select>&nbsp;&nbsp;&nbsp;<span onclick="swaf._debug.goParentObject()" style="cursor:pointer;border:1px solid #a0a0ef;">&nbsp;PARENT&nbsp;</span></td></tr>\
			<tr style="height:200px;"><td><textarea id="SwafDebugJSConsole" style="width:490px;height:200px;font-size:11px;"></textarea></td></tr><tr><td><textarea id="SwafDebugMessageContents" style="width:490px;height:250px;" readonly></textarea></td></tr></table>',
	dumpObject:function(obj,separator) {
		var msg='';
		var sep=separator||' ';
		if (obj instanceof Array) {
			for(var i=0;i<obj.length;i++) msg+=obj[i]+sep;
		} else {
			for (selector in obj) {
				msg+=selector+' : '+obj[selector]+sep;
			}
		}
		return msg;
	},
	initialize:function() {
	    if (this.bInit==true) return;
	    this.bInit=true;
	    
	    this.setObjectList2();
	    swaf.listener($('SwafDebugJSConsole'),'keydown',this.onJSKeyDown,this);
	    swaf.listener($('swaf_debug_object_path'),'keydown',this.onObj1KeyDown,this);
	},
	curObj:window,
	objList2:null,
	setObjectList2:function() {
	    var arr;
	    var el=swaf.$('swaf_debug_objects2');
	    if (this.curObj) {
	        arr=this.getMemberList(this.curObj);
	    } else {
	        arr=this.getMemberList(window);
	    }
	    this.setObjectList(arr,el);
	    this.objList2=arr;
	    this.viewValue();
	},
	onChangeObject2:function() {
	    var el=swaf.$('swaf_debug_objects2');
	    var path_el=swaf.$('swaf_debug_object_path');
	    path_el.value+='.'+el.value;
	    swaf.$('swaf_debug_objects1').value=el.value;
	    this.curObj=this.curObj[el.value];
	    this.setObjectList2();
	},
	getMemberList:function(obj) {
	    var arr=[];
	    for(property in obj) {
	        arr.push({text:property+' ['+typeof obj[property]+']',value:property});
	    }
	    arr.sort(function(a,b) {return a.text.toLowerCase()<b.text.toLowerCase()?-1:1;});
	    return arr;
	},
	setObjectList:function(arr,el,index) {
	    el.options.length=0;
	    for(var i=0;i<arr.length;i++) {
	        el.options[i]=new Option();
	        el.options[i].text=arr[i].text;
	        el.options[i].value=arr[i].value;
	    }
	    if (typeof index !='undefined') el.selectedIndex=index;
	    arr=el=null;
	},
	viewValue:function() {
	    var text=swaf.$('swaf_debug_object_path').value;
	    try {
	        var value=eval(text);
	    } catch (e) {
	        this.outputDebugLn(this.dumpObject(e,'\n'));
	    }
	    switch (typeof value) {
	        case 'number' :
	        case 'string' :
	        case 'boolean' :
        	    this.outputDebugLn(text+' = '+value);
        	    break;
        	case 'object' :
        	    if (value instanceof Array) this.outputDebugLn(this.dumpObject(value,','));
        	    break;
	    }
	},
	onObj1KeyDown:function(evt,src,type) {
	    if (evt.keyCode()==13) {
	        var value=swaf.$('swaf_debug_object_path').value;
	        swaf.$('swaf_debug_objects1').value=value.split('.').last();
            try {
    	        this.curObj=eval(value);
    	        this.setObjectList2();
            } catch(e) {
                 swaf.$('swaf_debug_objects2').options.length=0;
                 this.outputDebugLn(this.dumpObject(e,'\n'));
            }
	    }
	},
	goParentObject:function() {
        var value=swaf.$('swaf_debug_object_path').value;
        var arrValue=value.split('.');
        if (arrValue.length==1) return;
        arrValue.pop();
        swaf.$('swaf_debug_objects1').value=arrValue.last();
        var path=arrValue.join('.');
        swaf.$('swaf_debug_object_path').value=path;
        this.curObj=eval(path);
        this.setObjectList2();
	},
	jscode:[],
	onJSKeyDown:function(evt,src,type) {
	    if (evt.keyCode()==13) {
	        var el=swaf.$('SwafDebugJSConsole');
	        var text=el.value;
	        var lines=text.split('\n');
	        var code=lines.last();
	        if (code.trim().length==0) return;
	        var result='';
	        try {
	            result=_swaf_execJS(code);
	        } catch(e) {
	            result=this.dumpObject(e,'\n');
	        }
	        el.value=text+'\n'+result;
	        el.scrollTop=el.scrollHeight;
	    }
	},
	clearCode:function() {
	    swaf.$('SwafDebugJSConsole').value='';
	    this.clearDebug();
	},
	debugMsg:'',
	viewConsole:function() {
	    if (this.debugMode!=true) return;
	    swaf.dom.setSize(swaf.$('SwafDebugMessageLayer'),500,530);
        this.initialize();
	},
	hideConsole:function() {
	    swaf.dom.setSize(swaf.$('SwafDebugMessageLayer'),40,15);
	},
	clearConsole:function() {
	    swaf.$('SwafDebugMessageContents').value='';
	    this.clearDebug();
	},
	onDndDown:function(evt,src,type) {
	    if (this.dragMode==true) return;
    	this.dragMode=true;
    	var pos=swaf.dom.getPos(src);
    	this.origOffset={x:evt.getX()-pos.x,y:evt.getY()-pos.y};
	    this.dndListenerHandle=swaf.event(document,{
	        mousemove:this.onDndMove,
	        mouseup:this.onDndUp
	    });
	},
	onDndMove:function(evt,src,type) {
	    if (swaf._debug.dragMode==true) 
	        swaf.dom.setPos(swaf.$('SwafDebugMessageLayer'),evt.getX()-swaf._debug.origOffset.x,evt.getY()-swaf._debug.origOffset.y);
	},
	onDndUp:function(evt,src,type) {
	    if (swaf._debug.dragMode==true) {
	        swaf._debug.dragMode=false;
	        swaf.dom.setPos(swaf.$('SwafDebugMessageLayer'),evt.getX()-swaf._debug.origOffset.x,evt.getY()-swaf._debug.origOffset.y);
	        swaf.event.remove(swaf._debug.dndListenerHandle);
	        swaf._debug.dndListenerHandle=null;
	    }
	},
	outputDebug:function(msg) {
		if (swaf._debug.debugMode!=true) return;
		this.debugMsg+=msg;
		this.createConsole();
		el=swaf.$('SwafDebugMessageContents');
		el.value=this.debugMsg;
		if (this.autoview==false) this.hideDebug();
		else el.scrollTop=el.scrollHeight;
		
		el=null;
	},
	createConsole:function() {
		var el=document.getElementById('SwafDebugMessageLayer');
		if (!el) {
			el=document.createElement('div');
			el.id='SwafDebugMessageLayer';
			el.style.position='absolute';
			el.style.left='0px';
			el.style.top='0px';
			el.style.background='white';
			el.style.border='1px solid red';
			el.style.zIndex=9999;
			el.style.width='40px';
			el.style.height='15px';
			el.style.overflow='hidden';
			el.dragMode=false;
			document.body.appendChild(el);
			el.innerHTML=this.consoleHTML;
			$style.opacity(el,0.9);
    	    swaf.listener($('swaf_debug_dnd_handle'),'mousedown',this.onDndDown,this);
		}
	},
	outputDebugLn:function(msg) {
	    if (swaf._debug.debugMode!=true) return;
		this.outputDebug(msg+'\n');
	},
	clearDebug:function() {
		this.debugMsg='';
	},
	hideDebug:function() {
	    var el=swaf.$('SwafDebugMessageLayer');
	    if (el) swaf.dom.hide(el);
	},
	showDebug:function() {
	    if (this.debugMode!=true) return;
        this.createConsole();
        swaf.dom.show(swaf.$('SwafDebugMessageLayer'));
	},
	setDebugMode:function(mode,autoview,keycode) {
	    this.debugMode=mode;
	    this.autoview=(typeof autoview=='undefined')?true:autoview;
	    if (mode==true) {
	        this.debugKeyCode=(typeof keycode=='undefined')?68:keycode; // d
	        this.debugModeHandle=swaf.listener(document,'keydown',this.viewDebugConsole,this);
	    } else {
	        this.hideDebug();
	        if (this.debugModeHandle) swaf.listener.remove(this.debugModeHandle);
	        this.debugModeHandle=null;
	    }
	},
	viewDebugConsole:function(evt,src) {
	    if (this.debugMode!=true) return;
	    if (evt.event.altKey && evt.event.ctrlKey && evt.event.shiftKey && evt.keyCode()==this.debugKeyCode) {
	        this.showDebug();
	    }
	}
};

swaf.debug= function(mode,autoview,keycode) {swaf._debug.setDebugMode(mode,autoview,keycode);};
swaf.debug.output=function(msg) {swaf._debug.outputDebug(msg);};
swaf.debug.outputLn=function(msg) {swaf._debug.outputDebugLn(msg);};
swaf.debug.show=function() {swaf._debug.showDebug();};
swaf.debug.hide=function() {swaf._debug.hideDebug();};
swaf.debug.max=function() {swaf._debug.viewConsole();};
swaf.debug.min=function() {swaf._debug.hideConsole();};
swaf.debug.dump=function(obj,sep) {return swaf._debug.dumpObject(obj,sep);};

if (typeof $debug== 'undefined') var $debug=swaf.debug;

// css function
swaf.css=function(element,className) {
	if (className) swaf.css.set(element.className);
	else return swaf.css.get(element);
};
swaf.css.set=function(element,className) {
	element.className=className;
	element._swaf_class_cache=className.split(' ');
};
swaf.css.add=function(element,className) {
	if (!element._swaf_class_cache) {
		element._swaf_class_cache=element.className.split(' ');
	}
	if (element._swaf_class_cache.find(className)>=0) return;
	element._swaf_class_cache.push(className);
	element.className=element._swaf_class_cache.join(' ');
};
swaf.css.get=function(element) {
	if (!element._swaf_class_cache) {
		element._swaf_class_cache=element.className.split(' ');
	}
	return element._swaf_class_cache;
};
swaf.css.remove=function(element,className) {
	if (!element._swaf_class_cache) {
		element._swaf_class_cache=element.className.split(' ');
	}
	var p=element._swaf_class_cache.find(className);
	if (p<0) return;
	element._swaf_class_cache=element._swaf_class_cache.splice(p,1);
	element.className=element._swaf_class_cache.join(' ');
};
swaf.css.getRule=function(selectorname) {
	var css=document.styleSheets;
	var rules,rule;
	for(var i=css.length-1;i>=0;i--) {
		try {
			if (css[i].cssRules) rules=css[i].cssRules;
			else if (css[i].rules) rules=css[i].rules;
		} catch(e) {
			continue;
		}
		for(var j=0;j<rules.length;j++) {
			rule=rules[j];
			if (rule.selectorText && rule.selectorText==selectorname) {
				return rule.style;
			}
		}
	}
	return null;
};
swaf.css.addRule=function(strName,strRule) {
	var head=document.getElementsByTagName("head");
	if (head) {
		var style=document.createElement('style');
		if (swaf.browser.isIE) {
			style.setAttribute('type','text/css');
			if(style.styleSheet){// IE
				style.styleSheet.cssText = strName+' {'+strRule+'}';
			} else {// w3c
				var cssText = document.createTextNode(strName+' {'+strRule+'}');
				style.appendChild(cssText);
				cssText=null;
			}
		} else {
			style.setAttribute('type','text/css');
			style.innerHTML=strName+' {'+strRule+'}';
		}
		head[0].appendChild(style);
		style=null;
	}
	head=null;
};
swaf.css.load=function(src) {
	var head=document.getElementsByTagName("head");
	if (head) {
		var linkel=document.createElement('link');
		linkel.setAttribute('href', src);
		linkel.setAttribute('rel', 'stylesheet');
		linkel.setAttribute('type', 'text/css');
		head[0].appendChild(linkel);
	}
	head=null;
};
swaf.style=function(element,property,value) {
	if (value) swaf.style.set(element,property,value);
	else return swaf.style.get(element,property);
};
swaf.style.set=function(element,property,value) {
	if (property=='opacity') swaf.style.opacity(element,value);
	else element.style[property] = value;
};
swaf.style.get=function(element,property) {
  var value = null;
  var dv = document.defaultView;
  
  if (swaf.browser.isIE && property == 'opacity') { // IE
  	value=1;
    if (value = (element.style.filter || '').match(/alpha\(opacity=(.*)\)/))
      if (value[1]) value=parseFloat(value[1]) / 100;
  }
/*  if (property == 'opacity' && element.filters) 	// IE
  {
     value = 1;
     try { value = element.filters.item('DXImageTransform.Microsoft.Alpha').opacity; } catch(e) {
        try { value = element.filters.item('alpha').opacity/100; } catch(e) {}
     }
  }*/
  else if (element.style[property]) {return element.style[property];}
  else if (element.currentStyle && element.currentStyle[property]) { return element.currentStyle[property];}
  else if ( dv && dv.getComputedStyle )
  {
     var converted = '';
     for(var i = 0, len = property.length;i < len; ++i) {
        if (property.charAt(i) == property.charAt(i).toUpperCase()) {
           converted = converted + '-' + property.charAt(i).toLowerCase();
        } else {
           converted = converted + property.charAt(i);
        }
     }
     if (dv.getComputedStyle(element, '') && dv.getComputedStyle(element, '').getPropertyValue(converted)) {
        value = dv.getComputedStyle(element, '').getPropertyValue(converted);
     }
  }
  element=null;
  return value;
};
swaf.style.opacity=function(element,value) {
	if (arguments.length>1) this.setOpacity(element,value);
	else return this.get(element,'opacity');
};
swaf.style._setOpacity_ie=function(element,value) {
	element.style.filter = 'alpha(opacity=' + (value*100) + ')';
	if (!element.currentStyle || !element.currentStyle.hasLayout) {element.style.zoom = 1;}
};
swaf.style._setOpacity_non_ie=function(element,value) {
	element.style.opacity = value;
  element.style['-moz-opacity'] = value;
  element.style['-khtml-opacity'] = value;
};
// process cross browsing
swaf.style.setOpacity = (swaf.browser.isIE)?swaf.style._setOpacity_ie:swaf.style._setOpacity_non_ie;

swaf.style.setFromObject=function(element,objStyle) {
	for(selector in objStyle) {
		this.set(element,selector,objStyle[selector]);
	}
};

swaf.dom={
	setPos:function(element,x,y,parentElement) {
		var pos=element.style.position?element.style.position:'static';
		var relative=(pos=='relative');
		var position=swaf.dom.getPos(element);
		var dx=parseInt(element.style.left,10);
		var dy=parseInt(element.style.top,10);
		if (isNaN(dx)) {dx=(relative)?0:element.offsetLeft;}
		if (isNaN(dy)) {dy=(relative)?0:element.offsetTop;}
		if (parentElement) {
			var ppos=swaf.dom.getPos(parentElement);
			dx+=ppos.x;
			dy+=ppos.y;
			parentElement=null;
		}
		position.x=x-position.x+dx;
		position.y=y-position.y+dy;
		element.style.left = position.x+'px';
		element.style.top = position.y+'px';
		element=null;
	},
	_getPosition_ie:function(element,parentElement) {
		var parent = null;
		var pos = {x:0,y:0};
		
		var rect = element.getBoundingClientRect();
		pos.x=rect.left + Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
		pos.y=rect.top + Math.max(document.documentElement.scrollTop, document.body.scrollTop);
		rect=null;
          
		if (parentElement) {
			var ppos=this._getPosition_ie(parentElement);
			pos.x-=ppos.x;
			pos.y-=ppos.y;
			parentElement=null;
			ppos=null;
		}
		element=null;
		parent=null;
		return {x:isNaN(pos.x)?0:pos.x,y:isNaN(pos.y)?0:pos.y};
	},
	_getPosition_ff:function(element,parentElement) {
    var parent = null;
    var pos = {x:0,y:0};
    
		var rect = document.getBoxObjectFor(element);
		pos = {x:rect.x, y:rect.y};
		rect=null;

    if (element.parentNode) { parent = element.parentNode; }
    else { parent = null; }

    while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') 
    {
       pos.x -= parent.scrollLeft;
	     pos.y -= parent.scrollTop;

       if (parent.parentNode) { parent = parent.parentNode; } 
       else { parent = null; }
    }
          
		if (parentElement) {
			var ppos=this._getPosition_ff(parentElement);
			pos.x-=ppos.x;
			pos.y-=ppos.y;
			parentElement=null;
			ppos=null;
		}
		element=null;
		parent=null;
		return {x:isNaN(pos.x)?0:pos.x,y:isNaN(pos.y)?0:pos.y};
	},
	_getPosition_etc:function(element,parentElement) {
		var parent = null;
		var pos = {x:0,y:0};
		
		pos = {x:element.offsetLeft, y:element.offsetTop};
		parent = element.offsetParent;
		if (parent != element) {
		  while (parent) {
		     pos.x += parent.offsetLeft;
		     pos.y += parent.offsetTop;
		     parent = parent.offsetParent;
		  }
		}
		if (swaf.browser.isOpera||( swaf.browser.isSafari && element.style.position == 'absolute')) {
		  pos.x -= document.body.offsetLeft;
		  pos.y -= document.body.offsetTop;
		} 
		      
		if (parentElement) {
			var ppos=this._getPosition_etc(parentElement);
			pos.x-=ppos.x;
			pos.y-=ppos.y;
			parentElement=null;
			ppos=null;
		}
		element=null;
		parent=null;
		return {x:isNaN(pos.x)?0:pos.x,y:isNaN(pos.y)?0:pos.y};
	},
	_getPosition:null,
	getPos:function(element,parentElement) {
		if (!this._getPosition) {
			if (element.getBoundingClientRect) this._getPosition=this._getPosition_ie;
			else if (document.getBoxObjectFor) this._getPosition=this._getPosition_ff;
			else this._getPosition=this._getPosition_etc;
		}
		return this._getPosition(element,parentElement);
	},
	toRelative:function(x,y,element) {
		var pos={x:x,y:y};
		var ppos=this.getPosition(element);
		pos.x-=ppos.x;
		pos.y-=ppos.y;
		element=null;
		ppos=null;
		return pos;
	},
	setWidth:function(element,w) {		element.style.width=w+'px';	},
	setHeight:function(element,h) {		element.style.height=h+'px';	},
	getWidth:function(element) {		return element.offsetWidth;	},
	getHeight:function(element) {		return element.offsetHeight;	},
	setSize:function(element,w,h) {
		var els=element.style;
		els.width=w+'px';
		els.height=h+'px';
		els=null;
	},
	getSize:function(element) {		return {width:element.offsetWidth,height:element.offsetHeight};	},
	setRect:function(element,x,y,width,height,parentElement) {
		this.setPos(element,x,y,parentElement);
		this.setSize(element,width,height);
		element=null;
	},
	getRect:function(element,parentElement) {
		var pos=this.getPos(element,parentElement);
		var size=this.getSize(element);
		element=null;
    return {x:pos.x,y:pos.y,width:size.width,height:size.height};
	},
	getBorderWidth:function(element) {
		var l=parseInt(swaf.style.get(element,'borderLeftWidth'),10);
		var t=parseInt(swaf.style.get(element,'borderTopWidth'),10);
		var r=parseInt(swaf.style.get(element,'borderRightWidth'),10);
		var b=parseInt(swaf.style.get(element,'borderBottomWidth'),10);
		return {left:isNaN(l)?0:l,top:isNaN(t)?0:t,right:isNaN(r)?0:r,bottom:isNaN(b)?0:b};
	},
	getPadding:function(element) {
		var l=parseInt(swaf.style.get(element,'paddingLeft'),10);
		var t=parseInt(swaf.style.get(element,'paddingTop'),10);
		var r=parseInt(swaf.style.get(element,'paddingRight'),10);
		var b=parseInt(swaf.style.get(element,'paddingBottom'),10);
		return {left:isNaN(l)?0:l,top:isNaN(t)?0:t,right:isNaN(r)?0:r,bottom:isNaN(b)?0:b};
	},
	getMargin:function(element) {
		var l=parseInt(swaf.style.get(element,'marginLeft'),10);
		var t=parseInt(swaf.style.get(element,'marginTop'),10);
		var r=parseInt(swaf.style.get(element,'marginRight'),10);
		var b=parseInt(swaf.style.get(element,'marginBottom'),10);
		return {left:isNaN(l)?0:l,top:isNaN(t)?0:t,right:isNaN(r)?0:r,bottom:isNaN(b)?0:b};
	},
	getDocumentRect:function(doc) {
		if (!doc) doc=document;
		var docHeight=-1,winHeight=-1,bodyHeight=-1;
		var docWidth=-1,bodyWidth=-1,winWidth=-1;
		var margin=swaf.dom.getMargin(doc.body);

		var mode = doc.compatMode;
		if ( (mode || swaf.browser.isIE) && !swaf.browser.isOpera ) { // (IE, NS)
		  switch (mode) {
		     case 'CSS1Compat': 
		        docWidth = doc.docElement?doc.docElement.clientWidth:0;
		        docHeight = ((window.innerHeight && window.scrollMaxY) ?  window.innerHeight+window.scrollMaxY : -1);
		        winWidth = self.innerWidth || -1;
		        winHeight = Math.max((doc.docElement)?doc.docElement.clientHeight:0,self.innerHeight||-1);
		        bodyWidth = doc.body.offsetWidth + margin.left + margin.right;
		        bodyHeight = doc.body.offsetHeight + margin.top + margin.bottom;
		        break;
		     
		     default: 
		        winWidth = doc.body.scrollWidth;
		        winHeight= doc.body.scrollHeight;
		        //docHeight = doc.body.docHeight;
		        bodyWidth = doc.body.clientWidth;
		        bodyHeight = doc.body.clientHeight;
		        break;
		  }
		} else { // Safari & Opera
		  winWidth = self.innerWidth;
		  winHeight = self.innerHeight;
		  docWidth = doc.docElement.clientWidth;
		  docHeight = doc.docElement.docHeight;
		  bodyWidth = doc.body.offsetWidth + margin.left + margin.right;
		  bodyHeight = doc.docElement.clientHeight;
		}
		var w = [docWidth,bodyWidth,winWidth].sort(function(a, b){return(a-b);});
		var h = [docHeight,winHeight,bodyHeight].sort(function(a, b){return(a-b);});
		doc=null;
		return {width:w[2],height:h[2]};
	},
	show:function(element,x,y,parentElement) {
		swaf.style.set(element,'display','block');
		if (x && y) this.setPosition(element,x,y,parentElement);
	},
/*	showInline:function(element,x,y,parentElement) {
		swaf.style.set(element,'display','inline');
		if (x && y) this.setPosition(element,x,y,parentElement);
	},
	showStatic:function(element,x,y,parentElement) {
		swaf.style.set(element,'display','static');
	},*/
	hide:function(element) {
		swaf.style.set(element,'display','none');
	},
	toggle:function(element,x,y,parentElement) {
		var show=swaf.style.get(element,'display');
		if (show=='none') this.show(element,x,y,parentElement);
		else this.hide(element);
	},
/*	toggleInline:function(element,x,y,parentElement) {
		var show=swaf.style.get(element,'display');
		if (show=='none') this.showInline(element,x,y,parentElement);
		else this.hide(element);
	},*/
	swap:function(el1,el2) {
		if (el1.swapNode) {
			el1.swapNode(el2);
		} else {
			var p=el2.parentNode;
			var s=el2.nextSibling;
			el1.parentNode.insertBefore(el2,el1.nextSibling);
			p.insertBefore(el1,s);
		}
	},
	hideByTag:function(tagName,element) {
		var arrSelect=element.getElementsByTagName(tagName);
		for(var i=0;i<arrSelect.length;i++) {
			if (arrSelect[i].style.display=='none') continue;
			arrSelect[i].style.visibility='hidden';
		}
		arrSelect=null;
	},
	showByTag:function(tagName,element) {
		var arrSelect=element.getElementsByTagName(tagName);
		for(var i=0;i<arrSelect.length;i++) {
			arrSelect[i].style.visibility='visible';
		}
		arrSelect=null;
	},
	deleteElement:function(element) {
		try {
			element.innerHTML='';
	    var garbageBin = document.getElementById('IELeakGarbageBin');
	    if (!garbageBin) {
	        garbageBin = document.createElement('DIV');
	        garbageBin.id = 'IELeakGarbageBin';
	        garbageBin.style.display = 'none';
	        document.body.appendChild(garbageBin);
	    }
	    // move the element to the garbage bin
	    garbageBin.appendChild(element);
	    garbageBin.innerHTML = '';
	  } catch(e) {
	  }
	    element=null;
	},
	resetID:function(element) {
		var arr=element.childNodes;
		for(var i=0;i<arr.length;i++) {
			node=arr[i];
			if (node.nodeType==swaf.define.ELEMENT_NODE && node.id) {
				node.id='';
			}
		}
		arr=null;
	},
	cloneNode:function(element) {
		var retEl=element.cloneNode(true);
		swaf.dom.resetID(retEl);
		return retEl;
	}
};

swaf.iframe={
	document:function(element) {
		var doc;
		try {
			if (element.contentWindow) {doc=element.contentWindow.document}	// IE
			else if (element.contentDocument) {doc=element.contentDocument.documentElement}
		} catch(e) {
			doc=null;
		}
	  return doc;
	},
	window:function(element) {
		return element.contentWindow;
	},
	setHTML:function(element,html) {
		var doc=this.document(element);
		doc.open();
		doc.write(html);
		doc.close();
	},
	write:function(element,html) {
		var doc=this.document(element);
		doc.write(html);
	},
	resizeWidth:function(element,baseID,min,max) {
		var doc=this.document(element);
		var base=baseID?doc.getElementById(baseID):null;
		var w=(base)?swaf.dom.getWidth(base):(doc.body.scrollWidth+(doc.body.offsetWidth-doc.body.clientWidth));
		if (typeof min=='number') w=Math.max(w,min);
		if (typeof max=='number') w=Math.min(w,max);
		swaf.dom.setWidth(element,w);
		return w;
	},
	resizeHeight:function(element,baseID,min,max) {
		var doc=this.document(element);
		var base=baseID?doc.getElementById(baseID):null;
		var h=(base)?swaf.dom.getHeight(base):(doc.body.scrollHeight+(doc.body.offsetHeight-doc.body.clientHeight));
		if (typeof min=='number') h=Math.max(h,min);
		if (typeof max=='number') h=Math.min(h,max);
		swaf.dom.setHeight(element,h);
		return h;
	},
	resize:function(element,baseID,min,max) {
		var doc=this.document(element);
		var base=baseID?doc.getElementById(baseID):null;
		var w=(base)?swaf.dom.getWidth(base):(doc.body.scrollWidth+(doc.body.offsetWidth-doc.body.clientWidth));
		var h=(base)?swaf.dom.getHeight(base):(doc.body.scrollHeight+(doc.body.offsetHeight-doc.body.clientHeight));
		if (min) { w=Math.max(w,min.width);h=Math.max(h,min.height);}
		if (max) { w=Math.min(w,max.width);h=Math.min(h,max.height);}
		swaf.dom.setSize(element,w,h);
		return {width:w,height:h};
	}
};

if (typeof $css== 'undefined') var $css=swaf.css;
if (typeof $style== 'undefined') var $style=swaf.style;
if (typeof $dom== 'undefined') var $dom=swaf.dom;
if (typeof $iframe== 'undefined') var $iframe=swaf.iframe;

swaf.util={
	setPngSrc:function(el,src) {
		if (swaf.browser.isIE==true && swaf.browser.getVersion()<7) {
			if (el.src!='about:blank') {
				el.src='about:blank';
				el.width=el.height=1;
			}
			el.style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\''+ src+'\', sizingMethod=\'image\');';
		} else { 
			el.src=src;
		}
	}
};


swaf.$class({
	xmlDocument:{
		NAMESPACE:swaf,
		xmlobj:null,
		// constructor
		init : function(xmlObject) {
			if (xmlObject) {
				if (typeof xmlObject=='string') this.loadXML(xmlObject);
				else this.xmlobj=xmlObject;
			}
		},
		// method
		setXMLObject:function(xmlObject) { this.xmlobj=xmlObject; },
		getXMLObject:function() { return this.xmlobj; },
		loadXML:function(xmlString) {
			this.xmlobj=null;
			var xmlDoc=[
				function() {return new ActiveXObject('Microsoft.XMLDOM')},
	      function() {return new XMLDocument();}
	    ].tryFn();
	    if (xmlDoc) {
	    	xmlDoc.loadXML((typeof xmlString=='string'?xmlString:xmlString.toString()));
	    	this.xmlobj=xmlDoc;
	    	return this;
	    }
	    return null;
	 	},
	  $:function(node,index) {	// Node의 Child Array를 리턴
			var obj;
				if (this.xmlobj) {
					if (index!=null) obj=this.xmlobj.getElementsByTagName(node)[index];
					else obj=this.xmlobj.getElementsByTagName(node)[0];
		  		if (obj) return new swaf.xmlNode(obj);
				}
	  	return null;
	  }
	}
});

swaf.$class({
	xmlNode:{
		NAMESPACE:swaf,
		xmlobj:null,
		// constructor
		init : function(obj) {
			this.node=obj;
			if (obj) {
				this.tagName=obj.tagName;
				this.nodeType=obj.nodeType;
			}
		},
		// method
		setXMLNode:function(obj) {
			this.node=obj;
			if (obj) {
				this.tagName=obj.tagName;
				this.nodeType=obj.nodeType;
			}
		},
		getXMLNode:function() {
			return this.node;
		},
	  toArray:function(tagName) {	// 현재 node의 child node들을 Array로 구성하여 return
	  	var arr=[];
			var cnode;
			for(cnode=this.node.firstChild;cnode;cnode=cnode.nextSibling) {
				if (cnode.nodeType==swaf.define.ELEMENT_NODE) {
					if (cnode.tagName!=undefined && (tagName==undefined || (tagName!=undefined && tagName==cnode.tagName))) {
						arr.push(new swaf.xmlNode(cnode));
					}
				}
			}
			return arr;
	  },
	 	isNull:function() {
	 		return (this.node==null);
	 	},
	  getValue:function() {
	  	return this.toString();
	  },
			/* API Interface */
	  $:function(tagName,index) {
  		if (this.node) {
				var obj=this.node.getElementsByTagName(tagName)[index||0];
	  		if (obj) return new swaf.xmlNode(obj);
  		}
	  	return null;
	  },
	  $a:function(attribute) {	// Tag의 Attribute를 리턴
	  	return this.node.getAttribute(attribute);
	  },
	  // 2006.8.25... 길이 반환
	  $len:function(tagName) {
	  	var arr=[];
			var cnode,len=0;
	 		if (this.node) {
				for(cnode=this.node.firstChild;cnode;cnode=cnode.nextSibling) {
					if (cnode.nodeType==swaf.define.ELEMENT_NODE) {
						if (tagName) {
							if (cnode.tagName==tagName) len++;
						} else {
							len++;
						}
					}
				}
	 		}
	  	return len;
	  },
	  getNext:function() { return this.node.nextSibling?new swaf.xmlNode(this.node.nextSibling):null;},
	  getPrev:function() { return this.node.previousSibling?new swaf.xmlNode(this.node.previousSibling):null;},
	  getFirstChild:function() { return this.node.firstChild?new swaf.xmlNode(this.node.firstChild):null;},
	  getLastChild:function() { return this.node.lastChild?new swaf.xmlNode(this.node.lastChild):null;},
	  getParent:function() { return this.node.parentNode?new swaf.xmlNode(this.node.parentNode):null;}
	}
});

swaf.extend(swaf.xmlNode.prototype,{
	getChilds:swaf.xmlNode.prototype.toArray
});

swaf.xmlNode.prototype.toString=function() {return (this.node&&this.node.firstChild)?this.node.firstChild.data:null;};		// 위에 넣으면 동작 안함

swaf.xml=function(xmldoc) { return new swaf.xmlDocument(xmldoc);};
if (typeof $xml == 'undefined') var $xml=swaf.xml;


swaf.dummy._swaf_ajax_dummy_func=function() {};

swaf._ajax=
{
	requestHeaders:[
		'X-Requested-With', 'SwafXMLHttpRequest',
    'X-Swaf-Version', swaf.version+'.'+swaf.build
	],
	regexp_local:/%%local%%/gm,
	regexp_load1:/%%load%%\s*=\s*\S+/gm,
	regexp_load2:/%%load%%\s*=\s*/,
	regexp_load3:/%%load%%\s*=\s*\S+/,
	sequence:0,
	addAjaxSequence:true,
	ajaxDebug:false,
	arrMSxmlProgId:["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],
	msxmlProgId:null,
	getSequence:function() {
		this.sequence++;
		if (this.sequence>9999999) this.sequence=0;
		return this.sequence;
	},
	_createXHR1:function() {
		return new XMLHttpRequest();
	},
	_createXHR2:function() {
		if (this.msxmlProgId) {
			return new ActiveXObject(this.msxmlProgId); 
		}
		for (var i = 0; i < this.arrMSxmlProgId.length; i++)
		{
			try { 
				var xhr = new ActiveXObject(this.arrMSxmlProgId[i]); 
				if (xhr) {
						this.msxmlProgId=this.arrMSxmlProgId[i];
						return xhr;
				}
			} catch (e) { continue; }
		} // for
		return null;
	},
	createXMLHTTPRequest:function() { return null; },
	initAjax:function() {
		// init pool
		var num=this.poolnum=(swaf.browser.isIE)?2:4;
		this.queue_pool=new Array(num);
		for(var i=0;i<num;i++) {
			this.queue_pool[i]=new swaf._ajax.RequestProcessor();
		}
		this.queue_index=0;
		this.ajaxobjnum=0;
		this.ajaxobjcache={};
	},
	destroyAjax:function() {
		for(var i=0;i<this.poolnum;i++) {
			delete this.queue_pool[i];
		}
		delete this.queue_pool;
		this.ajaxobjcache=null;
		this.ajaxobjnum=0;
		this.initialized=false;
	},
	// request
	// { url, parameter, method, userid, password, doctype, owner, callback, callbackParameter, headers}
	push_request:function(request) {
		this.queue_index=(this.queue_index+1)%this.poolnum;
		return {queue:this.queue_index,sequence:this.queue_pool[this.queue_index].push_request(request)};
	},
	abortRequest:function(req_seq) {
		this.queue_pool[req_seq.queue].abortRequest(req_seq.sequence);
	},
	getResponseHeader:function(xhr,name) {
		return xhr.getResponseHeader(name);
	},
	// Synchronous ajax call
	ajaxSyncRequest:function(url,method,type,parameter,headers) {
		var xhr=this.createXMLHTTPRequest();
		var rparameter=(parameter?((typeof parameter=='string') ?parameter:swaf.ext.Object.toQueryString(parameter)) : '');
		var rurl=url;
		var header=(headers)?this.requestHeaders.concat(headers):this.requestHeaders.copy();
		if (method=='get' && rparameter.length>0) {
			rurl+=(rurl.match(/\?/) ? '&' : '?') + rparameter;
		}
		xhr.open(method,rurl,false);
		if (method=='post') {
			xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
		}
		if (xhr.overrideMimeType) header.push('Connection', 'close');		// Mozilla Bugzilla #246651 대응
		for(var i=0;i<header.length;i+=2) {
			xhr.setRequestHeader(header[i],header[i+1]);
		}
		xhr.send(method=='post'?rparameter:null);
		return new swaf.ajax.Response(xhr,type);
	},
	// 11/9 ajax object
	ajaxobjnum:0,
	ajaxobjcache:{},
	ajaxobjpool:{},
	getAjaxObject:function() {
		if (!this.ajaxobjcache[this.ajaxobjnum]) this.ajaxobjcache[this.ajaxobjnum]={_objectIndex:this.ajaxobjnum};
		var ret='ajaxScript'+this.ajaxobjnum;
		this.ajaxobjpool[ret]=this.ajaxobjcache[this.ajaxobjnum];
		this.ajaxobjnum++;
		return ret;
	},
	removeAjaxObject:function(object) {
		if (object && object._objectIndex) {
			this['ajaxScript'+object._objectIndex]=null;
			this.ajaxobjcache[object._objectIndex]=null;
			object=null;
		}
	}
};

if (window.XMLHttpRequest) swaf._ajax.createXMLHTTPRequest=swaf._ajax._createXHR1;
else if (window.ActiveXObject) swaf._ajax.createXMLHTTPRequest=swaf._ajax._createXHR2;

/* option 
	method : 'post' / 'get' (default : get)
	async  : true / false   (default : true)
	parameter : string / object
	type   : HTML / XML / TEXT / JSON / JS (default : XML)
	header : array 
	cbHandler : function
	cbParameter : callback parameter
*/
swaf.ajax=function(url,option) {
	var opt=option || {
		method : 'get',
		async : true,
		parameter : null,
		type : 'XML',
		header : null,
		cbHandler : null,
		cbParameter : null
	}; 
	if (opt.async==false) {
		return swaf._ajax.ajaxSyncRequest(url,opt.method||'get',opt.type||'XML',opt.parameter,opt.header);
	} 
	var request=new swaf.ajax.Request(opt.method||'get',opt.type||'XML',true);
	if (opt.parameter) request.setParameter(opt.parameter);
	if (opt.header) request.setRequestHeader(opt.header);
	if (opt.cbHandler) request.setCallbackHandler(opt.cbHandler);
	if (opt.cbParameter) request.setCallbackParameter.call(request,opt.cbParameter);
	request.request();
	return request;
};


swaf.$class({RequestQueue:
{
	NAMESPACE:swaf._ajax,
	/////////////////////////
	queue:null,
	pool:{},
	garbage:null,
	init:function() {
		this.initRequestQueue();
	},
	initRequestQueue:function() {
		this.queue=[];
		this.garbage=[];
	},
	push:function(request) {
		var seq=swaf._ajax.getSequence();
		request.__sequence=seq;
		this.pool[seq]=request;
		this.queue.push(seq);
		return seq;
	},
	pop:function() {
		if (this.queue.length>0) {
			var seq=this.queue.shift();
			this.garbage.push(seq);
			return this.pool[seq];
		}
		return null;
	},
	remove:function(seq) {
		for(var i=0;i<this.queue;i++) {
			if (this.queue[i]==seq) {
				this.queue.splice(i,1);
				delete this.pool[seq];
				return true;
			}
		}
		return false;
	},
	clearGarbage:function() {
		for(var i=0;i<this.garbage.length;i++) {
			delete this.pool[this.garbage[i]];
		}
		this.garbage.length=0;
	}
}});

swaf.$class({RequestProcessor:
{
	NAMESPACE:swaf._ajax,
	/////////////////////////
	queue:null,
	busy:false,
	curRequest:null,
	xhr:null,
	init:function() {
		this.initRequestProcessor();
	},
	initRequestProcessor:function() {
		this.queue=new swaf._ajax.RequestQueue();
	},
	onDestroy:function() {
		this.queue.clearGarbage();
		delete this.queue;
	},
	push_request:function(request) {
		// apply default
		var req={parameter:'', method:'get', doctype:'XML',headers:[]};
		Object.extend(req,request);
		var seq=this.queue.push(req);
		if (seq%10==0) this.queue.clearGarbage();
		window.setTimeout(this.do_request.bind(this),0); // for mozilla bug  https://bugzilla.mozilla.org/show_bug.cgi?id=317600
		return seq;
	},
	deleteXHR:function() {
		if (this.xhr) {
			this.xhr.onreadystatechange= swaf.dummy._swaf_ajax_dummy_func;
			delete this.xhr;
		}
		this.busy=false;
		this.curRequest=null;
	},
	abortRequest:function(req_seq) {
		if (this.curRequest) {
			if (this.curRequest.__sequence==req_seq) {
				if (this.xhr) this.xhr.abort();
				this.deleteXHR();
				window.setTimeout(this.do_request.bind(this),0); // for mozilla bug  https://bugzilla.mozilla.org/show_bug.cgi?id=317600
			}
		}
		this.queue.remove(req_seq);
	},
	do_request:function() {
		var request;
		if (this.busy==true) return;
		if (this.queue) {
			request=this.queue.pop();
			if (!request) return;
		} else return;
		this.deleteXHR();
		this.curRequest=request;
		this.busy=true;
		this.xhr=swaf._ajax.createXMLHTTPRequest();

		var requestHeaders=(request.headers)?swaf._ajax.requestHeaders.concat(request.headers):swaf._ajax.requestHeaders.copy();
		var parameter=(request.parameter? ((typeof request.parameter=='string') ?request.parameter:swaf.ext.Object.toQueryString(request.parameter)) : '');
		var url=request.url;
		if (request.method=='get' && parameter.length>0) {
			url+=(url.match(/\?/) ? '&' : '?') + parameter;
		}
		if (swaf._ajax.addAjaxSequence==true) {
			if (url.indexOf('?')==-1) url+='?swaf_ajaxseq='+request.__sequence;
			else url+='&swaf_ajaxseq='+request.__sequence;
		}

		this.xhr.open(request.method,url,true);
		this.xhr.onreadystatechange=this.callbackAjax.bind(this);
		
		if (request.method=='post') {
			requestHeaders.push('Content-type','application/x-www-form-urlencoded');
		}
		if (this.xhr.overrideMimeType) requestHeaders.push('Connection', 'close');		// Mozilla Bugzilla #246651 대응
		for(var i=0;i<requestHeaders.length;i+=2) {
			this.xhr.setRequestHeader(requestHeaders[i],requestHeaders[i+1]);
		}
		this.xhr.send(request.method=='post'?parameter:'');
		request=null;
	},
	callbackAjax:function() {
		if (this.xhr.readyState==4) {	// ajax complete
			var response=new swaf.ajax.Response(this.xhr,this.curRequest.doctype,null,this.curRequest.owner);
			if (this.curRequest.callback) {
				this.curRequest.callbackParameter[0]=response;
				if (swaf._ajax.ajaxDebug==true) {
					this.curRequest.callback.apply(this.curRequest.owner,this.curRequest.callbackParameter);
				} else {
					try {
						this.curRequest.callback.apply(this.curRequest.owner,this.curRequest.callbackParameter);
					} catch(err) {
						swaf.debug.outputDebugLn('Ajax Callback Handler Exception!<br>'+swaf.debug.dumpObject(err,'<br>')+'<br>request url : '+this.curRequest.url+'<br>response status : '+response.getStatus()+' - '+response.getStatusText()+'<br>response data : <br>'+response.getText());
					}
				}
			}
			response=null;
			this.deleteXHR();
			this.do_request();
		}
	}
}});


swaf.$class({Request:
{
	NAMESPACE:swaf.ajax,
	/////////////////////////
	url:null,
	method:'get',
	doctype:'XML',
	parameter:null,
	async:true,
	userid:null,
	password:null,
	owner:null,
	callbackParameter:[null],	// 2006.11.1
	request_sequence:null, // 2006.12.5
	init:function(method,doctype,async) {
		// local variable
		this.onComplete=swaf.dummy._swaf_ajax_dummy_func;
		this.method=method?method.toLowerCase():'get';
		this.doctype=doctype||'XML';
		this.async=(typeof async!='undefined')?async:true;		
	},
	setUrl:function(url) {
		this.url=url;
	},
	getUrl:function() { return this.url;},
	setOwner:function(owner) {
		this.owner=owner;
	},
	getOwner:function() {
		return this.owner;
	},
	setMethod:function(method) {
		this.method=method;
	},
	getMethod:function() {
		return this.method;
	},
	setDocType:function(doctype) {
		this.doctype=doctype;
	},
	getDocType:function() {
		return this.doctype;
	},
	setAsync:function(async) {
		this.async=async;
	},
	getAsync:function() {
		return this.async;
	},
	setParameter:function(parameter) {
		this.parameter=parameter;
	},
	getParameter:function() {
		return this.parameter;
	},
	setRequestHeader:function(arrHeaders) {
		if (!this.requestHeaders) this.requestHeaders=arrHeaders;
		else this.requestHeaders=this.requestHeaders.concat(arrHeaders);
	},
	getRequestHeader:function() {
		return this.requestHeaders;
	},
	setCallbackHandler:function(fn) {
		this.onComplete=fn;
	},
	getCallbackHandler:function() {
		return this.onComplete;
	},
	setCallbackParameter:function() {
		this.callbackParameter=this.callbackParameter.concat(swaf.$A(arguments));
	},
	request:function() {
	// { url, parameter, method, userid, password, doctype, owner, callback, callbackParameter, headers}
		var request={url:this.url, parameter:this.parameter,method:this.method,/*userid:this.userid,password:this.password,*/doctype:this.doctype,owner:this.owner||window,callback:this.onComplete,callbackParameter:this.callbackParameter,headers:this.requestHeaders};
		this.request_sequence=swaf._ajax.push_request(request);
		request=null;
	},
	abort:function() {
		swaf._ajax.abortRequest(this.request_sequence);
	}
}});

swaf.$class({Response:
{
	NAMESPACE:swaf.ajax,
	/////////////////////////
	xhr:null,
	doctype:null,
	option:null,
	value:null,
	owner:null,
	recvtext:null,				// 2007.1.9
	// 2007.1.9.. srctext 추가
	init:function(xhr,doctype,option,owner,srctext) {
		this.xhr=xhr;
		var readyState=xhr.readyState;
		var status=xhr.status;
		this.doctype=doctype;
		this.option=option;
		this.owner=owner;
		this.recvtext=srctext;
		if (!this.isSuccess() && !srctext) {
			this.value=null;
			return;
		}
		switch(doctype.toUpperCase()) {
			case 'JSON' :
				this.value=this.evalResult();
				break;
			case 'XML' :
				this.value=this.getXML();
				break;
			case 'HTML' :
				this.value=this.getText();
				break;
			case 'JS' :
				this.value=this.applyScript();
				break;
			case 'TEXT' :
				this.value=this.getText().escapeHTML();
				break;
		}
	},
	isSuccess:function() {
		return (this.xhr.status==undefined || this.xhr.status==0 || (this.xhr.status>=200 && this.xhr.status<300));
	},
	getHeader:function(name) {
		return this.xhr.getResponseHeader(name);
	},
	getDocType:function() {
		return this.doctype;
	},
	getOwner:function() {
		return this.owner;
	},
	getXML:function() {
		if (this.recvtext) {
			return swaf.xml(this.recvtext);
		} else if (this.xhr) {
			return swaf.xml(this.xhr.responseXML);
		}
	},
	getText:function() {
		if (this.recvtext) {
			return this.recvtext;
		} else if (this.xhr) {
			return (this.xhr.responseText);
		}
	},
	evalResult:function() {
		var ret;
		if (swaf._ajax.ajaxDebug==true) {
			ret=eval('('+this.getText()+')');
		} else {
			try {
				ret=eval('('+this.getText()+')');
			} catch(e) {
				swaf.debug.outputDebugLn('Evaluation failed! '+swaf.debug.dumpObject(e,'<br>')+'<br>Received data :<br>'+this.getText());
			}
		}
		return ret;
	},
	applyScript:function() {
		return this.getText().evalScripts();
	},
	updateHTML:function(element,initFunction) {
		var swafLoad=null;
		
		var objectnm=swaf._ajax.getAjaxObject();

		var html=this.getText().replace(swaf._ajax.regexp_local,'swaf._ajax.ajaxobjpool.'+objectnm);
		
		element.innerHTML=html;
		
		var script=html.extractScripts();
		if (script) {
			for(var i=0;i<script.length;i++) {
				var tmparr=script[i].match(swaf._ajax.regexp_load1);
				if (tmparr) {
					swafLoad=tmparr[0].replace(swaf._ajax.regexp_load2,'');
					swafLoad=swafLoad.replace(';','');
				}
				script[i]=script[i].replace(swaf._ajax.regexp_load3,'');
			} // for
			for(var i=0;i<script.length;i++) eval(script[i]);
		}

		if (swafLoad) eval(swafLoad+'()');
		
		if (initFunction) eval(initFunction+'()');	// 2006.11.6
	},
	updateIFrame:function(element) {
		swaf.iframe.setHTML(element,this.getText());
	},
	getStatus:function() {
		return this.xhr.status;
	},
	getStatusText:function() {
		return this.xhr.statusText;
	}
}});

swaf.ajax.Response.prototype.toString=function() { return this.getText();};


swaf._ajax.initAjax();
swaf.listener(window,'unload',swaf._ajax.destroyAjax,swaf._ajax);

if (typeof $ajax == 'undefined') var $ajax=swaf.ajax;

swaf._ajax._swaf_ajaxHTML_callback=function(response,element) {
    response.updateHTML(element);
    element=null;
    response=null;
};

swaf.ajaxHTML=function(url,option) {
	var opt=option || {
		method : 'get',
		async : true,
		parameter : null,
		element : null
	}; 
	if (!opt.element) return null;
	
    $extend(opt,{
	    type : 'HTML',
	    cbHandler : swaf._ajax._swaf_ajaxHTML_callback,
	    cbParameter : [opt.element]
	});
	return $ajax(url,opt);
};

if (typeof $ajaxHTML == 'undefined') var $ajaxHTML=swaf.ajaxHTML;