/*
 * jQuery 1.2.6 - New Wave Javascript
 *
 * Copyright (c) 2008 John Resig (jquery.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
 * $Rev: 5685 $
 */
(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else
return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else
return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else
selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i<max;i++){var option=options[i];if(option.selected){value=jQuery.browser.msie&&!option.attributes.value.specified?option.text:option.value;if(one)return value;values.push(value);}}return values;}else
return(this[0].value||"").replace(/\r/g,"");}return undefined;}if(value.constructor==Number)value+='';return this.each(function(){if(this.nodeType!=1)return;if(value.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,value)>=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else
this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else
return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else
jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i<length;i++)if((options=arguments[i])!=null)for(var name in options){var src=target[name],copy=options[name];if(target===copy)continue;if(deep&&copy&&typeof copy=="object"&&!copy.nodeType)target[name]=jQuery.extend(deep,src||(copy.length!=null?[]:{}),copy);else if(copy!==undefined)target[name]=copy;}return target;};var expando="jQuery"+now(),uuid=0,windowData={},exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i,defaultView=document.defaultView||{};jQuery.extend({noConflict:function(deep){window.$=_$;if(deep)window.jQuery=_jQuery;return jQuery;},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/^[\s[]?function/.test(fn+"");},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;},globalEval:function(data){data=jQuery.trim(data);if(data){var head=document.getElementsByTagName("head")[0]||document.documentElement,script=document.createElement("script");script.type="text/javascript";if(jQuery.browser.msie)script.text=data;else
script.appendChild(document.createTextNode(data));head.insertBefore(script,head.firstChild);head.removeChild(script);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;var id=elem[expando];if(!id)id=elem[expando]=++uuid;if(name&&!jQuery.cache[id])jQuery.cache[id]={};if(data!==undefined)jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?windowData:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id])break;if(!name)jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute)elem.removeAttribute(expando);}delete jQuery.cache[id];}},each:function(object,callback,args){var name,i=0,length=object.length;if(args){if(length==undefined){for(name in object)if(callback.apply(object[name],args)===false)break;}else
for(;i<length;)if(callback.apply(object[i++],args)===false)break;}else{if(length==undefined){for(name in object)if(callback.call(object[name],name,object[name])===false)break;}else
for(var value=object[0];i<length&&callback.call(value,i,value)!==false;value=object[++i]){}}return object;},prop:function(elem,value,type,i,name){if(jQuery.isFunction(value))value=value.call(elem,i);return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(name)?value+"px":value;},className:{add:function(elem,classNames){jQuery.each((classNames||"").split(/\s+/),function(i,className){if(elem.nodeType==1&&!jQuery.className.has(elem.className,className))elem.className+=(elem.className?" ":"")+className;});},remove:function(elem,classNames){if(elem.nodeType==1)elem.className=classNames!=undefined?jQuery.grep(elem.className.split(/\s+/),function(className){return!jQuery.className.has(classNames,className);}).join(" "):"";},has:function(elem,className){return jQuery.inArray(className,(elem.className||elem).toString().split(/\s+/))>-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else
jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i<stack.length;i++)if(color(stack[i])){swap[i]=stack[i].style.display;stack[i].style.display="block";}ret=name=="display"&&swap[stack.length-1]!=null?"none":(computedStyle&&computedStyle.getPropertyValue(name))||"";for(i=0;i<swap.length;i++)if(swap[i]!=null)stack[i].style.display=swap[i];}if(name=="opacity"&&ret=="")ret="1";}else if(elem.currentStyle){var camelCase=name.replace(/\-(\w)/g,function(all,letter){return letter.toUpperCase();});ret=elem.currentStyle[name]||elem.currentStyle[camelCase];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var left=style.left,rsLeft=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;style.left=ret||0;ret=style.pixelLeft+"px";style.left=left;elem.runtimeStyle.left=rsLeft;}}return ret;},clean:function(elems,context){var ret=[];context=context||document;if(typeof context.createElement=='undefined')context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;jQuery.each(elems,function(i,elem){if(!elem)return;if(elem.constructor==Number)elem+='';if(typeof elem=="string"){elem=elem.replace(/(<(\w+)[^>]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+"></"+tag+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!tags.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!tags.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!tags.indexOf("<td")||!tags.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!tags.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf("<table")&&tags.indexOf("<tbody")<0?div.firstChild&&div.firstChild.childNodes:wrap[1]=="<table>"&&tags.indexOf("<tbody")<0?div.childNodes:[];for(var j=tbody.length-1;j>=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else
ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&&notxml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&&notxml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&&notxml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else
while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i<length;i++)if(array[i]===elem)return i;return-1;},merge:function(first,second){var i=0,elem,pos=first.length;if(jQuery.browser.msie){while(elem=second[i++])if(elem.nodeType!=8)first[pos++]=elem;}else
while(elem=second[i++])first[pos++]=elem;return first;},unique:function(array){var ret=[],done={};try{for(var i=0,length=array.length;i<length;i++){var id=jQuery.data(array[i]);if(!done[id]){done[id]=true;ret.push(array[i]);}}}catch(e){ret=array;}return ret;},grep:function(elems,callback,inv){var ret=[];for(var i=0,length=elems.length;i<length;i++)if(!inv!=!callback(elems[i],i))ret.push(elems[i]);return ret;},map:function(elems,callback){var ret=[];for(var i=0,length=elems.length;i<length;i++){var value=callback(elems[i],i);if(value!=null)ret[ret.length]=value;}return ret.concat.apply([],ret);}});var userAgent=navigator.userAgent.toLowerCase();jQuery.browser={version:(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1],safari:/webkit/.test(userAgent),opera:/opera/.test(userAgent),msie:/msie/.test(userAgent)&&!/opera/.test(userAgent),mozilla:/mozilla/.test(userAgent)&&!/(compatible|webkit)/.test(userAgent)};var styleFloat=jQuery.browser.msie?"styleFloat":"cssFloat";jQuery.extend({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing"}});jQuery.each({parent:function(elem){return elem.parentNode;},parents:function(elem){return jQuery.dir(elem,"parentNode");},next:function(elem){return jQuery.nth(elem,2,"nextSibling");},prev:function(elem){return jQuery.nth(elem,2,"previousSibling");},nextAll:function(elem){return jQuery.dir(elem,"nextSibling");},prevAll:function(elem){return jQuery.dir(elem,"previousSibling");},siblings:function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},children:function(elem){return jQuery.sibling(elem.firstChild);},contents:function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}},function(name,fn){jQuery.fn[name]=function(selector){var ret=jQuery.map(this,fn);if(selector&&typeof selector=="string")ret=jQuery.multiFilter(selector,ret);return this.pushStack(jQuery.unique(ret));};});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(){var args=arguments;return this.each(function(){for(var i=0,length=args.length;i<length;i++)jQuery(args[i])[original](this);});};});jQuery.each({removeAttr:function(name){jQuery.attr(this,name,"");if(this.nodeType==1)this.removeAttribute(name);},addClass:function(classNames){jQuery.className.add(this,classNames);},removeClass:function(classNames){jQuery.className.remove(this,classNames);},toggleClass:function(classNames){jQuery.className[jQuery.className.has(this,classNames)?"remove":"add"](this,classNames);},remove:function(selector){if(!selector||jQuery.filter(selector,[this]).r.length){jQuery("*",this).add(this).each(function(){jQuery.event.remove(this);jQuery.removeData(this);});if(this.parentNode)this.parentNode.removeChild(this);}},empty:function(){jQuery(">*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return i<m[3]-0;},gt:function(a,i,m){return i>m[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j<rl;j++){var n=m=="~"||m=="+"?ret[j].nextSibling:ret[j].firstChild;for(;n;n=n.nextSibling)if(n.nodeType==1){var id=jQuery.data(n);if(m=="~"&&merge[id])break;if(!nodeName||n.nodeName.toUpperCase()==nodeName){if(m=="~")merge[id]=true;r.push(n);}if(m=="+")break;}}ret=r;t=jQuery.trim(t.replace(re,""));foundToken=true;}}if(t&&!foundToken){if(!t.indexOf(",")){if(context==ret[0])ret.shift();done=jQuery.merge(done,ret);r=ret=[context];t=" "+t.substr(1,t.length);}else{var re2=quickID;var m=re2.exec(t);if(m){m=[0,m[2],m[3],m[1]];}else{re2=quickClass;m=re2.exec(t);}m[2]=m[2].replace(/\\/g,"");var elem=ret[ret.length-1];if(m[1]=="#"&&elem&&elem.getElementById&&!jQuery.isXMLDoc(elem)){var oid=elem.getElementById(m[2]);if((jQuery.browser.msie||jQuery.browser.opera)&&oid&&typeof oid.id=="string"&&oid.id!=m[2])oid=jQuery('[@id="'+m[2]+'"]',elem)[0];ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[];}else{for(var i=0;ret[i];i++){var tag=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];if(tag=="*"&&ret[i].nodeName.toLowerCase()=="object")tag="param";r=jQuery.merge(r,ret[i].getElementsByTagName(tag));}if(m[1]==".")r=jQuery.classFilter(r,m[2]);if(m[1]=="#"){var tmp=[];for(var i=0;r[i];i++)if(r[i].getAttribute("id")==m[2]){tmp=[r[i]];break;}r=tmp;}ret=r;}t=t.replace(re2,"");}}if(t){var val=jQuery.filter(t,r);ret=r=val.r;t=jQuery.trim(val.t);}}if(t)ret=[];if(ret&&context==ret[0])ret.shift();done=jQuery.merge(done,ret);return done;},classFilter:function(r,m,not){m=" "+m+" ";var tmp=[];for(var i=0;r[i];i++){var pass=(" "+r[i].className+" ").indexOf(m)>=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i<rl;i++){var a=r[i],z=a[jQuery.props[m[2]]||m[2]];if(z==null||/href|src|selected/.test(m[2]))z=jQuery.attr(a,m[2])||'';if((type==""&&!!z||type=="="&&z==m[5]||type=="!="&&z!=m[5]||type=="^="&&z&&!z.indexOf(m[5])||type=="$="&&z.substr(z.length-m[5].length)==m[5]||(type=="*="||type=="~=")&&z.indexOf(m[5])>=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i<rl;i++){var node=r[i],parentNode=node.parentNode,id=jQuery.data(parentNode);if(!merge[id]){var c=1;for(var n=parentNode.firstChild;n;n=n.nextSibling)if(n.nodeType==1)n.nodeIndex=c++;merge[id]=true;}var add=false;if(first==0){if(node.nodeIndex==last)add=true;}else if((node.nodeIndex-last)%first==0&&(node.nodeIndex-last)/first>=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else
for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i<args.length)jQuery.event.proxy(fn,args[i++]);return this.click(jQuery.event.proxy(fn,function(event){this.lastToggle=(this.lastToggle||0)%i;event.preventDefault();return args[this.lastToggle++].apply(this,arguments)||false;}));},hover:function(fnOver,fnOut){return this.bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else
jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.call(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i<document.styleSheets.length;i++)if(document.styleSheets[i].disabled){setTimeout(arguments.callee,0);return;}jQuery.ready();},false);if(jQuery.browser.safari){var numStyles;(function(){if(jQuery.isReady)return;if(document.readyState!="loaded"&&document.readyState!="complete"){setTimeout(arguments.callee,0);return;}if(numStyles===undefined)numStyles=jQuery("style, link[rel=stylesheet]").length;if(document.styleSheets.length!=numStyles){setTimeout(arguments.callee,0);return;}jQuery.ready();})();}jQuery.event.add(window,"load",jQuery.ready);}jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,"+"mousedown,mouseup,mousemove,mouseover,mouseout,change,select,"+"submit,keydown,keypress,keyup,error").split(","),function(i,name){jQuery.fn[name]=function(fn){return fn?this.bind(name,fn):this.trigger(name);};});var withinElement=function(event,elem){var parent=event.relatedTarget;while(parent&&parent!=elem)try{parent=parent.parentNode;}catch(error){parent=elem;}return parent==elem;};jQuery(window).bind("unload",function(){jQuery("*").add(document).unbind();});jQuery.fn.extend({_load:jQuery.fn.load,load:function(url,params,callback){if(typeof url!='string')return this._load(url);var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else
xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else
jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else
for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else
s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else
e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length){clearInterval(jQuery.timerId);jQuery.timerId=null;}},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=now();if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})();
/** 
 * x.js compiled from X 4.0 with XC 0.27b. 
 * Distributed by GNU LGPL. For copyrights, license, documentation and more visit Cross-Browser.com 
 * Copyright 2001-2005 Michael Foster (Cross-Browser.com)
 **/

var xOp7Up,xOp6Dn,xIE4Up,xIE4,xIE5,xIE6,xNN4,xUA=navigator.userAgent.toLowerCase();
if(window.opera){
  var i=xUA.indexOf('opera');
  if(i!=-1){
    var v=parseInt(xUA.charAt(i+6));
    xOp7Up=v>=7;
    xOp6Dn=v<7;
  }
}
else if(navigator.vendor!='KDE' && document.all && xUA.indexOf('msie')!=-1){
  xIE4Up=parseFloat(navigator.appVersion)>=4;
  xIE4=xUA.indexOf('msie 4')!=-1;
  xIE5=xUA.indexOf('msie 5')!=-1;
  xIE6=xUA.indexOf('msie 6')!=-1;
}
else if(document.layers){xNN4=true;}
var xMac=xUA.indexOf('mac')!=-1;
var xFF=xUA.indexOf('firefox')!=-1;

// (element, event(without 'on'), event listener(function name)[, caption])
function xAddEventListener(e,eT,eL,cap)
{
  if(!(e=xGetElementById(e))) return;
  eT=eT.toLowerCase();
  if((!xIE4Up && !xOp7Up) && e==window) {
    if(eT=='resize') { window.xPCW=xClientWidth(); window.xPCH=xClientHeight(); window.xREL=eL; xResizeEvent(); return; }
    if(eT=='scroll') { window.xPSL=xScrollLeft(); window.xPST=xScrollTop(); window.xSEL=eL; xScrollEvent(); return; }
  }
  var eh='e.on'+eT+'=eL';
  if(e.addEventListener) e.addEventListener(eT,eL,cap);
  else if(e.attachEvent) e.attachEvent('on'+eT,eL);
  else eval(eh);
}
// called only from the above
function xResizeEvent()
{
  if (window.xREL) setTimeout('xResizeEvent()', 250);
  var cw = xClientWidth(), ch = xClientHeight();
  if (window.xPCW != cw || window.xPCH != ch) { window.xPCW = cw; window.xPCH = ch; if (window.xREL) window.xREL(); }
}

function xScrollEvent()
{
  if (window.xSEL) setTimeout('xScrollEvent()', 250);
  var sl = xScrollLeft(), st = xScrollTop();
  if (window.xPSL != sl || window.xPST != st) { window.xPSL = sl; window.xPST = st; if (window.xSEL) window.xSEL(); }
}

function xAppendChild(oParent, oChild)
{
  if (oParent.appendChild) return oParent.appendChild(oChild);
  else return null;
}

function xClientHeight()
{
  var h=0;
  if(xOp6Dn) h=window.innerHeight;
  else if(document.compatMode == 'CSS1Compat' && !window.opera && document.documentElement && document.documentElement.clientHeight)
    h=document.documentElement.clientHeight;
  else if(document.body && document.body.clientHeight)
    h=document.body.clientHeight;
  else if(xDef(window.innerWidth,window.innerHeight,document.width)) {
    h=window.innerHeight;
    if(document.width>window.innerWidth) h-=16;
  }
  return h;
}

function xClientWidth()
{
  var w=0;
  if(xOp6Dn) w=window.innerWidth;
  else if(document.compatMode == 'CSS1Compat' && !window.opera && document.documentElement && document.documentElement.clientWidth)
    w=document.documentElement.clientWidth;
  else if(document.body && document.body.clientWidth)
    w=document.body.clientWidth;
  else if(xDef(window.innerWidth,window.innerHeight,document.height)) {
    w=window.innerWidth;
    if(document.height>window.innerHeight) w-=16;
  }
  return w;
}

function xCreateElement(sTag)
{
  if (document.createElement) return document.createElement(sTag);
  else return null;
}

function xDef()
{
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])=='undefined') return false;}
  return true;
}

function xDeleteCookie(name, path)
{
  if (xGetCookie(name)) {
    document.cookie = name + "=" +
                    "; path=" + ((!path) ? "/" : path) +
                    "; expires=" + new Date(0).toGMTString();
  }
}

function xDisplay(e,s)
{
  if(!(e=xGetElementById(e))) return null;
  if(e.style && xDef(e.style.display)) {
    if (xStr(s)) e.style.display = s;
    return e.style.display;
  }
  return null;
}

function xEvent(evt) // object prototype
{
  var e = evt || window.event;
  if(!e) return;
  if(e.type) this.type = e.type;
  if(e.target) this.target = e.target;
  else if(e.srcElement) this.target = e.srcElement;

  // Section B
  if (e.relatedTarget) this.relatedTarget = e.relatedTarget;
  else if (e.type == 'mouseover' && e.fromElement) this.relatedTarget = e.fromElement;
  else if (e.type == 'mouseout') this.relatedTarget = e.toElement;
  // End Section B

  if(xOp6Dn) { this.pageX = e.clientX; this.pageY = e.clientY; }
  else if(xDef(e.pageX,e.pageY)) { this.pageX = e.pageX; this.pageY = e.pageY; }
  else if(xDef(e.clientX,e.clientY)) { this.pageX = e.clientX + xScrollLeft(); this.pageY = e.clientY + xScrollTop(); }

  // Section A
  if (xDef(e.offsetX,e.offsetY)) {
    this.offsetX = e.offsetX;
    this.offsetY = e.offsetY;
  }
  else if (xDef(e.layerX,e.layerY)) {
    this.offsetX = e.layerX;
    this.offsetY = e.layerY;
  }
  else {
    this.offsetX = this.pageX - xPageX(this.target);
    this.offsetY = this.pageY - xPageY(this.target);
  }
  // End Section A
  
  if (e.keyCode) { this.keyCode = e.keyCode; } // for moz/fb, if keyCode==0 use which
  else if (xDef(e.which) && e.type.indexOf('key')!=-1) { this.keyCode = e.which; }

  this.shiftKey = e.shiftKey;
  this.ctrlKey = e.ctrlKey;
  this.altKey = e.altKey;
}

function xFirstChild(e, t)
{
  var c = e ? e.firstChild : null;
  if (t) while (c && c.nodeName != t) { c = c.nextSibling; }
  else while (c && c.nodeType != 1) { c = c.nextSibling; }
  return c;
}

function xGetBodyWidth() {
  var cw = xClientWidth();
  var sw = window.document.body.scrollWidth;
  return cw>sw?cw:sw;
}

function xGetBodyHeight() {
  var cw = xClientHeight();
  var sw = window.document.body.scrollHeight;
  return cw>sw?cw:sw;
}

function xGetComputedStyle(oEle, sProp, bInt)
{
  var s, p = 'undefined';
  var dv = document.defaultView;
  if(dv && dv.getComputedStyle){
    s = dv.getComputedStyle(oEle,'');
    if (s) p = s.getPropertyValue(sProp);
  }
  else if(oEle.currentStyle) {
    // convert css property name to object property name for IE
    var a = sProp.split('-');
    sProp = a[0];
    for (var i=1; i<a.length; ++i) {
      c = a[i].charAt(0);
      sProp += a[i].replace(c, c.toUpperCase());
    }   
    p = oEle.currentStyle[sProp];
  }
  else return null;
  return bInt ? (parseInt(p) || 0) : p;
}

function xGetCookie(name)
{
  var value=null, search=name+"=";
  if (document.cookie.length > 0) {
    var offset = document.cookie.indexOf(search);
    if (offset != -1) {
      offset += search.length;
      var end = document.cookie.indexOf(";", offset);
      if (end == -1) end = document.cookie.length;
      value = unescape(document.cookie.substring(offset, end));
    }
  }
  return value;
}

function xGetElementById(e)
{
  if(typeof(e)!='string') return e;
  if(document.getElementById) e=document.getElementById(e);
  else if(document.all) e=document.all[e];
  else e=null;
  return e;
}

function xGetElementsByAttribute(sTag, sAtt, sRE, fn)
{
  var a, list, found = new Array(), re = new RegExp(sRE, 'i');
  list = xGetElementsByTagName(sTag);
  for (var i = 0; i < list.length; ++i) {
    a = list[i].getAttribute(sAtt);
    if (!a) {a = list[i][sAtt];}
    if (typeof(a)=='string' && a.search(re) != -1) {
      found[found.length] = list[i];
      if (fn) fn(list[i]);
    }
  }
  return found;
}

function xGetElementsByClassName(c,p,t,f)
{
  var found = new Array();
  var re = new RegExp('\\b'+c+'\\b', 'i');
  var list = xGetElementsByTagName(t, p);
  for (var i = 0; i < list.length; ++i) {
    if (list[i].className && list[i].className.search(re) != -1) {
      found[found.length] = list[i];
      if (f) f(list[i]);
    }
  }
  return found;
}

function xGetElementsByTagName(t,p)
{
  var list = null;
  t = t || '*';
  p = p || document;
  if (xIE4 || xIE5) {
    if (t == '*') list = p.all;
    else list = p.all.tags(t);
  }
  else if (p.getElementsByTagName) list = p.getElementsByTagName(t);
  return list || new Array();
}

function xGetURLArguments()
{
  var idx = location.href.indexOf('?');
  var params = new Array();
  if (idx != -1) {
    var pairs = location.href.substring(idx+1, location.href.length).split('&');
    for (var i=0; i<pairs.length; i++) {
      nameVal = pairs[i].split('=');
      params[i] = nameVal[1];
      params[nameVal[0]] = nameVal[1];
    }
  }
  return params;
}

function xHeight(e,h)
{
  if(!(e=xGetElementById(e))) return 0;
  if (xNum(h)) {
    if (h<0) h = 0;
    else h=Math.round(h);
  }
  else h=-1;
  var css=xDef(e.style);
  if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    h = xClientHeight();
  }
  else if(css && xDef(e.offsetHeight) && xStr(e.style.height)) {
    if(h>=0) {
      var pt=0,pb=0,bt=0,bb=0;
      if (document.compatMode=='CSS1Compat') {
        var gcs = xGetComputedStyle;
        pt=gcs(e,'padding-top',1);
        if (pt !== null) {
          pb=gcs(e,'padding-bottom',1);
          bt=gcs(e,'border-top-width',1);
          bb=gcs(e,'border-bottom-width',1);
        }
        // Should we try this as a last resort?
        // At this point getComputedStyle and currentStyle do not exist.
        else if(xDef(e.offsetHeight,e.style.height)){
          e.style.height=h+'px';
          pt=e.offsetHeight-h;
        }
      }
      h-=(pt+pb+bt+bb);
      if(isNaN(h)||h<0) return null;
      else e.style.height=h+'px';
    }
    h=e.offsetHeight;
  }
  else if(css && xDef(e.style.pixelHeight)) {
    if(h>=0) e.style.pixelHeight=h;
    h=e.style.pixelHeight;
  }
  return h;
}

function xHex(sn, digits, prefix)
{
  var p = '';
  var n = Math.ceil(sn);
  if (prefix) p = prefix;
  n = n.toString(16);
  for (var i=0; i < digits - n.length; ++i) {
    p += '0';
  }
  return p + n;
}

function xHide(e){return xVisibility(e,0);}

function xInnerHtml(e,h)
{
  if(!(e=xGetElementById(e)) || !xStr(e.innerHTML)) return null;
  var s = e.innerHTML;
  if (xStr(h)) {e.innerHTML = h;}
  return s;
}

function xLeft(e, iX)
{
  if(!(e=xGetElementById(e))) return 0;
  var css=xDef(e.style);
  if (css && xStr(e.style.left)) {
    if(xNum(iX)) e.style.left=iX+'px';
    else {
      iX=parseInt(e.style.left);
      if(isNaN(iX)) iX=0;
    }
  }
  else if(css && xDef(e.style.pixelLeft)) {
    if(xNum(iX)) e.style.pixelLeft=iX;
    else iX=e.style.pixelLeft;
  }
  return iX;
}

function xMoveTo(e,x,y)
{
  xLeft(e,x);
  xTop(e,y);
}

function xName(e)
{
  if (!e) return e;
  else if (e.id && e.id != "") return e.id;
  else if (e.name && e.name != "") return e.name;
  else if (e.nodeName && e.nodeName != "") return e.nodeName;
  else if (e.tagName && e.tagName != "") return e.tagName;
  else return e;
}

function xNextSib(e,t)
{
  var s = e ? e.nextSibling : null;
  if (t) while (s && s.nodeName != t) { s = s.nextSibling; }
  else while (s && s.nodeType != 1) { s = s.nextSibling; }
  return s;
}

function xNum()
{
  for(var i=0; i<arguments.length; ++i){if(isNaN(arguments[i]) || typeof(arguments[i])!='number') return false;}
  return true;
}

function xOffsetLeft(e)
{
  if (!(e=xGetElementById(e))) return 0;
  if (xDef(e.offsetLeft)) return e.offsetLeft;
  else return 0;
}

function xOffsetTop(e)
{
  if (!(e=xGetElementById(e))) return 0;
  if (xDef(e.offsetTop)) return e.offsetTop;
  else return 0;
}

function xPad(s,len,c,left)
{
  if(typeof s != 'string') s=s+'';
  if(left) {for(var i=s.length; i<len; ++i) s=c+s;}
  else {for (i=s.length; i<len; ++i) s+=c;}
  return s;
}

function xPageX(e)
{
  if (!(e=xGetElementById(e))) return 0;
  var x = 0;
  while (e) {
    if (xDef(e.offsetLeft)) x += e.offsetLeft;
    e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
  return x;
}

function xPageY(e)
{
  if (!(e=xGetElementById(e))) return 0;
  var y = 0;
  while (e) {
    if (xDef(e.offsetTop)) y += e.offsetTop;
    e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
//  if (xOp7Up) return y - document.body.offsetTop; // v3.14, temporary hack for opera bug 130324 (reported 1nov03)
  return y;
}

function xParent(e, bNode)
{
  if (!(e=xGetElementById(e))) return null;
  var p=null;
  if (!bNode && xDef(e.offsetParent)) p=e.offsetParent;
  else if (xDef(e.parentNode)) p=e.parentNode;
  else if (xDef(e.parentElement)) p=e.parentElement;
  return p;
}

function xPreventDefault(e)
{
  if (e && e.preventDefault) e.preventDefault()
  else if (window.event) window.event.returnValue = false;
}

function xPrevSib(e,t)
{
  var s = e ? e.previousSibling : null;
  if (t) while(s && s.nodeName != t) {s=s.previousSibling;}
  else while(s && s.nodeType != 1) {s=s.previousSibling;}
  return s;
}

function xRemoveEventListener(e,eT,eL,cap)
{
  if(!(e=xGetElementById(e))) return;
  eT=eT.toLowerCase();
  if((!xIE4Up && !xOp7Up) && e==window) {
    if(eT=='resize') { window.xREL=null; return; }
    if(eT=='scroll') { window.xSEL=null; return; }
  }
  var eh='e.on'+eT+'=null';
  if(e.removeEventListener) e.removeEventListener(eT,eL,cap);
  else if(e.detachEvent) e.detachEvent('on'+eT,eL);
  else eval(eh);
}

function xResizeTo(e,w,h)
{
  xWidth(e,w);
  xHeight(e,h);
}

function xScrollLeft(e, bWin)
{
  var offset=0;
  if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    var w = window;
    if (bWin && e) w = e;
    if(w.document.documentElement && w.document.documentElement.scrollLeft) offset=w.document.documentElement.scrollLeft;
    else if(w.document.body && xDef(w.document.body.scrollLeft)) offset=w.document.body.scrollLeft;
  }
  else {
    e = xGetElementById(e);
    if (e && xNum(e.scrollLeft)) offset = e.scrollLeft;
  }
  return offset;
}

function xScrollTop(e, bWin)
{
  var offset=0;
  if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    var w = window;
    if (bWin && e) w = e;
    if(w.document.documentElement && w.document.documentElement.scrollTop) offset=w.document.documentElement.scrollTop;
    else if(w.document.body && xDef(w.document.body.scrollTop)) offset=w.document.body.scrollTop;
  }
  else {
    e = xGetElementById(e);
    if (e && xNum(e.scrollTop)) offset = e.scrollTop;
  }
  return offset;
}

function xSetCookie(name, value, expire, path)
{
  document.cookie = name + "=" + escape(value) +
                    ((!expire) ? "" : ("; expires=" + expire.toGMTString())) +
                    "; path=" + ((!path) ? "/" : path);
}

function xShow(e) {return xVisibility(e,1);}


function xStr(s)
{
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])!='string') return false;}
  return true;
}

function xTop(e, iY)
{
  if(!(e=xGetElementById(e))) return 0;
  var css=xDef(e.style);
  if(css && xStr(e.style.top)) {
    if(xNum(iY)) e.style.top=iY+'px';
    else {
      iY=parseInt(e.style.top);
      if(isNaN(iY)) iY=0;
    }
  }
  else if(css && xDef(e.style.pixelTop)) {
    if(xNum(iY)) e.style.pixelTop=iY;
    else iY=e.style.pixelTop;
  }
  return iY;
}

function xVisibility(e, bShow)
{
  if(!(e=xGetElementById(e))) return null;
  if(e.style && xDef(e.style.visibility)) {
    if (xDef(bShow)) e.style.visibility = bShow ? 'visible' : 'hidden';
    return e.style.visibility;
  }
  return null;
}

function xWidth(e,w)
{
  if(!(e=xGetElementById(e))) return 0;
  if (xNum(w)) {
    if (w<0) w = 0;
    else w=Math.round(w);
  }
  else w=-1;
  var css=xDef(e.style);
  if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    w = xClientWidth();
  }
  else if(css && xDef(e.offsetWidth) && xStr(e.style.width)) {
    if(w>=0) {
      var pl=0,pr=0,bl=0,br=0;
      if (document.compatMode=='CSS1Compat') {
        var gcs = xGetComputedStyle;
        pl=gcs(e,'padding-left',1);
        if (pl !== null) {
          pr=gcs(e,'padding-right',1);
          bl=gcs(e,'border-left-width',1);
          br=gcs(e,'border-right-width',1);
        }
        // Should we try this as a last resort?
        // At this point getComputedStyle and currentStyle do not exist.
        else if(xDef(e.offsetWidth,e.style.width)){
          e.style.width=w+'px';
          pl=e.offsetWidth-w;
        }
      }
      w-=(pl+pr+bl+br);
      if(isNaN(w)||w<0) return null;
      else e.style.width=w+'px';
    }
    w=e.offsetWidth;
  }
  else if(css && xDef(e.style.pixelWidth)) {
    if(w>=0) e.style.pixelWidth=w;
    w=e.style.pixelWidth;
  }
  return w;
}

function xZIndex(e,uZ)
{
  if(!(e=xGetElementById(e))) return 0;
  if(e.style && xDef(e.style.zIndex)) {
    if(xNum(uZ)) e.style.zIndex=uZ;
    uZ=parseInt(e.style.zIndex);
  }
  return uZ;
}

function xStopPropagation(evt)
{
  if (evt && evt.stopPropagation) evt.stopPropagation();
  else if (window.event) window.event.cancelBubble = true;
}


/**
 * @file common.js
 * @author zero (zero@nzeo.com)
 * @brief 몇가지 유용한 & 기본적으로 자주 사용되는 자바스크립트 함수들 모음
 **/

/* jQuery 참조변수($) 제거 */
if(jQuery) jQuery.noConflict();

;(function($) {
    /**
     * @brief XE 공용 유틸리티 함수
     * @namespace XE
     */
    window.XE = {
        loaded_popup_menus : new Array(),
        addedDocument : new Array(),
        /**
         * @brief 특정 name을 가진 체크박스들의 checked 속성 변경
         * @param [itemName='cart',][options={}]
         */
        checkboxToggleAll : function() {
            var itemName='cart';
            var options = {
                wrap : null,
                checked : 'toggle',
                doClick : false
            };

            switch(arguments.length) {
                case 1:
                    if(typeof(arguments[0]) == "string") {
                        itemName = arguments[0];
                    } else {
                        $.extend(options, arguments[0] || {});
                    }
                    break;
                case 2:
                    itemName = arguments[0];
                    $.extend(options, arguments[1] || {});
            }

            if(options.doClick == true) options.checked = null;
            if(typeof(options.wrap) == "string") options.wrap ='#'+options.wrap;

            if(options.wrap) {
                var obj = $(options.wrap).find('input[name='+itemName+']:checkbox');
            } else {
                var obj = $('input[name='+itemName+']:checkbox');
            }

            if(options.checked == 'toggle') {
                obj.each(function() {
                    $(this).attr('checked', ($(this).attr('checked')) ? false : true);
                });
            } else {
                (options.doClick == true) ? obj.click() : obj.attr('checked', options.checked);
            }
        },

        /**
         * @brief 문서/회원 등 팝업 메뉴 출력
         */
        displayPopupMenu : function(ret_obj, response_tags, params) {
            var target_srl = params["target_srl"];
            var menu_id = params["menu_id"];
            var menus = ret_obj['menus'];
            var html = "";

            if(this.loaded_popup_menus[menu_id]) {
                html = this.loaded_popup_menus[menu_id];

            } else {
                if(menus) {
                    var item = menus['item'];
                    if(typeof(item.length)=='undefined' || item.length<1) item = new Array(item);
                    if(item.length) {
                        for(var i=0;i<item.length;i++) {
                            var url = item[i].url;
                            var str = item[i].str;
                            var icon = item[i].icon;
                            var target = item[i].target;

                            var styleText = "";
                            var click_str = "";
                            if(icon) styleText = " style=\"background-image:url('"+icon+"')\" ";
                            switch(target) {
                                case "popup" :
                                        click_str = " onclick=\"popopen(this.href,'"+target+"'); return false;\"";
                                    break;
                                case "self" :
                                        //click_str = " onclick=\"location.href='"+url+"' return false;\"";
                                    break;
                                case "javascript" :
                                        click_str = " onclick=\""+url+"; return false; \"";
                                        url="#";
                                    break;
                                default :
                                        click_str = " onclick=\"window.open(this.href); return false;\"";
                                    break;
                            }

                            html += '<li '+styleText+'><a href="'+url+'"'+click_str+'>'+str+'</a></li> ';
                        }
                    }
                }
                this.loaded_popup_menus[menu_id] =  html;
            }

            /* 레이어 출력 */
            if(html) {
                var area = jQuery("#popup_menu_area").html('<ul>'+html+'</ul>');
                var areaOffset = {top:params['page_y'], left:params['page_x']};

                if(area.outerHeight()+areaOffset.top > jQuery(window).height()+jQuery(window).scrollTop())
                    areaOffset.top = jQuery(window).height() - area.outerHeight() + jQuery(window).scrollTop();
                if(area.outerWidth()+areaOffset.left > jQuery(window).width()+jQuery(window).scrollLeft())
                    areaOffset.left = jQuery(window).width() - area.outerWidth() + jQuery(window).scrollLeft();

                if($.browser.safari) {
                    areaOffset.top -= 16;
                    areaOffset.left -= 16;
                }

                area.css({ visibility:"visible", top:areaOffset.top, left:areaOffset.left });
            }
        }
    }

}) (jQuery);

/* jQuery(document).ready() */
jQuery(function($) {
    /* 팝업메뉴 레이어 생성 */
    if(!$('#popup_menu_area').length) {
        var menuObj = $('<div>')
            .attr('id', 'popup_menu_area')
            .css({visibility:'hidden', zIndex:9999});
        $(document.body).append(menuObj);
    }

    $(document).click(function(evt) {
        var area = jQuery("#popup_menu_area");
        if(!area.length) return;

        // 이전에 호출되었을지 모르는 팝업메뉴 숨김
        area.css('visibility', 'hidden');

        var targetObj = $(evt.target);
        if(!targetObj.length) return;

        // obj의 nodeName이 div나 span이 아니면 나올대까지 상위를 찾음
        if(targetObj.length && jQuery.inArray(targetObj.attr('nodeName'), ['DIV', 'SPAN', 'A']) == -1) targetObj = targetObj.parent();
        if(!targetObj.length || jQuery.inArray(targetObj.attr('nodeName'), ['DIV', 'SPAN', 'A']) == -1) return;

        // 객체의 className값을 구함
        var class_name = targetObj.attr('className');
        if(class_name.indexOf('_') <= 0) return;
        // className을 분리
        var class_name_list = class_name.split(' ');

        var menu_id = '';
        var menu_id_regx = /^([a-zA-Z]+)_([0-9]+)$/;


        for(var i = 0, c = class_name_list.length; i < c; i++) {
            if(menu_id_regx.test(class_name_list[i])) {
                menu_id = class_name_list[i];
            }
        }

        if(!menu_id) return;

        // module명과 대상 번호가 없으면 return
        var tmp_arr = menu_id.split('_');
        var module_name = tmp_arr[0];
        var target_srl = tmp_arr[1];
        if(!module_name || !target_srl || target_srl < 1) return;

        // action이름을 규칙에 맞게 작성
        var action_name = "get" + module_name.substr(0,1).toUpperCase() + module_name.substr(1,module_name.length-1) + "Menu";

        // 서버에 메뉴를 요청
        var params = new Array();
        params["target_srl"] = target_srl;
        params["cur_mid"] = current_mid;
        params["cur_act"] = current_url.getQuery('act');
        params["menu_id"] = menu_id;
        params["page_x"] = evt.pageX;
        params["page_y"] = evt.pageY;

        var response_tags = new Array("error","message","menus");

        if(typeof(XE.loaded_popup_menus[menu_id]) != 'undefined') {
            XE.displayPopupMenu(params, response_tags, params);
            return;
        }
        show_waiting_message = false;
        exec_xml(module_name, action_name, params, XE.displayPopupMenu, response_tags, params);
        show_waiting_message = true;
    });

    /* select - option의 disabled=disabled 속성을 IE에서도 체크하기 위한 함수 */
    if($.browser.msie) {
        $('select').each(function(i, sels) {
            var disabled_exists = false;
            var first_enable = new Array();

            for(var j=0; j < sels.options.length; j++) {
                if(sels.options[j].disabled) {
                    sels.options[j].style.color = '#CCCCCC';
                    disabled_exists = true;
                }else{
                    first_enable[i] = (first_enable[i] > -1) ? first_enable[i] : j;
                }
            }

            if(!disabled_exists) return;

            sels.oldonchange = sels.onchange;
            sels.onchange = function() {
                if(this.options[this.selectedIndex].disabled) {

                    this.selectedIndex = first_enable[i];
                    /*
                    if(this.options.length<=1) this.selectedIndex = -1;
                    else if(this.selectedIndex < this.options.length - 1) this.selectedIndex++;
                    else this.selectedIndex--;
                    */

                } else {
                    if(this.oldonchange) this.oldonchange();
                }
            };

            if(sels.selectedIndex >= 0 && sels.options[ sels.selectedIndex ].disabled) sels.onchange();

        });
    }
});

/*
 * jQuery 1.2.6
 * Opera 브라우저에서 $(window).height() / width() 값을 잘못 가져오는 문제 수정
 * jQuery 1.3에서 수정되었음
 * @link http://dev.jquery.com/changeset/5938
 */
if(jQuery.fn.jquery == '1.2.6') {
    jQuery.each([ "Height", "Width" ], function(i, name){
        var type = name.toLowerCase();

        jQuery.fn[ type ] = function( size ) {
            return this[0] == window ?
                // Opera 브라우저에서 $(window).height() / width() 값을 잘못 가져오는 문제 수정
                jQuery.browser.opera  && document.body.parentNode[ "client" + name ] ||

                jQuery.browser.safari && window[ "inner" + name ] ||
                document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :

                this[0] == document ?
                    Math.max(
                        Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
                        Math.max(document.body["offset" + name], document.documentElement["offset" + name])
                    ) :

                    size == undefined ?
                        (this.length ? jQuery.css( this[0], type ) : null) :
                        this.css( type, size.constructor == String ? size : size + "px" );
        };
    });
}



/**
 * @brief location.href에서 특정 key의 값을 return
 **/
String.prototype.getQuery = function(key) {
    var idx = this.indexOf('?');
    if(idx == -1) return null;
    var query_string = this.substr(idx+1, this.length);
    var args = {};
    query_string.replace(/([^=]+)=([^&]*)(&|$)/g, function() { args[arguments[1]] = arguments[2]; });

    var q = args[key];
    if(typeof(q)=="undefined") q = "";

    return q;
}

/**
 * @brief location.href에서 특정 key의 값을 return
 **/
String.prototype.setQuery = function(key, val) {
    var idx = this.indexOf('?');
    var uri = this;
    uri = uri.replace(/#$/,'');

    if(idx != -1) {
        uri = this.substr(0, idx);
        var query_string = this.substr(idx+1, this.length);
        var args = new Array();
        query_string.replace(/([^=]+)=([^&]*)(&|$)/g, function() { args[arguments[1]] = arguments[2]; });

        args[key] = val;

        var q_list = new Array();
        for(var i in args) {
        if( !args.hasOwnProperty(i) ) continue;
            var arg = args[i];
            if(!arg.toString().trim()) continue;
            arg = decodeURI(arg);
            q_list[q_list.length] = i+'='+arg;
        }
        uri = uri+"?"+q_list.join("&");
    } else {
        if(val.toString().trim()) uri = uri+"?"+key+"="+val;
    }

    var re = /https:\/\/([^:\/]+)(:\d+|)/i;
    var check = re.exec(uri);
    if(check)
    {
        var toReplace = "http://"+check[1];
        if(typeof(http_port)!='undefined' && http_port != 80)
        {
            toReplace += ":" + http_port;
        }
        uri = uri.replace(re,toReplace);
    }
    var bUseSSL = false;
    if(typeof(enforce_ssl)!='undefined' && enforce_ssl)
    {
        bUseSSL = true;
    }
    else if(typeof(ssl_actions)!='undefined' && typeof(ssl_actions.length)!='undefined' && uri.getQuery('act')) {
        var act = uri.getQuery('act');
        for(i=0;i<ssl_actions.length;i++) {
            if(ssl_actions[i]==act) {
                bUseSSL = true;
                break;
            }
        }
    }

    if(bUseSSL)
    {
        var re = /http:\/\/([^:\/]+)(:\d+|)/i;
        var check = re.exec(uri);
        if(check)
        {
            var toReplace = "https://"+check[1];
            if(typeof(https_port)!='undefined' && https_port != 443)
            {
                toReplace += ":" + https_port;
            }
            uri = uri.replace(re,toReplace);
        }
    }

    return encodeURI(uri);
}

/**
 * @brief string prototype으로 trim 함수 추가
 **/
String.prototype.trim = function() {
    return this.replace(/(^\s*)|(\s*$)/g, "");
}

/**
 * @brief xSleep(micro time)
 **/
function xSleep(sec) {
    sec = sec / 1000;
    var now = new Date();
    var sleep = new Date();
    while( sleep.getTime() - now.getTime() < sec) {
        sleep = new Date();
    }
}

/**
 * @brief 주어진 인자가 하나라도 defined되어 있지 않으면 false return
 **/
function isDef() {
    for(var i=0; i < arguments.length; ++i) {
        if(typeof(arguments[i]) == "undefined") return false;
    }
    return true;
}

/**
 * @brief 윈도우 오픈
 * 열려진 윈도우의 관리를 통해 window.focus()등을 FF에서도 비슷하게 구현함
 **/
var winopen_list = new Array();
function winopen(url, target, attribute) {
    try {
        if(target != "_blank" && winopen_list[target]) {
            winopen_list[target].close();
            winopen_list[target] = null;
        }
    } catch(e) {
    }

    if(typeof(target) == 'undefined') target = '_blank';
    if(typeof(attribute) == 'undefined') attribute = '';
    var win = window.open(url, target, attribute);
    win.focus();
    if(target != "_blank") winopen_list[target] = win;
}

/**
 * @brief 팝업으로만 띄우기
 * common/tpl/popup_layout.html이 요청되는 XE내의 팝업일 경우에 사용
 **/
function popopen(url, target) {
    if(typeof(target) == "undefined") target = "_blank";
    winopen(url, target, "left=10,top=10,width=10,height=10,scrollbars=no,resizable=yes,toolbars=no");
}

/**
 * @brief 메일 보내기용
 **/
function sendMailTo(to) {
    location.href="mailto:"+to;
}

/**
 * @brief url이동 (open_window 값이 N 가 아니면 새창으로 띄움)
 **/
function move_url(url, open_wnidow) {
    if(!url) return false;
    if(typeof(open_wnidow) == 'undefined') open_wnidow = 'N';
    if(open_wnidow=='N') {
        open_wnidow = false;
    } else {
        open_wnidow = true;
    }

    if(/^\./.test(url)) url = request_uri+url;

    if(open_wnidow) {
        winopen(url);
    } else {
        location.href=url;
    }

    return false;
}

/**
 * @brief 멀티미디어 출력용 (IE에서 플래쉬/동영상 주변에 점선 생김 방지용)
 **/
function displayMultimedia(src, width, height, options) {
    if(src.indexOf('files') == 0) src = request_uri + src;

    var defaults = {
        wmode : 'transparent',
        allowScriptAccess : 'sameDomain',
        quality : 'high',
        flashvars : '',
        autostart : false
    };

    var params = jQuery.extend(defaults, options || {});
    var autostart = (params.autostart && params.autostart != 'false') ? 'true' : 'false';
    delete(params.autostart);

    var clsid = "";
    var codebase = "";
    var html = "";

    if(/\.swf/i.test(src)) {
        clsid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
        codebase = "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0";
        html = '<object classid="'+clsid+'" codebase="'+codebase+'" width="'+width+'" height="'+height+'" flashvars="'+params.flashvars+'">';
        html += '<param name="movie" value="'+src+'" />';
        for(var name in params) {
            if(params[name] != 'undefined' && params[name] != '') {
                html += '<param name="'+name+'" value="'+params[name]+'" />';
            }
        }
        html += ''
            + '<embed src="'+src+'" autostart="'+autostart+'"  width="'+width+'" height="'+height+'" flashvars="'+params.flashvars+'" wmode="'+params.wmode+'"></embed>'
            + '</object>';
    } else if(/\.flv/i.test(src) || /\.mov/i.test(src) || /\.moov/i.test(src) || /\.m4v/i.test(src)) {
        html = '<embed src="'+request_uri+'common/tpl/images/flvplayer.swf" allowfullscreen="true" autostart="'+autostart+'" width="'+width+'" height="'+height+'" flashvars="&file='+src+'&width='+width+'&height='+height+'&autostart='+autostart+'" />';
    }  else {
        html = '<embed src="'+src+'" autostart="'+autostart+'" width="'+width+'" height="'+height+'"></embed>';
    }
    document.writeln(html);
}

/**
 * @brief 에디터에서 사용되는 내용 여닫는 코드 (고정, zbxe용)
 **/
function zbxe_folder_open(id) {
    jQuery("#folder_open_"+id).hide();
    jQuery("#folder_close_"+id).show();
    jQuery("#folder_"+id).show();
}
function zbxe_folder_close(id) {
    jQuery("#folder_open_"+id).show();
    jQuery("#folder_close_"+id).hide();
    jQuery("#folder_"+id).hide();
}

/**
 * @brief 팝업의 경우 내용에 맞춰 현 윈도우의 크기를 조절해줌
 * 팝업의 내용에 맞게 크기를 늘리는 것은... 쉽게 되지는 않음.. ㅡ.ㅜ
 * popup_layout 에서 window.onload 시 자동 요청됨.
 **/
function setFixedPopupSize() {
    var bodyObj = jQuery('#popBody');

    if(bodyObj.length) {
        if(bodyObj.height() > 500) {
            bodyObj.css({ overflowY:'scroll', overflowX:'hidden', height:500 });
        }
    }

    var w = jQuery("#popup_content").width();
    var h = jQuery("#popup_content").height();

    jQuery('div').each(function() {
        var ww = jQuery(this).width();
        if(jQuery.inArray(this.id, ['waitingforserverresponse', 'fororiginalimagearea', 'fororiginalimageareabg']) == -1) {
            if(ww > w) w = ww;
        }
    });

    // 윈도우에서는 브라우저 상관없이 가로 픽셀이 조금 더 늘어나야 한다.
    if(navigator.userAgent.toLowerCase().indexOf('windows') > 0) {
        if(jQuery.browser.opera) w += 10;
        else if(jQuery.browser.msie) w += 10;
        else w += 6;
    }
    window.resizeTo(w, h);

    var h1 = jQuery(window).height();
    window.resizeBy(0, h-h1);

    window.scrollTo(0,0);
}

/**
 * @brief 추천/비추천,스크랩,신고기능등 특정 srl에 대한 특정 module/action을 호출하는 함수
 **/
function doCallModuleAction(module, action, target_srl) {
    var params = new Array();
    params['target_srl'] = target_srl;
    params['cur_mid'] = current_mid;
    exec_xml(module, action, params, completeCallModuleAction);
}

function completeCallModuleAction(ret_obj, response_tags) {
    if(ret_obj['message']!='success') alert(ret_obj['message']);
    location.reload();
}

function completeMessage(ret_obj) {
    alert(ret_obj['message']);
    location.reload();
}



/* 언어코드 (lang_type) 쿠키값 변경 */
function doChangeLangType(obj) {
    if(typeof(obj) == "string") {
        setLangType(obj);
    } else {
        var val = obj.options[obj.selectedIndex].value;
        setLangType(val);
    }
    location.reload();
}
function setLangType(lang_type) {
    var expire = new Date();
    expire.setTime(expire.getTime()+ (7000 * 24 * 3600000));
    xSetCookie('lang_type', lang_type, expire);
}

/* 미리보기 */
function doDocumentPreview(obj) {
    var fo_obj = obj;
    while(fo_obj.nodeName != "FORM") {
        fo_obj = fo_obj.parentNode;
    }
    if(fo_obj.nodeName != "FORM") return;
    var editor_sequence = fo_obj.getAttribute('editor_sequence');

    var content = editorGetContent(editor_sequence);

    var win = window.open("", "previewDocument","toolbars=no,width=700px;height=800px,scrollbars=yes,resizable=yes");

    var dummy_obj = jQuery("#previewDocument");

    if(!dummy_obj.length) {
        jQuery(
            '<form id="previewDocument" target="previewDocument" method="post" action="'+request_uri+'">'+
            '<input type="hidden" name="module" value="document" />'+
            '<input type="hidden" name="act" value="dispDocumentPreview" />'+
            '<input type="hidden" name="content" />'+
            '</form>'
        ).appendTo(document.body);

        dummy_obj = jQuery("#previewDocument")[0];
    }

    if(dummy_obj) {
        dummy_obj.content.value = content;
        dummy_obj.submit();
    }
}

/* 게시글 저장 */
function doDocumentSave(obj) {
    var editor_sequence = obj.form.getAttribute('editor_sequence');
    var prev_content = editorRelKeys[editor_sequence]['content'].value;
    if(typeof(editor_sequence)!='undefined' && editor_sequence && typeof(editorRelKeys)!='undefined' && typeof(editorGetContent)=='function') {
        var content = editorGetContent(editor_sequence);
        editorRelKeys[editor_sequence]['content'].value = content;
    }

    var oFilter = new XmlJsFilter(obj.form, "member", "procMemberSaveDocument", completeDocumentSave);
    oFilter.addResponseItem("error");
    oFilter.addResponseItem("message");
    oFilter.addResponseItem("document_srl");
    oFilter.proc();

    editorRelKeys[editor_sequence]['content'].value = prev_content;
    return false;
}

function completeDocumentSave(ret_obj) {
    jQuery('input[name=document_srl]').eq(0).val(ret_obj['document_srl']);
    alert(ret_obj['message']);
}

/* 저장된 게시글 불러오기 */
var objForSavedDoc = null;
function doDocumentLoad(obj) {
    // 저장된 게시글 목록 불러오기
    objForSavedDoc = obj.form;
    popopen(request_uri.setQuery('module','member').setQuery('act','dispSavedDocumentList'));
}

/* 저장된 게시글의 선택 */
function doDocumentSelect(document_srl) {
    if(!opener || !opener.objForSavedDoc) {
        window.close();
        return;
    }

    // 게시글을 가져와서 등록하기
    opener.location.href = opener.current_url.setQuery('document_srl', document_srl).setQuery('act', 'dispBoardWrite');
    window.close();
}


/* 스킨 정보 */
function viewSkinInfo(module, skin) {
    popopen("./?module=module&act=dispModuleSkinInfo&selected_module="+module+"&skin="+skin, 'SkinInfo');
}


/* 관리자가 문서를 관리하기 위해서 선택시 세션에 넣음 */
var addedDocument = new Array();
function doAddDocumentCart(obj) {
    var srl = obj.value;
    addedDocument[addedDocument.length] = srl;
    setTimeout(function() { callAddDocumentCart(addedDocument.length); }, 100);
}

function callAddDocumentCart(document_length) {
    if(addedDocument.length<1 || document_length != addedDocument.length) return;
    var params = new Array();
    params["srls"] = addedDocument.join(",");
    exec_xml("document","procDocumentAdminAddCart", params, null);
    addedDocument = new Array();
}

/* ff의 rgb(a,b,c)를 #... 로 변경 */
function transRGB2Hex(value) {
    if(!value) return value;
    if(value.indexOf('#') > -1) return value.replace(/^#/, '');

    if(value.toLowerCase().indexOf('rgb') < 0) return value;
    value = value.replace(/^rgb\(/i, '').replace(/\)$/, '');
    value_list = value.split(',');

    var hex = '';
    for(var i = 0; i < value_list.length; i++) {
        var color = parseInt(value_list[i], 10).toString(16);
        if(color.length == 1) color = '0'+color;
        hex += color;
    }
    return hex;
}

/* 보안 로그인 모드로 전환 */
function toggleSecuritySignIn() {
    var href = location.href;
    if(/https:\/\//i.test(href)) location.href = href.replace(/^https/i,'http');
    else location.href = href.replace(/^http/i,'https');
}

function reloadDocument() {
    location.reload();
}


/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/

var Base64 = {

    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

    // public method for encoding
    encode : function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;

        input = Base64._utf8_encode(input);

        while (i < input.length) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output = output +
            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

        }

        return output;
    },

    // public method for decoding
    decode : function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;

        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

        while (i < input.length) {

            enc1 = this._keyStr.indexOf(input.charAt(i++));
            enc2 = this._keyStr.indexOf(input.charAt(i++));
            enc3 = this._keyStr.indexOf(input.charAt(i++));
            enc4 = this._keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output = output + String.fromCharCode(chr1);

            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }

        }

        output = Base64._utf8_decode(output);

        return output;

    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }

}






/* ----------------------------------------------
 * DEPRECATED
 * 하위호환용으로 남겨 놓음
 * ------------------------------------------- */

if(typeof(resizeImageContents) == 'undefined') {
    function resizeImageContents() {}
}

if(typeof(activateOptionDisabled) == 'undefined') {
    function activateOptionDisabled() {}
}

objectExtend = jQuery.extend;

/**
 * @brief 특정 Element의 display 옵션 토글
 **/
function toggleDisplay(objId) {
    jQuery('#'+objId).toggle();
}

/* 체크박스 선택 */
function checkboxSelectAll(formObj, name, checked) {
    var itemName = name;
    var option = {};
    if(typeof(formObj) != "undefined") option.wrap = formObj;
    if(typeof(checked) != "undefined") option.checked = checked;

    XE.checkboxToggleAll(itemName, option);
}

/* 체크박스를 실행 */
function clickCheckBoxAll(formObj, name) {
    var itemName = name;
    var option = { doClick:true };
    if(typeof(formObj) != "undefined") option.wrap = formObj;

    XE.checkboxToggleAll(itemName, option);
}

/**
 * @brief 에디터에서 사용하되 내용 여닫는 코드 (zb5beta beta 호환용으로 남겨 놓음)
 **/
function svc_folder_open(id) {
    jQuery("#_folder_open_"+id).hide();
    jQuery("#_folder_close_"+id).show();
    jQuery("#_folder_"+id).show();
}
function svc_folder_close(id) {
    jQuery("#_folder_open_"+id).show();
    jQuery("#_folder_close_"+id).hide();
    jQuery("#_folder_"+id).hide();
}

/**
 * @brief 날짜 선택 (달력 열기)
 **/
function open_calendar(fo_id, day_str, callback_func) {
    if(typeof(day_str)=="undefined") day_str = "";

    var url = "./common/tpl/calendar.php?";
    if(fo_id) url+="fo_id="+fo_id;
    if(day_str) url+="&day_str="+day_str;
    if(callback_func) url+="&callback_func="+callback_func;

    popopen(url, 'Calendar');
}

var loaded_popup_menus = XE.loaded_popup_menus;
function createPopupMenu() {}
function chkPopupMenu() {}
function displayPopupMenu(ret_obj, response_tags, params) {
    XE.displayPopupMenu(ret_obj, response_tags, params);
}

function GetObjLeft(obj) {
    return jQuery(obj).offset().left;
}
function GetObjTop(obj) {
    return jQuery(obj).offset().top;
}

function replaceOuterHTML(obj, html) {
    jQuery(obj).replaceWith(html);
}

function getOuterHTML(obj) {
    return jQuery(obj).html().trim();
}

/**
 * @file   common/js/xml_handler.js
 * @author zero <zero@nzeo.com>
 * @brief  zbxe내에서 ajax기능을 이용함에 있어 module, act를 잘 사용하기 위한 자바스크립트
 **/

// xml handler을 이용하는 user function
var show_waiting_message = true;
function exec_xml(module, act, params, callback_func, response_tags, callback_func_arg, fo_obj) {
    var oXml = new xml_handler();
    oXml.reset();
    if(typeof(params)!='undefined') {
        for(var key in params) {
            if(!params.hasOwnProperty(key)) continue;
            var val = params[key];
            oXml.addParam(key, val);
        }
    }
    oXml.addParam("module", module);
    oXml.addParam("act", act);

    if(typeof(response_tags)=="undefined" || response_tags.length<1) response_tags = new Array('error','message');

    oXml.request(xml_response_filter, oXml, callback_func, response_tags, callback_func_arg, fo_obj);
}

// 결과 처리 후 callback_func에 넘겨줌
function xml_response_filter(oXml, callback_func, response_tags, callback_func_arg, fo_obj) {
    var xmlDoc = oXml.getResponseXml();
    if(!xmlDoc) return null;

    var waiting_obj = xGetElementById("waitingforserverresponse");
    if(waiting_obj) waiting_obj.style.visibility = "hidden";

    var ret_obj = oXml.toZMsgObject(xmlDoc, response_tags);
    if(ret_obj["error"]!=0) {
        alert(ret_obj["message"]);
        return null;
    }

    if(ret_obj["redirect_url"]) {
        location.href=ret_obj["redirect_url"];
        return null;
    }

    if(!callback_func) return null;

    callback_func(ret_obj, response_tags, callback_func_arg, fo_obj);

    return null;
}

// xml handler
function xml_handler() {
    this.objXmlHttp = null;
    this.method_name = null;
    this.xml_path = request_uri+"index.php";

    this.params = new Array();

    this.reset = xml_handlerReset;
    this.getXmlHttp = zGetXmlHttp;
    this.request = xml_handlerRequest;
    this.setPath = xml_handlerSetPath;
    this.addParam = xml_handlerAddParam;
    this.getResponseXml = xml_handlerGetResponseXML;
    this.toZMsgObject = xml_handlerToZMsgObject;
    this.parseXMLDoc = xml_parseXmlDoc;

    this.objXmlHttp = this.getXmlHttp();
}

function zGetXmlHttp() {
    if (window.XMLHttpRequest) return new XMLHttpRequest();
    else if (window.ActiveXObject) {
        try {
            return new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            return new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    return null;
}

function xml_handlerRequest(callBackFunc, xmlObj, callBackFunc2, response_tags, callback_func_arg, fo_obj) {
    var rd = "";
    rd += "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
    +  "<methodCall>\n"
    +  "<params>\n"

    for (var key in this.params) {
        if(!this.params.hasOwnProperty(key)) continue;
        var val = this.params[key];
        rd += "<"+key+"><![CDATA["+val+"]]></"+key+">\n";
    }

    rd += "</params>\n"
    +  "</methodCall>\n";

    // ssl action
    if(typeof(ssl_actions)!='undefined' && typeof(ssl_actions.length)!='undefined' && typeof(this.params['act'])!='undefined' && /^https:\/\//i.test(location.href) ) {
        var action = this.params['act'];
        for(i=0;i<ssl_actions.length;i++) {
            if(ssl_actions[i]==action) {
                this.xml_path = this.xml_path.replace(/^http:\/\//i,'https://');
                break;
            }
        }
    }

    if(this.objXmlHttp.readyState!=0) {
        this.objXmlHttp.abort();
        this.objXmlHttp = this.getXmlHttp();
    }
    this.objXmlHttp.onreadystatechange = function () {callBackFunc(xmlObj, callBackFunc2, response_tags, callback_func_arg, fo_obj)};

    // 모든 xml데이터는 POST방식으로 전송. try-cacht문으로 오류 발생시 대처
    try {

        this.objXmlHttp.open("POST", this.xml_path, true);

    } catch(e) {
        alert(e);
        return;
    }

    // ajax 통신중 대기 메세지 출력 (show_waiting_message값을 false로 세팅시 보이지 않음)
    var waiting_obj = xGetElementById("waitingforserverresponse");
    if(show_waiting_message && waiting_obj) {
        xInnerHtml(waiting_obj, waiting_message);

        xTop(waiting_obj, xScrollTop()+20);
        xLeft(waiting_obj, xScrollLeft()+20);
        waiting_obj.style.visibility = "visible";
    }

    this.objXmlHttp.send(rd);
}

function xml_handlerSetPath(path) {
    this.xml_path = "./"+path;
}


function xml_handlerReset() {
    this.objXmlHttp = this.getXmlHttp();
    this.params = new Array();
}

function xml_handlerAddParam(key, val) {
    this.params[key] = val;
}

function xml_handlerGetResponseXML() {
    if(this.objXmlHttp && this.objXmlHttp.readyState == 4 && isDef(this.objXmlHttp.responseXML)) {
        var xmlDoc = this.objXmlHttp.responseXML;
        this.reset();
        return xmlDoc;
    }
    return null;
}


function xml_parseXmlDoc(dom) {

    if(!dom) return;

    var jsonStr = xml2json(dom,false,false);
    var jsonObj = eval("("+ jsonStr +");");
    return jsonObj.response;
/*

    var ret_obj = new Array();

    var obj = dom.firstChild;
    var preObj;
    if(!obj) return;

    while(obj) {
        if(obj.nodeType == 1) {

            var name = obj.nodeName;
            var value = null;

            if(obj.childNodes.length==1 && obj.firstChild.nodeType != 1) {

                value = obj.firstChild.nodeValue;
            } else {
                value = this.parseXMLDoc(obj);
            }
            if(typeof(ret_obj[name])=='undefined') {
                ret_obj[name] = value;
            } else {
                if(ret_obj[name].length>0) {
                    ret_obj[name][ret_obj[name].length] = value;
                } else {
                    var tmp_value = ret_obj[name];
                    ret_obj[name] = new Array();
                    ret_obj[name][ret_obj[name].length] = tmp_value;
                    ret_obj[name][ret_obj[name].length] = value;
                }
            }

        }
        obj = obj.nextSibling;

    }
    return ret_obj;
*/
}

function xml_handlerToZMsgObject(xmlDoc, tags) {
    if(!xmlDoc) return null;
    if(!tags) tags = new Array("error","message");
    tags[tags.length] = "redirect_url";
    tags[tags.length] = "act";

    var parsed_array = this.parseXMLDoc(xmlDoc.getElementsByTagName('response')[0]);

    var obj_ret = new Array();
    for(var i=0; i<tags.length; i++) {
        var key = tags[i];
        if(parsed_array[key]) obj_ret[key] = parsed_array[key];
        else obj_ret[key] = null;
    }
    return obj_ret;
}



/*  This work is licensed under Creative Commons GNU LGPL License.

    License: http://creativecommons.org/licenses/LGPL/2.1/
   Version: 0.9
    Author:  Stefan Goessner/2006
    Web:     http://goessner.net/
*/
function xml2json(xml, tab, ignoreAttrib) {
   var X = {
      toObj: function(xml) {
         var o = {};
         if (xml.nodeType==1) {   // element node ..
            if (ignoreAttrib && xml.attributes.length)   // element with attributes  ..
               for (var i=0; i<xml.attributes.length; i++)
                  o["@"+xml.attributes[i].nodeName] = (xml.attributes[i].nodeValue||"").toString();
            if (xml.firstChild) { // element has child nodes ..
               var textChild=0, cdataChild=0, hasElementChild=false;
               for (var n=xml.firstChild; n; n=n.nextSibling) {
                  if (n.nodeType==1) hasElementChild = true;
                  else if (n.nodeType==3 && n.nodeValue.match(/[^ \f\n\r\t\v]/)) textChild++; // non-whitespace text
                  else if (n.nodeType==4) cdataChild++; // cdata section node
               }
               if (hasElementChild) {
                  if (textChild < 2 && cdataChild < 2) { // structured element with evtl. a single text or/and cdata node ..
                     X.removeWhite(xml);
                     for (var n=xml.firstChild; n; n=n.nextSibling) {
                        if (n.nodeType == 3)  // text node
                           o = X.escape(n.nodeValue);
                        else if (n.nodeType == 4)  // cdata node
//                           o["#cdata"] = X.escape(n.nodeValue);
                            o = X.escape(n.nodeValue);
                        else if (o[n.nodeName]) {  // multiple occurence of element ..
                           if (o[n.nodeName] instanceof Array)
                              o[n.nodeName][o[n.nodeName].length] = X.toObj(n);
                           else
                              o[n.nodeName] = [o[n.nodeName], X.toObj(n)];
                        }
                        else  // first occurence of element..
                           o[n.nodeName] = X.toObj(n);
                     }
                  }
                  else { // mixed content
                     if (!xml.attributes.length)
                        o = X.escape(X.innerXml(xml));
                     else
                        o["#text"] = X.escape(X.innerXml(xml));
                  }
               }
               else if (textChild) { // pure text
                  if (!xml.attributes.length)
                     o = X.escape(X.innerXml(xml));
                  else
                     o["#text"] = X.escape(X.innerXml(xml));
               }
               else if (cdataChild) { // cdata
                  if (cdataChild > 1)
                     o = X.escape(X.innerXml(xml));
                  else
                     for (var n=xml.firstChild; n; n=n.nextSibling){
                        //o["#cdata"] = X.escape(n.nodeValue);
                        o = X.escape(n.nodeValue);
                  }
               }
            }
            if (!xml.attributes.length && !xml.firstChild) o = null;
         }
         else if (xml.nodeType==9) { // document.node
            o = X.toObj(xml.documentElement);
         }
         else
            alert("unhandled node type: " + xml.nodeType);
         return o;
      },
      toJson: function(o, name, ind) {
         var json = name ? ("\""+name+"\"") : "";
         if (o instanceof Array) {
            for (var i=0,n=o.length; i<n; i++)
               o[i] = X.toJson(o[i], "", ind+"\t");
            json += (name?":[":"[") + (o.length > 1 ? ("\n"+ind+"\t"+o.join(",\n"+ind+"\t")+"\n"+ind) : o.join("")) + "]";
         }
         else if (o == null)
            json += (name&&":") + "null";
         else if (typeof(o) == "object") {
            var arr = [];
            for (var m in o)
               arr[arr.length] = X.toJson(o[m], m, ind+"\t");
            json += (name?":{":"{") + (arr.length > 1 ? ("\n"+ind+"\t"+arr.join(",\n"+ind+"\t")+"\n"+ind) : arr.join("")) + "}";
         }
         else if (typeof(o) == "string")
            json += (name&&":") + "\"" + o.toString() + "\"";
         else
            json += (name&&":") + o.toString();
         return json;
      },
      innerXml: function(node) {
         var s = ""
         if ("innerHTML" in node)
            s = node.innerHTML;
         else {
            var asXml = function(n) {
               var s = "";
               if (n.nodeType == 1) {
                  s += "<" + n.nodeName;
                  for (var i=0; i<n.attributes.length;i++)
                     s += " " + n.attributes[i].nodeName + "=\"" + (n.attributes[i].nodeValue||"").toString() + "\"";
                  if (n.firstChild) {
                     s += ">";
                     for (var c=n.firstChild; c; c=c.nextSibling)
                        s += asXml(c);
                     s += "</"+n.nodeName+">";
                  }
                  else
                     s += "/>";
               }
               else if (n.nodeType == 3)
                  s += n.nodeValue;
               else if (n.nodeType == 4)
                  s += "<![CDATA[" + n.nodeValue + "]]>";
               return s;
            };
            for (var c=node.firstChild; c; c=c.nextSibling)
               s += asXml(c);
         }
         return s;
      },
      escape: function(txt) {
         return txt.replace(/[\\]/g, "\\\\")
                   .replace(/[\"]/g, '\\"')
                   .replace(/[\n]/g, '\\n')
                   .replace(/[\r]/g, '\\r');
      },
      removeWhite: function(e) {
         e.normalize();
         for (var n = e.firstChild; n; ) {
            if (n.nodeType == 3) {  // text node
               if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) { // pure whitespace text node
                  var nxt = n.nextSibling;
                  e.removeChild(n);
                  n = nxt;
               }
               else
                  n = n.nextSibling;
            }
            else if (n.nodeType == 1) {  // element node
               X.removeWhite(n);
               n = n.nextSibling;
            }
            else                      // any other node
               n = n.nextSibling;
         }
         return e;
      }
   };
   if (xml.nodeType == 9) // document node
      xml = xml.documentElement;
   var json = X.toJson(X.toObj(X.removeWhite(xml)), xml.nodeName, "");
   return "{" + (tab ? json.replace(/\t/g, tab) : json.replace(/\t|\n/g, "")) + "}";
}


/**
 * @brief exec_json (exec_xml와 같은 용도)
 **/
(function($){
$.exec_json = function(action,data,func){
    if(typeof(data) == 'undefined') data = {};
    action = action.split(".");
    if(action.length == 2){

        if(show_waiting_message) {
            $("#waitingforserverresponse").html(waiting_message).css('top',$(document).scrollTop()+20).css('left',$(document).scrollLeft()+20).css('visibility','visible');
        }

        $.extend(data,{module:action[0],act:action[1]});
        $.ajax({
            type:"POST"
            ,dataType:"json"
            ,url:request_uri
            ,contentType:"application/json"
            ,data:$.param(data)
            ,success : function(data){
                $("#waitingforserverresponse").css('visibility','hidden');
                if(data.error > 0) alert(data.message);
                if($.isFunction(func)) func(data);
            }
        });
    }
};

$.fn.exec_html = function(action,data,type){
    if(typeof(data) == 'undefined') data = {};
    if(!$.inArray(type, ['html','append','prepend'])) type = 'html';

    var self = $(this);
    action = action.split(".");
    if(action.length == 2){
        if(show_waiting_message) {
            $("#waitingforserverresponse").html(waiting_message).css('top',$(document).scrollTop()+20).css('left',$(document).scrollLeft()+20).css('visibility','visible');
        }

        $.extend(data,{module:action[0],act:action[1]});
        $.ajax({
            type:"POST"
            ,dataType:"html"
            ,url:request_uri
            ,data:$.param(data)
            ,success : function(html){
                $("#waitingforserverresponse").css('visibility','hidden');
                self[type](html);
            }
        });
    }
};
})(jQuery);

/**
 * @file   common/js/xml_js_filter.js
 * @author zero (zero@nzeo.com)
 * @brief  xml filter에서 사용될 js
 *
 * zbxe 에서 form의 동작시 필수입력 여부등을 선처리하고 xml_handler.js의 exec_xml()을 통해서
 * 특정 모듈과의 ajax 통신을 통해 process를 진행시킴
 **/

var alertMsg = new Array();
var target_type_list = new Array();
var notnull_list = new Array();
var extra_vars = new Array();

/**
 * @function filterAlertMessage
 * @brief ajax로 서버에 요청후 결과를 처리할 callback_function을 지정하지 않았을 시 호출되는 기본 함수
 **/
function filterAlertMessage(ret_obj) {
    var error = ret_obj["error"];
    var message = ret_obj["message"];
    var act = ret_obj["act"];
    var redirect_url = ret_obj["redirect_url"];
    var url = location.href;

    if(typeof(message)!="undefined"&&message&&message!="success") alert(message);

    if(typeof(act)!="undefined" && act) url = current_url.setQuery("act", act);
    else if(typeof(redirect_url)!="undefined" && redirect_url) url = redirect_url;

    if(url == location.href) url = url.replace(/#(.+)$/,'');

    location.href = url;
}

/**
 * @class XmlJsFilter
 * @authro zero (zero@nzeo.com)
 * @brief form elements, module/act, callback_user_func을 이용하여 서버에 ajax로 form 데이터를 넘기고 결과를 받아오는 js class
 **/
function XmlJsFilter(form_object, module, act, callback_user_func) {
    this.field = new Array();
    this.parameter = new Array();
    this.response = new Array();

    this.fo_obj = form_object;
    this.module = module;
    this.act = act;
    this.user_func = callback_user_func;
    this.setFocus = XmlJsFilterSetFocus;
    this.addFieldItem = XmlJsFilterAddFieldItem;
    this.addParameterItem = XmlJsFilterAddParameterItem;
    this.addResponseItem = XmlJsFilterAddResponseItem;
    this.getValue = XmlJsFilterGetValue;
    this.executeFilter = XmlJsFilterExecuteFilter;
    this.checkFieldItem = XmlJsFilterCheckFieldItem;
    this.getParameterParam = XmlJsFilterGetParameterParam;
    this.alertMsg = XmlJsFilterAlertMsg;
    this.proc = XmlJsFilterProc;
}

function XmlJsFilterSetFocus(target_name) {
    var obj = this.fo_obj[target_name];
    if(typeof(obj)=='undefined' || !obj) return;
    
    var length = obj.length;
    try {
        if(typeof(length)!='undefined') {
            obj[0].focus();
        } else {
            obj.focus();
        }
    } catch(e) {
    }
}

function XmlJsFilterAddFieldItem(target, required, minlength, maxlength, equalto, filter) {
    var obj = new Array(target, required, minlength, maxlength, equalto, filter);
    this.field[this.field.length] = obj;
}

function XmlJsFilterAddParameterItem(param, target) {
    var obj = new Array(param, target);
    this.parameter[this.parameter.length] = obj;
}

function XmlJsFilterAddResponseItem(name) {
    this.response[this.response.length] = name;
}

function XmlJsFilterGetValue(target_name) {
    var obj = this.fo_obj[target_name];
    if(typeof(obj)=='undefined' || !obj) return '';
    var value = '';
    var length = obj.length;
    var type = obj.type;
    if((typeof(type)=='undefined'||!type) && typeof(length)!='undefined' && typeof(obj[0])!='undefined' && length>0) type = obj[0].type;
    else length = 0;

    switch(type) {
        case 'checkbox' :
                if(length>0) {
                    var value_list = new Array();
                    for(var i=0;i<length;i++) {
                        if(obj[i].checked) value_list[value_list.length] = obj[i].value;
                    }
                    value = value_list.join('|@|');
                } else {
                    if(obj.checked) value = obj.value;
                    else value = '';
                }
            break;
        case 'radio' :
                if(length>0) {
                    for(var i=0;i<length;i++) {
                        if(obj[i].checked) value = obj[i].value;
                    }
                } else {
                    if(obj.checked) value = obj.value;
                    else value = '';
                }
            break;
        case 'select' :
        case 'select-one' :
                if(obj.selectedIndex>=0) value = obj.options[obj.selectedIndex].value;
            break;
        default :
                if(length>0 && target_type_list[target_name]) {
                    switch(target_type_list[target_name]) {
                        case 'kr_zip' :
                                var val1 = obj[0].value;
                                var val2 = obj[1].value;
                                if(val1&&val2) {
                                    value = val1+'|@|'+val2;
                                }
                            break;
                        case 'tel' :
                                var val1 = obj[0].value;
                                var val2 = obj[1].value;
                                var val3 = obj[2].value;
                                if(val1&&val2&&val3) {
                                    value = val1+'|@|'+val2+'|@|'+val3;
                                }
                            break;
                    }

                } else {
                    value = obj.value;
                }
            break;
    }

    if(typeof(value)=='undefined'||!value) return '';
    return value.trim();
}

function XmlJsFilterExecuteFilter(filter, value) {
    switch(filter) {
        case "email" :
        case "email_address" :
                var regx = /^[_0-9a-zA-Z-]+(\.[_0-9a-zA-Z-]+)*@[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*$/;
                return regx.test(value);
            break;
        case "userid" :
        case "user_id" :
                var regx = /^[a-zA-Z]+([_0-9a-zA-Z]+)*$/;
                return regx.test(value);
            break;
        case "homepage" :
                var regx = /^(http|https|ftp|mms):\/\/[0-9a-z-]+(\.[_0-9a-z-\/\~]+)+(:[0-9]{2,4})*$/;       
                return regx.test(value);
            break;
        case "korean" :
                var regx = /^[가-힣]*$/; 
                return regx.test(value);
            break;
        case "korean_number" :
                var regx = /^[가-힣0-9]*$/; 
                return regx.test(value);
            break;
        case "alpha" :
                var regx = /^[a-zA-Z]*$/; 
                return regx.test(value);
            break;
        case "alpha_number" :
                var regx = /^[a-zA-Z][a-zA-Z0-9\_]*$/; 
                return regx.test(value);
            break;
        case "number" :
            return !isNaN(value);
        break;
    }

    return null;
}

function XmlJsFilterAlertMsg(target, msg_code, minlength, maxlength) {
    var target_msg = "";

    if(alertMsg[target]!='undefined') target_msg = alertMsg[target];
    else target_msg = target;

    var msg = "";
    if(typeof(alertMsg[msg_code])!='undefined') {
        if(alertMsg[msg_code].indexOf('%s')>=0) msg = alertMsg[msg_code].replace('%s',target_msg);
        else msg = target_msg+alertMsg[msg_code];
    } else {
        msg = msg_code;
    }

    if(typeof(minlength)!='undefined' && typeof(maxlength)!='undefined') msg += "("+minlength+"~"+maxlength+")";

    alert(msg);
    this.setFocus(target);

    return false;
}

function XmlJsFilterCheckFieldItem() {
    for(var i=0; i<extra_vars.length;i++) {
        var name = extra_vars[i];
        this.addFieldItem(name, false, 0, 0, "", "");
    }

    for(var i=0; i<this.field.length;i++) {
        var item = this.field[i];
        var target = item[0];
        var required = item[1];
        var minlength = item[2];
        var maxlength = item[3];
        var equalto = item[4];
        var filter = item[5].split(",");

        if(typeof(this.fo_obj[target])=='undefined') continue;

        for(var j=0; j<notnull_list.length; j++) {
            if(notnull_list[j]==target) required = true;
        }

        var value = this.getValue(target);
        if(!required && !value) continue;
        if(required && !value && this.fo_obj[target]) return this.alertMsg(target,'isnull');

        if(minlength>0 && maxlength>0 && (value.length < minlength || value.length > maxlength)) return this.alertMsg(target, 'outofrange', minlength, maxlength);

        if(equalto) {
            var equalto_value = this.getValue(equalto);
            if(equalto_value != value) return this.alertMsg(target, 'equalto');
        }

        if(filter.length && filter[0]) {
            for(var j=0;j<filter.length;j++) {
                var filter_item = filter[j];
                if(!this.executeFilter(filter_item, value)) return this.alertMsg(target, "invalid_"+filter_item);
            }
        }
    }
    return true;
} 

function XmlJsFilterGetParameterParam() {
    if(!this.fo_obj) return new Array();

    var prev_name = '';
    if(this.parameter.length<1) {
        for(var i=0;i<this.fo_obj.length;i++) {
            var name = this.fo_obj[i].name;
            if(typeof(name)=='undefined'||!name||name==prev_name) continue;
            this.addParameterItem(name, name);
            prev_name = name;
        }
    }

    var params = new Array();
    for(var i=0; i<this.parameter.length;i++) {
        var item = this.parameter[i];
        var param = item[0];
        var target = item[1];
        var value = this.getValue(target);
        params[param] = value;
    }
    return params;
}

function XmlJsFilterProc(confirm_msg) {
    var result = this.checkFieldItem();
    if(!result) return false;

    if(typeof(confirm_msg)=='undefined') confirm_msg = '';

    var params = this.getParameterParam();
    var response = this.response;
    if(confirm_msg && !confirm(confirm_msg)) return false;
    if(!this.act) {
        this.user_func(this.fo_obj, params);
        return true;
    }
    exec_xml(this.module, this.act, params, this.user_func, response, params, this.fo_obj);

    return false;
}

// form proc
function procFilter(fo_obj, filter_func) {
    // form문 안에 위지윅 에디터가 세팅되어 있을 경우 에디터의 값과 지정된 content field를 sync
    var editor_sequence = fo_obj.getAttribute('editor_sequence');
    if(typeof(editor_sequence)!='undefined' && editor_sequence && typeof(editorRelKeys)!='undefined') { 
        var content = editorGetContent(editor_sequence);

        var dummy = xCreateElement("div");
        xInnerHtml(dummy, content);

        // IE에서 컨텐츠 전체를 P태그로 감싸는 경우가 있어서 이 의미없는 P태그를 제거
        if(dummy.firstChild && dummy.firstChild.nodeName == 'P' && dummy.firstChild == dummy.lastChild) {
            var content = xInnerHtml(dummy.firstChild);
            xInnerHtml(dummy,content);
        }

        // img/a 태그의 대상에 대해 경로 재설정 (IE브라우저에서 위지윅 에디터내의 경로를 절대 경로로 바꾸는 버그때문ㅇ)
        var imgTags = xGetElementsByTagName('IMG', dummy);
        for(var i=0;i<imgTags.length;i++) {
            if(imgTags[i].src.indexOf(request_uri)!=-1) {
                imgTags[i].src = imgTags[i].src.replace(/(.*)files\/(.*)/i,'files/$2');
            }
        }
        var aTags = xGetElementsByTagName('A', dummy);
        for(var i=0;i<aTags.length;i++) {
            if(aTags[i].href.indexOf(request_uri)!=-1) {
                aTags[i].href = aTags[i].href.replace(/(.*)\?module=file&(.*)/i,'./?module=file&$2');
            }
        }
        var content = xInnerHtml(dummy);
        editorRelKeys[editor_sequence]['content'].value = content;
    }

    filter_func(fo_obj);
    return false;
}

/**
 * @brief 카운터 정보 수집 javascript
 * window.onload 이벤트 후에 counter 모듈을 호출한다.
 **/

// 이벤트 등록
jQuery(doCallCounter);

// counter 모듈을 호출하는 함수
function doCallCounter() {
    show_waiting_message = false;
    exec_xml('counter','procCounterExecute');
    show_waiting_message = true;
}

/************************************************************************/
/* Rainbow Links Version 1.03 (2003.9.20)                               */
/* Script updated by Dynamicdrive.com for IE6                           */
/* Copyright (C) 1999-2001 TAKANASHI Mizuki                             */
/* takanasi@hamal.freemail.ne.jp                                        */
/*----------------------------------------------------------------------*/
/* Read it somehow even if my English text is a little wrong! ;-)       */
/*                                                                      */
/* Usage:                                                               */
/*  Insert '<script src="rainbow.js"></script>' into the BODY section,  */
/*  right after the BODY tag itself, before anything else.              */
/*  You don't need to add "onMouseover" and "onMouseout" attributes!!   */
/*                                                                      */
/*  If you'd like to add effect to other texts(not link texts), then    */
/*  add 'onmouseover="doRainbow(this);"' and                            */
/*  'onmouseout="stopRainbow();"' to the target tags.                   */
/*                                                                      */
/* This Script works with IE4,Netscape6,Mozilla browser and above only, */
/* but no error occurs on other browsers.                               */
/************************************************************************/


////////////////////////////////////////////////////////////////////
// Setting

var rate = 20;  // Increase amount(The degree of the transmutation)


////////////////////////////////////////////////////////////////////
// Main routine

/*
if (document.getElementById)
window.onerror=new Function("return true")
*/

var objActive;  // The object which event occured in
var act = 0;    // Flag during the action
var elmH = 0;   // Hue
var elmS = 128; // Saturation
var elmV = 255; // Value
var clrOrg;     // A color before the change
var TimerID;    // Timer ID


if(xIE4Up) {
    xAddEventListener(document, 'mouseover', doRainbowAnchor);
    xAddEventListener(document, 'mouseout', stopRainbowAnchor);
} else {
    xAddEventListener(document, 'mouseover', Mozilla_doRainbowAnchor);
    xAddEventListener(document, 'mouseout', Mozilla_stopRainbowAnchor);
}
/*
if (document.all) {
    document.onmouseover = doRainbowAnchor;
    document.onmouseout = stopRainbowAnchor;
}
else if (document.getElementById) {
    document.captureEvents(Event.MOUSEOVER | Event.MOUSEOUT);
    document.onmouseover = Mozilla_doRainbowAnchor;
    document.onmouseout = Mozilla_stopRainbowAnchor;
}
*/


//=============================================================================
// doRainbow
//  This function begins to change a color.
//=============================================================================
function doRainbow(obj)
{
    if (act == 0) {
        act = 1;
        if (obj)
            objActive = obj;
        else
            objActive = event.srcElement;
        clrOrg = objActive.style.color;
        TimerID = setInterval("ChangeColor()",100);
    }
}


//=============================================================================
// stopRainbow
//  This function stops to change a color.
//=============================================================================
function stopRainbow()
{
    if (act) {
        objActive.style.color = clrOrg;
        clearInterval(TimerID);
        act = 0;
    }
}


//=============================================================================
// doRainbowAnchor
//  This function begins to change a color. (of a anchor, automatically)
//=============================================================================
function doRainbowAnchor()
{
    try {
        if (act == 0) {
            var obj = event.srcElement;
            while (obj.tagName != 'A' && obj.tagName != 'BODY') {
                obj = obj.parentElement;
                if (obj.tagName == 'A' || obj.tagName == 'BODY')
                    break;
            }

            if (obj.tagName == 'A' && obj.href != '') {
                objActive = obj;
                act = 1;
                clrOrg = objActive.style.color;
                TimerID = setInterval("ChangeColor()",100);
            }
        }
    } catch(e) {
    }
}


//=============================================================================
// stopRainbowAnchor
//  This function stops to change a color. (of a anchor, automatically)
//=============================================================================
function stopRainbowAnchor()
{
    if (act) {
        if (objActive.tagName == 'A') {
            objActive.style.color = clrOrg;
            clearInterval(TimerID);
            act = 0;
        }
    }
}


//=============================================================================
// Mozilla_doRainbowAnchor(for Netscape6 and Mozilla browser)
//  This function begins to change a color. (of a anchor, automatically)
//=============================================================================
function Mozilla_doRainbowAnchor(evt)
{
    var e = new xEvent(evt);
    if (act == 0) {
        obj = e.target;
        while (obj.nodeName != 'A' && obj.nodeName != 'BODY') {
            obj = obj.parentNode;
            if(typeof(obj)=='undefined'||!obj) return;
            if (obj.nodeName == 'A' || obj.nodeName == 'BODY') break;
        }

        if (obj.nodeName == 'A' && obj.href != '') {
            objActive = obj;
            act = 1;
            clrOrg = obj.style.color;
            TimerID = setInterval("ChangeColor()",100);
        }
    }
}


//=============================================================================
// Mozilla_stopRainbowAnchor(for Netscape6 and Mozilla browser)
//  This function stops to change a color. (of a anchor, automatically)
//=============================================================================
function Mozilla_stopRainbowAnchor(e)
{
    if (act) {
        if (objActive.nodeName == 'A') {
            objActive.style.color = clrOrg;
            clearInterval(TimerID);
            act = 0;
        }
    }
}


//=============================================================================
// Change Color
//  This function changes a color actually.
//=============================================================================
function ChangeColor()
{
    objActive.style.color = makeColor();
}


//=============================================================================
// makeColor
//  This function makes rainbow colors.
//=============================================================================
function makeColor()
{
    // Don't you think Color Gamut to look like Rainbow?

    // HSVtoRGB
    if (elmS == 0) {
        elmR = elmV;    elmG = elmV;    elmB = elmV;
    }
    else {
        t1 = elmV;
        t2 = (255 - elmS) * elmV / 255;
        t3 = elmH % 60;
        t3 = (t1 - t2) * t3 / 60;

        if (elmH < 60) {
            elmR = t1;  elmB = t2;  elmG = t2 + t3;
        }
        else if (elmH < 120) {
            elmG = t1;  elmB = t2;  elmR = t1 - t3;
        }
        else if (elmH < 180) {
            elmG = t1;  elmR = t2;  elmB = t2 + t3;
        }
        else if (elmH < 240) {
            elmB = t1;  elmR = t2;  elmG = t1 - t3;
        }
        else if (elmH < 300) {
            elmB = t1;  elmG = t2;  elmR = t2 + t3;
        }
        else if (elmH < 360) {
            elmR = t1;  elmG = t2;  elmB = t1 - t3;
        }
        else {
            elmR = 0;   elmG = 0;   elmB = 0;
        }
    }

    elmR = Math.floor(elmR).toString(16);
    elmG = Math.floor(elmG).toString(16);
    elmB = Math.floor(elmB).toString(16);
    if (elmR.length == 1)    elmR = "0" + elmR;
    if (elmG.length == 1)    elmG = "0" + elmG;
    if (elmB.length == 1)    elmB = "0" + elmB;

    elmH = elmH + rate;
    if (elmH >= 360)
        elmH = 0;

    return '#' + elmR + elmG + elmB;
}


jQuery(function($) {
    var url_regx = /((http|https|ftp|news|telnet|irc):\/\/(([0-9a-z\-._~!$&'\(\)*+,;=:]|(%[0-9a-f]{2}))*\@)?((\[(((([0-9a-f]{1,4}:){6}([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|(::([0-9a-f]{1,4}:){5}([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|(([0-9a-f]{1,4})?::([0-9a-f]{1,4}:){4}([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|((([0-9a-f]{1,4}:)?[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){3}([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|((([0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:){2}([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|((([0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|((([0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::([0-9a-f]{1,4}:[0-9a-f]{1,4})|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])))|((([0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4})|((([0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::))|(v[0-9a-f]+.[0-9a-z\-._~!$&'\(\)*+,;=:]+))\])|(([0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5])){3}[0-9]|([1-9][0-9])|(1[0-9][0-9])|(2[0-4][0-9])|(25[0-5]))|(([0-9a-z\-._~!$&'\(\)*+,;=]|(%[0-9a-f]{2}))+))(:[0-9]*)?(\/([0-9a-z\-._~!$&'\(\)*+,;=:@]|(%[0-9a-f]{2}))*)*(\?([0-9a-z\-._~!$&'\(\)*+,;=:@\/\?]|(%[0-9a-f]{2}))*)?(#([0-9a-z\-._~!$&'\(\)*+,;=:@\/\?]|(%[0-9a-f]{2}))*)?)/i;

    function replaceHrefLink(obj) {
        var obj_list = obj.childNodes;

        for(var i = 0; i < obj_list.length; ++i) {
            var obj = obj_list[i];
            var pObj = obj.parentNode;
            if(!pObj) continue;

            var pN = pObj.nodeName.toLowerCase();
            if($.inArray(pN, ['a', 'pre', 'xml', 'textarea', 'input', 'option', 'code']) != -1) continue;

            if(obj.nodeType == 3 && obj.length >= 10) {
                var content = obj.nodeValue;
                if(!url_regx.test(content)) continue;

                content = content.replace(/</g, '&lt;');
                content = content.replace(/>/g, '&gt;');
                content = content.replace(url_regx, '<a href="$1" onclick="window.open(this.href); return false;">$1</a>');

                $(obj).replaceWith(content);
                delete(content);

            } else if(obj.nodeType == 1 && obj.childNodes.length) {
                replaceHrefLink(obj);
            }
        }
    }

    $('.xe_content').each(function() {
        if(url_regx.test($(this).text())) replaceHrefLink(this);
    });
});

(function($){
$(function(){
    if(addon_keyword_link.length > 0){
        if(!addon_keyword_link_cssquery) addon_keyword_link_cssquery= '.xe_content';
        $(addon_keyword_link_cssquery).each(function(){
            var content = $(this).html();
            for(var i=0,c=addon_keyword_link.length;i<c;i++){
                var re = new RegExp(addon_keyword_link[i].keyword + '(?! *<\/a)',addon_keyword_link_reg_type);
                content = content.replace(re,'<a href="'+addon_keyword_link[i].url+'">' + addon_keyword_link[i].keyword + '</a>');
            }
            $(this).html(content);
        });
    }
});
})(jQuery);
function write_content(fo_obj) {
	var oFilter = new XmlJsFilter(fo_obj, "planet", "procPlanetContentWrite", completeInsertContent);
	oFilter.addFieldItem("content",true,0,0,"","");
	oFilter.addFieldItem("postscript",false,0,250,"","");
	oFilter.addFieldItem("content_tag",false,0,250,"","");
	oFilter.addFieldItem("mid",true,0,0,"","");
	oFilter.addParameterItem("content","content");
	oFilter.addParameterItem("extra_vars20","postscript");
	oFilter.addParameterItem("tags","content_tag");
	oFilter.addParameterItem("mid","mid");
	oFilter.addParameterItem("me2day_autopush","me2day_autopush");
	oFilter.addResponseItem("error");
	oFilter.addResponseItem("message");
	oFilter.addResponseItem("document_srl");
	return oFilter.proc();
}
alertMsg["content"] = "내용";
alertMsg["postscript"] = "postscript";
alertMsg["content_tag"] = "content_tag";
alertMsg["mid"] = "모듈이름";
alertMsg["extra_vars20"] = "extra_vars20";
alertMsg["tags"] = "tags";
alertMsg["me2day_autopush"] = "me2day_autopush";
target_type_list["content"] = "";
target_type_list["postscript"] = "";
target_type_list["content_tag"] = "";
target_type_list["mid"] = "";
alertMsg["isnull"] = "%s의 값을 입력해주세요";
alertMsg["outofrange"] = "%s의 글자 길이를 맞추어 주세요.";
alertMsg["equalto"] = "%s의 값이 잘못 되었습니다.";
alertMsg["invalid_email"] = "%s의 형식이 잘못되었습니다. (예: zbxe@zeroboard.com)";
alertMsg["invalid_userid"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_user_id"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_homepage"] = "%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)";
alertMsg["invalid_korean"] = "%s의 형식이 잘못되었습니다. 한글로만 입력해주셔야 합니다";
alertMsg["invalid_korean_number"] = "%s의 형식이 잘못되었습니다. 한글과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_alpha"] = "%s의 형식이 잘못되었습니다. 영문으로만 입력해주셔야 합니다";
alertMsg["invalid_alpha_number"] = "%s의 형식이 잘못되었습니다. 영문과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_number"] = "%s의 형식이 잘못되었습니다. 숫자로만 입력해주셔야 합니다";

function modify_content_tag(fo_obj) {
	var oFilter = new XmlJsFilter(fo_obj, "planet", "procPlanetContentTagModify", completeUpdateContentTag);
	oFilter.addFieldItem("document_srl",true,0,0,"","");
	oFilter.addFieldItem("planet_content_tag",false,0,250,"","");
	oFilter.addParameterItem("document_srl","document_srl");
	oFilter.addParameterItem("planet_content_tag","planet_content_tag");
	oFilter.addResponseItem("error");
	oFilter.addResponseItem("message");
	oFilter.addResponseItem("document_srl");
	return oFilter.proc();
}
alertMsg["document_srl"] = "문서번호";
alertMsg["planet_content_tag"] = "planet_content_tag";
target_type_list["document_srl"] = "";
target_type_list["planet_content_tag"] = "";
alertMsg["isnull"] = "%s의 값을 입력해주세요";
alertMsg["outofrange"] = "%s의 글자 길이를 맞추어 주세요.";
alertMsg["equalto"] = "%s의 값이 잘못 되었습니다.";
alertMsg["invalid_email"] = "%s의 형식이 잘못되었습니다. (예: zbxe@zeroboard.com)";
alertMsg["invalid_userid"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_user_id"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_homepage"] = "%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)";
alertMsg["invalid_korean"] = "%s의 형식이 잘못되었습니다. 한글로만 입력해주셔야 합니다";
alertMsg["invalid_korean_number"] = "%s의 형식이 잘못되었습니다. 한글과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_alpha"] = "%s의 형식이 잘못되었습니다. 영문으로만 입력해주셔야 합니다";
alertMsg["invalid_alpha_number"] = "%s의 형식이 잘못되었습니다. 영문과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_number"] = "%s의 형식이 잘못되었습니다. 숫자로만 입력해주셔야 합니다";

function insert_reply(fo_obj) {
	var oFilter = new XmlJsFilter(fo_obj, "planet", "procPlanetReplyWrite", completeInsertReply);
	oFilter.addFieldItem("mid",true,0,0,"","");
	oFilter.addFieldItem("document_srl",true,0,0,"","");
	oFilter.addFieldItem("planet_reply_content",true,1,255,"","");
	oFilter.addResponseItem("error");
	oFilter.addResponseItem("message");
	oFilter.addResponseItem("tpl");
	oFilter.addResponseItem("document_srl");
	return oFilter.proc();
}
alertMsg["mid"] = "모듈이름";
alertMsg["document_srl"] = "문서번호";
alertMsg["planet_reply_content"] = "플래닛 댓글 내용";
target_type_list["mid"] = "";
target_type_list["document_srl"] = "";
target_type_list["planet_reply_content"] = "";
alertMsg["isnull"] = "%s의 값을 입력해주세요";
alertMsg["outofrange"] = "%s의 글자 길이를 맞추어 주세요.";
alertMsg["equalto"] = "%s의 값이 잘못 되었습니다.";
alertMsg["invalid_email"] = "%s의 형식이 잘못되었습니다. (예: zbxe@zeroboard.com)";
alertMsg["invalid_userid"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_user_id"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_homepage"] = "%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)";
alertMsg["invalid_korean"] = "%s의 형식이 잘못되었습니다. 한글로만 입력해주셔야 합니다";
alertMsg["invalid_korean_number"] = "%s의 형식이 잘못되었습니다. 한글과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_alpha"] = "%s의 형식이 잘못되었습니다. 영문으로만 입력해주셔야 합니다";
alertMsg["invalid_alpha_number"] = "%s의 형식이 잘못되었습니다. 영문과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_number"] = "%s의 형식이 잘못되었습니다. 숫자로만 입력해주셔야 합니다";

/**
 * Jindo2 Framework
 * @version 1.0.5
 */
/**
 * Core object
 *
 */
if (typeof window != "undefined" && typeof window.nhn == "undefined") {
	window.nhn = new Object;
}

/**
 * 지정된 id 를 가지는 객체를 반환한다.
 * argument를 복수개로 지정하면 배열로 객체를 반환하며,
 * 아이디에 해당하는 객체가 존재하지 않으면 null 을 반환한다.
 * 또한 "<tagName>" 과 같은 형식의 문자열을 입력하면 tagName을 가지는 객체를 생성한다.
 * @id core.$
 * @param {String} 객체의 아이디(복수개 가능)
 * @return element
 */
function $(sID/*, id1, id2*/) {
	var ret = new Array;
	var el  = null;
	var reg = /^<([a-z]+|h[1-5])>$/i;

	for(var i=0; i < arguments.length; i++) {
		el = arguments[i];
		if (typeof el == "string") {
			if (reg.test(el)) {
				el = document.createElement(RegExp.$1);
			} else {
				el = document.getElementById(el);
			}
		}
		if (el) ret[ret.length] = el;
	}
	return ret.length?((arguments.length>1)?ret:ret[0]):null;
}

/**
 * 클래스 타입을 정의한다. 생성자는 $init 으로 정의한다.
 * @id core.$Class
 * @param {object} 클래스 정의 object	
 * @return {class} 클래스 타입
 */
 function $Class(oDef) {
	function typeClass() {
		var t = this;
		var a = [];

		while(typeof t.$super != "undefined") {
			t.$super.$this = this;
			if (typeof t.$super.$init == "function") a[a.length] = t;
			t = t.$super;
		}
		
		for(var i=a.length-1; i > -1; i--) a[i].$super.$init.apply(a[i].$super, arguments);

		if (typeof this.$init == "function") this.$init.apply(this,arguments);
	}
	
	if (typeof oDef.$static != "undefined") {
		var i=0, x;
		for(x in oDef) x=="$static"||i++;
		for(x in oDef.$static) typeClass[x] = oDef.$static[x];

		if (!i) return oDef.$static;
		delete oDef.$static;
	}

	typeClass.prototype = oDef;
	typeClass.prototype.constructor = typeClass;
	typeClass.extend = $Class.extend;

	return typeClass;
 }

/**
 * 클래스를 상속한다.
 * 상속된 클래스에서 this.$super.method 로 상위 메소드에 접근할 수도 있으나,
 * this.$super.$super.method 와 같이 한 단계 이상의 부모 클래스에는 접근할 수 없다.
 * @id core.$Class.extend
 * @import core.$Class
 * @param {class} 수퍼 클래스 객체
 * @return {class} 확장된 클래스 타입
 */
 $Class.extend = function(superClass) {
	this.prototype.$super = new Object;

	var superFunc = function(m, func) {
		return function() {
			var r;
			var f = this.$this[m];
			var t = this.$this;
			t[m] = func;
			r = t[m].apply(t, arguments);
			t[m] = f;

			return r;
		};
	};

	for(var x in superClass.prototype) {
		if (typeof this.prototype[x] == "undefined" && x !="$init") this.prototype[x] = superClass.prototype[x];
		if (typeof superClass.prototype[x] == "function") {
			this.prototype.$super[x] = superFunc(x, superClass.prototype[x]);
		} else {
			this.prototype.$super[x] = superClass.prototype[x];
		}
	}

	// inherit static methods of parent
	for(var x in superClass) {
		if (x == "prototype") continue;
		this[x] = superClass[x];
	}

	return this;
};
/////
/**
 * Agent 객체를 반환한다. Agent 객체는 브라우저와 OS에 대한 정보를 알 수 있도록 한다.
 * @id core.$Agent
 */
function $Agent() {
	var cl = arguments.callee;
	var cached = cl._cached;
	
	if (cl._cached) return cl._cached;
	if (!(this instanceof cl)) return new cl;
	if (typeof cl._cached == "undefined") cl._cached = this;
}

/**
 * 웹브라우저에 대한 정보 객체를 반환한다.
 * @id core.$Agent.navigator
 * @return {TypeNavigatorInfo} 웹브라우저 정보 객체
 */
$Agent.prototype.navigator = function() {
	var info = new Object;
	var ver  = -1;
	var u    = navigator.userAgent;
	var v    = navigator.vendor || "";
	
	function f(s,h){ return ((h||"").indexOf(s) > -1) };

	info.opera     = (typeof window.opera != "undefined") || f("Opera",u);
	info.ie        = !info.opera && f("MSIE",u);
	info.chrome    = f("Chrome",u);
	info.safari    = !info.chrome && f("Apple",v);
	info.mozilla   = f("Gecko",u) && !info.safari && !info.chrome;
	info.firefox   = f("Firefox",u);
	info.camino    = f("Camino",v);
	info.netscape  = f("Netscape",u);
	info.omniweb   = f("OmniWeb",u);
	info.icab      = f("iCab",v);
	info.konqueror = f("KDE",v);

	try {
		if (info.ie) {
			ver = u.match(/(?:MSIE) ([0-9.]+)/)[1];
		} else if (info.firefox||info.opera||info.omniweb) {
			ver = u.match(/(?:Firefox|Opera|OmniWeb)\/([0-9.]+)/)[1];
		} else if (info.mozilla) {
			ver = u.match(/rv:([0-9.]+)/)[1];
		} else if (info.safari) {
			ver = parseFloat(u.match(/Safari\/([0-9.]+)/)[1]);
			if (ver == 100) {
				ver = 1.1;
			} else {
				ver = [1.0,1.2,-1,1.3,2.0,3.0][Math.floor(ver/100)];
			}
		} else if (info.icab) {
			ver = u.match(/iCab[ \/]([0-9.]+)/)[1];
		} else if (info.chrome) {
			ver = u.match(/Chrome[ \/]([0-9.]+)/)[1];
		}

		info.version = parseFloat(ver);
		if (isNaN(info.version)) info.version = -1;
	} catch(e) {
		info.version = -1;
	}

	$Agent.prototype.navigator = function() {
		return info;
	};

	return info;
};

/**
 * OS에 대한 정보객체를 반환한다.
 * @id core.$Agent.os
 * @return {TypeOSInfo} OS 정보 객체
 */
$Agent.prototype.os = function() {
	var info = new Object;
	var u    = navigator.userAgent;
	var p    = navigator.platform;
	var f    = function(s,h){ return (h.indexOf(s) > -1) };

	info.win     = f("Win",p);
	info.mac     = f("Mac",p);
	info.linux   = f("Linux",p);
	info.win2000 = info.win && (f("NT 5.0",p) || f("2000",p));
	info.winxp   = info.win && (f("NT 5.1",p) || f("Win32",p));
	info.xpsp2   = info.winxp && (f("SV1",u) || f("MSIE 7",u));
	info.vista   = f("NT 6.0",p);

	$Agent.prototype.os = function() {
		return info;
	};

	return info;
};

/**
 * Flash에 대한 정보객체를 반환한다.
 * @id core.$Agent.flash
 * @return {TypeFlashInfo} Flash 정보 객체
 */
$Agent.prototype.flash = function() {
	var info = new Object;
	var p    = navigator.plugins;
	var m    = navigator.mimeTypes;
	var f    = null;

	info.installed = false;
	info.version   = -1;

	if (typeof p != "undefined" && p.length) {
		f = p["Shockwave Flash"];
		if (f) {
			info.installed = true;
			if (f.description) {
				info.version = parseFloat(f.description.match(/[0-9.]+/)[0]);
			}
		}

		if (p["Shockwave Flash 2.0"]) {
			info.installed = true;
			info.version   = 2;
		}
	} else if (typeof m != "undefined" && m.length) {
		f = m["application/x-shockwave-flash"];
		info.installed = (f && f.enabledPlugin);
	} else {
		for(var i=9; i > 1; i--) {
			try {
				f = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+i);

				info.installed = true;
				info.version   = i;
				break;
			} catch(e) {}
		}
	}

	$Agent.prototype.info = function() {
		return info;
	};

	return info;
};

/**
 * SilverLight에 대한 정보객체를 반환한다.
 * @id core.$Agent.silverlight
 */
$Agent.prototype.silverlight = function() {
	var info = new Object;
	var p    = navigator.plugins;
	var s    = null;

	info.installed = false;
	info.version   = -1;

	if (typeof p != "undefined" && p.length) {
		s = p["Silverlight Plug-In"];
		if (s) {
			info.installed = true;
		}
	} else {
		try {
			s = new ActiveXObject("AgControl.AgControl");
			info.installed = true;
		} catch(e) {}
	}

	$Agent.prototype.silverlight = function() {
		return info;
	};

	return info;
};
/**
 * 주어진 원소를 가진 배열 객체를 만든다.
 * @id core.$A
 * @import core.$A.toArray
 * @param {array} 배열 혹은 배열에 준하는 컬렉션 타입
 * @return {$A}
 */
function $A(array) {
	var cl = arguments.callee;
	
	if (typeof array == "undefined") array = [];
	if (array instanceof cl) return array;
	if (!(this instanceof cl)) return new cl(array);

	this._array = [];
	for(var i=0; i < array.length; i++) {
		this._array[this._array.length] = array[i];
	}
};

$A.prototype.toString = function() {
	return this._array.toString();
};

/**
 * 배열의 크기를 반환한다
 * @id core.$A.length
 * @return Number 배열의 크기
 * @
 */
$A.prototype.length = function(len, elem) {
	if (typeof len == "number") {
		var l = this._array.length;
		this._array.length = len;
		
		if (typeof elem != "undefined") {
			for(var i=l; i < len; i++) {
				this._array[i] = elem;
			}
		}

		return this;
	} else {
		return this._array.length;
	}
};

/**
 * 주어진 원소가 존재하는지 검사한다. 존재하면 true를, 그렇지 않으면 false를 반환한다
 * @id core.$A.has
 * @param {void} 검색할 값
 * @return Boolean
 * @import core.$A.indexOf
 */
$A.prototype.has = function(any) {
	return (this.indexOf(any) > -1);
};

/**
 * 주어진 원소가 배열에 몇 번째 요소로서 존재하는지 반환한다.
 * 배열의 인덱스는 0부터 시작한다. 해당 원소가 존재하지 않으면 -1 을 반환한다.
 * @id core.$A.indexOf
 * @param {void} 검색할 값
 * @return {Number} 검색결과 인덱스 번호
 */
$A.prototype.indexOf = function(any) {
	if (typeof this._array.indexOf != 'undefined') return this._array.indexOf(any);

	for(var i=0; i < this._array.length; i++) {
		if (this._array[i] == any) return i;
	}
	return -1;
};

/*
 * JavaScript 배열 객체를 반환한다
 * @id core.$A.$value
 * @return {Array} JavaScript 배열 객체
 */
$A.prototype.$value = function() {
	return this._array;
};

/**
 * 배열 객체에 엘리먼트를 추가한다.
 * @id core.$A.push
 * @param {void} 추가할 엘리먼트(복수개 가능)
 * @return {Number} 엘리먼트를 추가한 후의 배열 객체 크기
 */
$A.prototype.push = function(element1/*, ...*/) {
	return this._array.push.apply(this._array, $A(arguments).$value());
};

/**
 * 배열의 마지막 엘리먼트를 제거하고 제거된 엘리먼트를 반환한다.
 * @id core.$A.pop
 * @return {void} 제거된 엘리먼트
 */
$A.prototype.pop = function() {
	return this._array.pop();
};

/**
 * 배열의 첫 엘리먼트를 제거하고 제거된 엘리먼트를 반환한다.
 * @id core.$A.shift
 * @return {void} 제거된 엘리먼트
 */
$A.prototype.shift = function() {
	return this._array.shift();
};

/**
 * 주어진 한 개 이상의 엘리먼트를 배열 앞부분에 삽입하고, 해당 배열의 바뀐 크기를 반환한다.
 * @id core.$A.unshift
 * @param {void} 추가할 엘리먼트(복수개 가능)
 * @return {Nmber} 엘리먼트를 추가한 후의 배열 객체 크기
 */
$A.prototype.unshift = function(element1/*, ...*/) {
	this._array.unshift.apply(this._array, $A(arguments).$value());

	return this._array.length;
};

/**
 * 주어진 콜백함수를 배열의 각 요소에 실행한다.
 * @id core.$A.forEach
 * @import core.$A[Break, Continue]
 */
$A.prototype.forEach = function(callback, thisObject) {
	var arr         = this._array;
	var errBreak    = this.constructor.Break;
	var errContinue = this.constructor.Continue;
	
	function f(v,i,a) {
		try {
			callback.call(thisObject, v, i, a);
		} catch(e) {
			if (!(e instanceof errContinue)) throw e;
		}
	};

	if (typeof this._array.forEach == "function") {
		try {
			this._array.forEach(f);
		} catch(e) {
			if (!(e instanceof errBreak)) throw e;
		}
		return this;
	}

	for(var i=0; i < arr.length; i++) {
		try {
			f(arr[i], i, arr);
		} catch(e) {
			if (e instanceof errBreak) break;
			throw e;
			
		}
	}

	return this;
};

/**
 * 주어진 함수를 현재 객체의 모든 엘리먼트에 적용하고 현재 객체를 반환한다.
 * @id core.$A.map
 */
$A.prototype.map = function(callback, thisObject) {
	var arr         = this._array;
	var errBreak    = this.constructor.Break;
	var errContinue = this.constructor.Continue;
	
	function f(v,i,a) {
		try {
			return callback.call(thisObject, v, i, a);
		} catch(e) {
			if (e instanceof errContinue) return v;
			else throw e;
		}
	};

	if (typeof this._array.map == "function") {
		try {
			this._array = this._array.map(f);
		} catch(e) {
			if(!(e instanceof errBreak)) throw e;
		}
		return this;
	}

	for(var i=0; i < this._array.length; i++) {
		try {
			arr[i] = f(arr[i], i, arr);
		} catch(e) {
			if (e instanceof errBreak) break;
			throw e;
		}
	}

	return this;
};

/**
 * 주어진 콜백 함수를 만족시키는 요소만으로 만들어진 새로운 $A 배열을 반환한다.
 * 콜백 함수는 Boolean 값을 반환해야 한다.
 * @id core.$A.filter
 * @import core.$A.forEach
 */
$A.prototype.filter = function(callback, thisObject) {
	var ar = new Array;

	this.forEach(function(v,i,a) {
		if (callback.call(thisObject, v, i, a) === true) {
			ar[ar.length] = v;
		}
	});

	return $A(ar);
};

/**
 * 모든 배열의 원소가 주어진 콜백 함수를 만족시키는지를 검사한다.
 * 콜백함수는 Boolean 값을 반환해야 한다.
 * @id core.$A.every
 * @import core.$A.forEach
 */
$A.prototype.every = function(callback, thisObject) {
	if (typeof this._array.every != "undefined") return this._array.every(callback, thisObject);

	var result = true;
	this.forEach(function(v, i, a) {
		if (callback.call(thisObject, v, i, a) === false) {
			result = false;
			$A.Break();
		}
	});
	return result;
};

/**
 * 주어진 콜백 함수를 만족시키는 배열의 원소가 존재하는지를 검사한다.
 * 모든 배열의 요소중에서 하나라도 콜백함수를 만족시키면 이 메소드는 true를 반환한다.
 * 콜백함수는 Boolean 값을 반환해야 한다.
 * @id core.$A.every
 * @import core.$A.forEach
 */
$A.prototype.some = function(callback, thisObject) {
	if (typeof this._array.some != "undefined") return this._array.some(callback, thisObject);

	var result = false;
	this.forEach(function(v, i, a) {
		if (callback.call(thisObject, v, i, a) === true) {
			result = true;
			$A.Break();
		}
	});
	return result;
};

/**
 * 주어진 값을 제외한 새로운 $A배열을 반환한다
 * @id core.$A.refuse
 * @import core.$A.filter
 */
$A.prototype.refuse = function(value) {
	var a = $A(arguments);
	return this.filter(function(v,i) { return !a.has(v) });
};

/**
 * 주어진 시작 인덱스와 끝 인덱스까지의 배열 요소로 이루어진 새로운 $A 배열을 반환한다.
 * @id core.$A.slice
 */
$A.prototype.slice = function(start, end) {
	var a = this._array.slice.call(this._array, start, end);
	return $A(a);
};

/**
 * 특정 인덱스로부터 주어진 갯수만큼의 배열을 잘라서 반환한다.
 * @id core.$A.splice
 */
$A.prototype.splice = function(index, howMany/*, element*/) {
	var a = this._array.splice.apply(this._array, arguments);

	return $A(a);
};

/**
 * 배열의 원소를 무작위적으로 섞는다.
 * @id core.$A.shuffle
 */
$A.prototype.shuffle = function() {
	this._array.sort(function(a,b){ return Math.random()>Math.random()?1:-1 });
	
	return this;
};

/**
 * 배열에서 중복되는 원소를 제거한다.
 * @id core.$A.unique
 */
$A.prototype.unique = function() {
	var a = this._array, b = [], l = a.length;
	var i, j;

	// 중복되는 원소 제거
	for(i = 0; i < l; i++) {
		for(j = 0; j < b.length; j++) {
			if (a[i] == b[j]) break;
		}
		
		if (j >= b.length) b[j] = a[i];
	}
	
	this._array = b;
	
	return this;
};

/**
 * 배열 요소를 거꾸로 정렬한다.
 * @id core.$A.reverse
 */
$A.prototype.reverse = function() {
	this._array.reverse();

	return this;
};

/**
 * each, filter, map 메소드에서 반복구문을 중단한다.
 * @id core.$A.Break
 */
$A.Break = function() {
	if (!(this instanceof arguments.callee)) throw new arguments.callee;
};

/**
 * each, filter, map 메소드에서 현재 인덱스의 반복구문을 건너뛴다.
 * @id core.$A.Continue
 */
$A.Continue = function() {
	if (!(this instanceof arguments.callee)) throw new arguments.callee;
};
/**
 * Ajax 객체를 반환한다.
 * @id core.$Ajax
 * @import core.$Ajax.option
 */
function $Ajax(url, option) {
	var cl = arguments.callee;
	if (!(this instanceof cl)) return new cl(url, option);

	function _getXHR() {
		if (window.XMLHttpRequest) {
			return new XMLHttpRequest();
		} else if (ActiveXObject) {
			try { return new ActiveXObject('MSXML2.XMLHTTP'); }
			catch(e) { return new ActiveXObject('Microsoft.XMLHTTP'); }
			return null;
		}
	}

	var loc    = location.toString();
	var domain = '';
	try { domain = loc.match(/^https?:\/\/([a-z0-9_\-\.]+)/i)[1]; } catch(e) {}

	this._url = url;
	this._options  = new Object;
	this._headers  = new Object;
	this._options = {
		type   :"xhr",
		method :"post",
		proxy  :"",
		timeout:0,
		onload :function(){},
		ontimeout:function(){},
		jsonp_charset : "utf-8"
	};

	this.option(option);
	
	var _opt = this._options;
	
	_opt.type   = _opt.type.toLowerCase();
	_opt.method = _opt.method.toLowerCase();
	
	if (typeof window.__jindo2_callback == "undefined") {
		window.__jindo2_callback = new Array();
	}
	
	switch (_opt.type) {
		case "get":
		case "post":
			_opt.method = _opt.type;
			_opt.type   = "xhr";
		case "xhr":
			this._request = _getXHR();
			break;
		case "flash":
			this._request = new $Ajax.SWFRequest();
			break;
		case "jsonp":
			_opt.method = "get";
			this._request = new $Ajax.JSONPRequest();
			this._request.charset = _opt.jsonp_charset;
			break;
		case "iframe":
			this._request = new $Ajax.FrameRequest();
			this._request._proxy = _opt.proxy;
			break;
	}
};

/**
 * 주어진 데이터로 Ajax를 호출한다.
 * @id core.$Ajax._onload
 * @param {Function} Ajax 호출이 완료된 후 실행할 함수
 */
$Ajax.prototype._onload = function() {
	if (this._request.readyState == 4) {
		this._options.onload($Ajax.Response(this._request));
	}
};

/**
 * Ajax를 호출한다.
 * @id core.$Ajax.request
 * @param {Object} oData 요청시 보낼 데이터
 * @param {Function} onComplete 요청이 완료되었을 때 실행할 함수
 */
$Ajax.prototype.request = function(oData) {
	var t   = this;
	var req = this._request;
	var opt = this._options;
	var data, v,a = [], data = "";
	if (typeof oData == "undefined" || !oData) {
		data = null;
	} else {
		for(var k in oData) {
			v = oData[k];
			if (typeof v == "function") v = v();
			a[a.length] = k+"="+encodeURIComponent(v);
		}
		data = a.join("&");
	}

	req.open(opt.method.toUpperCase(), this._url, true);
	req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
//	req.setRequestHeader("charset", "utf-8");
	for(var x in this._headers) {
		if (typeof this._headers[x] == "function") continue;
		req.setRequestHeader(x, String(this._headers[x]));
	}
	
	if (typeof req.onload != "undefined") {
		req.onload = function(rq){ t._onload(rq) };
	} else {
		req.onreadystatechange = function(rq){ t._onload(rq) };
	}
	
	req.send(data);

	return this;
};

/**
 * @id core.$Ajax.abort
 */
$Ajax.prototype.abort = function() {
	this._request.abort();

	return this;
};

/**
 * 옵션을 가져오거나 설정한다.
 * 첫번째 전달값의 타입이 Object 이면 값을 설정하고 문자열이면 해당하는 옵션값을 반환한다.
 * @id core.$Ajax.option
 * @param {String} name 가지고 오거나 설정할 옵션이름
 * @param {void}   value 값을 설정할 옵션이름
 * @return {void}  설정된 옵션값 혹은 $Ajax 객체
 */
$Ajax.prototype.option = function(name, value) {
	if (typeof name == "undefined") return "";
	if (typeof name == "string") {
		if (typeof value == "undefined") return this._options[name];
		this._options[name] = value;
		return this;
	}

	try { for(var x in name) this._options[x] = name[x] } catch(e) {};
	
	return this;
};

/**
 * 헤더를 가져오거나 설정한다.
 * 첫번째 전달값의 타입이 Object 이면 값을 설정하고 문자열이면 해당하는 헤더값을 반환한다.
 * @id core.$Ajax.header
 * @param {String} name 가지고 오거나 설정할 헤더 이름
 * @param {void} value 값을 설정할 헤더 값
 * @return {void} 설정된 헤더값 혹은 $Ajax 객체
 */
$Ajax.prototype.header = function(name, value) {
	if (typeof name == "undefined") return "";
	if (typeof name == "string") {
		if (typeof value == "undefined") return this._headers[name];
		this._headers[name] = value;
		return this;
	}
	
	try { for(var x in name) this._headers[x] = name[x] } catch(e) {};
	
	return this;
};

/**
 * Ajax 응답 객체
 * @id core.$Ajax.Response
 * @param {Object} req 요청 객체
 */
$Ajax.Response  = function(req) {
	if (this === $Ajax) return new $Ajax.Response(req);	
	this._response = req;
};

/**
 * XML 객체를 반환한다.
 * @id core.$Ajax.Response.xml
 */
$Ajax.Response.prototype.xml = function() {
	return this._response.responseXML; 
};

$Ajax.Response.prototype.text = function() {
	return this._response.responseText;
};

/**
 * Returns json object
 * @id core.$Ajax.Response.json
 */
$Ajax.Response.prototype.json = function() {
	if (this._response.responseJSON) {
		return this._response.responseJSON;
	} else if (this._response.responseText) {
		try {
			if (typeof $JSON != "undefined") {
				return $JSON(this._response.responseText);
			} else {
				return eval("("+this._response.responseText+")");
			}
		} catch(e) {
			return {};
		}
	}
	
	return {};
};

/**
 * 응답헤더를 가져온다. 인자를 전달하지 않으면 모든 헤더를 반환한다.
 * @id core.$Ajax.Response.header
 * @param {String} 가져올 응답헤더의 이름
 */
$Ajax.Response.prototype.header = function(name) {
	if (typeof name == "string") return this._response.getResponseHeader(name);
	return this._response.getAllResponseHeaders();
};

/**
 * @id core.$Ajax.RequestBase
 */
$Ajax.RequestBase = $Class({
	_headers : {},
	_respHeaders : {},
	_respHeaderString : "",
	responseXML  : null,
	responseJSON : null,
	responseText : "",
	$init  : function(){},
	onload : function(){},
	abort  : function(){},
	open   : function(){},
	send   : function(){},
	setRequestHeader  : function(sName, sValue) {
		this._headers[sName] = sValue;
	}, 
	getResponseHeader : function(sName) {
		return this._respHeaders[sName] || "";
	},
	getAllResponseHeaders : function() {
		return this._respHeaderString;
	},
	_getCallbackInfo : function() {
		var id = "";
	
		do {
			id = "$"+Math.floor(Math.random()*10000);
		} while(window.__jindo2_callback[id]);
		
		return {id:id,name:"window.__jindo2_callback."+id};
	}
});

/**
 * @id core.$Ajax.JSONPRequest
 */
$Ajax.JSONPRequest = $Class({
	charset : "utf-8",
	_script : null,
	_callback : function(data) {
		var self = this;

		this.readyState = 4;
		this.responseJSON = data;
		this.onload(this);
		
		setTimeout(function(){ self.abort() }, 10);
	},
	abort : function() {
		if (this._script) {
			try { this._script.parentNode.removeChild(this._script) }catch(e){}; 
		}
	},
	open  : function(method, url) {
		this.responseJSON = null;

		this._url = url;
	},
	send  : function(data) {
		var t    = this;
		var info = this._getCallbackInfo();
		var head = document.getElementsByTagName("head")[0];
		
		this._script = $("<script>");
		this._script.type    = "text/javascript";
		this._script.charset = this.charset;
		
		if (head) {
			head.appendChild(this._script);
		} else if (document.body) {
			document.body.appendChild(this._script);
		}
		
		window.__jindo2_callback[info.id] = function(data){
			try {
				t._callback(data);
			} finally {
				delete window.__jindo2_callback[info.id];
			}
		};
		
		this._script.src = this._url+"?_callback="+info.name+"&"+data;
	}
}).extend($Ajax.RequestBase);

/**
 * @id core.$Ajax.SWFRequest
 */
$Ajax.SWFRequest = $Class({
	_callback : function(success, data){
		this.readyState = 4;
		if (success) {
			if (typeof data == "string") {
				try {
					this.responseText = decodeURIComponent(data);
				} catch(e) {}
			}
			this.onload(this);
		}
	},
	open : function(method, url) {
		var re  = /https?:\/\/([a-z0-9_\-\.]+)/i;
		
		this._url    = url;
		this._method = method;
	},
	send : function(data) {
		this.responseXML  = false;
		this.responseText = "";
		
		var t    = this;
		var dat  = {};
		var info = this._getCallbackInfo();
		var swf  = window.document[$Ajax.SWFRequest._tmpId];
		var header = [];
		
		function f(arg) {
			switch(typeof arg){
				case "string":
					return '"'+arg.replace(/\"/g, '\\"')+'"';
					break;
				case "number":
					return arg;
					break;
				case "object":
					var ret = "", arr = [];
					if (arg instanceof Array) {
						for(var i=0; i < arg.length; i++) {
							arr[i] = f(arg[i]);
						}
						ret = "["+arr.join(",")+"]";
					} else {
						for(var x in arg) {
							arr[arr.length] = f(x)+":"+f(arg[x]);
						}
						ret = "{"+arr.join(",")+"}";
					}
					return ret;
				default:
					return '""';
			}
		}

		data = (data || "").split("&");
		
		for(var i=0; i < data.length; i++) {
			pos = data[i].indexOf("=");
			key = data[i].substring(0,pos);
			val = data[i].substring(pos+1);
			
			dat[key] = decodeURIComponent(val);
		}
		
		window.__jindo2_callback[info.id] = function(success, data){
			try {
				t._callback(success, data);
			} finally {
				delete window.__jindo2_callback[info.id];
			}
		};

		swf.requestViaFlash(f({
			url  : this._url,
			type : this._method,
			data : dat,
			charset  : "UTF-8",
			callback : info.name,
			headers_json : this._headers
		}));
	}
}).extend($Ajax.RequestBase);

$Ajax.SWFRequest.write = function(swf_path) {
	if(typeof swf_path == "undefined") swf_path = "./ajax.swf";
	$Ajax.SWFRequest._tmpId = 'tmpSwf'+(new Date).getMilliseconds()+Math.floor(Math.random()*100000);
	
	document.write('<div style="position:absolute;top:-1000px;left:-1000px"><object id="'+$Ajax.SWFRequest._tmpId+'" width="1" height="1" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"><param name="movie" value="'+swf_path+'"><param name = "allowScriptAccess" value = "always" /><embed name="'+$Ajax.SWFRequest._tmpId+'" src="'+swf_path+'" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" width="1" height="1" allowScriptAccess="always" swLiveConnect="true"></embed></object></div>');
};

/**
 * @id core.$Ajax.FrameRequest
 */
$Ajax.FrameRequest = $Class({
	_frame  : null,
	_proxy  : "",
	_domain : "",
	_callback : function(id, data, header) {
		var self = this;

		this.readyState   = 4;
		this.responseText = data;
		
		this._respHeaderString = header;
		header.replace(/^([\w\-]+)\s*:\s*(.+)$/m, function($0,$1,$2) {
			self._respHeaders[$1] = $2;
		});
	
		this.onload(this);
	
		setTimeout(function(){ self.abort() }, 10);
	},
	abort : function() {
		if (this._frame) {
			try {
				this._frame.parentNode.removeChild(this._frame);
			} catch(e) {}
		}
	},
	open : function(method, url) {
		var re  = /https?:\/\/([a-z0-9_\-\.]+)/i;
		var dom = document.location.toString().match(re);
		
		this._method = method;
		this._url    = url;
		this._remote = String(url).match(/(https?:\/\/[a-z0-9_\-\.]+)/i)[1];
		this._frame = null;
		this._domain = (dom[1] != document.domain)?document.domain:"";
	},
	send : function(data) {
		this.responseXML  = "";
		this.responseText = "";
	
		var t      = this;
		var re     = /https?:\/\/([a-z0-9_\-\.]+)/i;
		var info   = this._getCallbackInfo();
		var url    = this._remote+"/ajax_remote_callback.html?method="+this._method;
		var header = new Array;
	
		window.__jindo2_callback[info.id] = function(id, data, header){
			try {
				t._callback(id, data, header);
			} finally {
				delete window.__jindo2_callback[info.id];
			}
		};
	
		for(var x in this._headers) {
			header[header.length] = "'"+x+"':'"+this._headers[x]+"'";
		}
	
		header = "{"+header.join(",")+"}";
	
		url += "&id="+info.id;
		url += "&header="+encodeURIComponent(header);
		url += "&proxy="+encodeURIComponent(this._proxy);
		url += "&domain="+this._domain;
		url += "&url="+encodeURIComponent(this._url.replace(re, ""));
		url += "#"+encodeURIComponent(data);
	
		var fr = this._frame = $("<iframe>");
		fr.style.position = "absolute";
		fr.style.visibility = "hidden";
		fr.style.width = "1px";
		fr.style.height = "1px";
	
		var body = document.body || document.documentElement;
		if (body.firstChild) body.insertBefore(fr, body.firstChild);
		else body.appendChild(fr);
	
		fr.src = url;
	}
}).extend($Ajax.RequestBase);
/**
 * $H 해시 객체를 리턴한다
 * @id core.$H
 */
function $H(hashObject) {
	var cl = arguments.callee;
	if (typeof hashObject == "undefined") hashObject = new Object;
	if (hashObject instanceof cl) return hashObject;
	if (!(this instanceof cl)) return new cl(hashObject);

	this._table = {};
	for(var k in hashObject) {
		if (this._table[k] == hashObject[k]) continue;
		this._table[k] = hashObject[k];
	}
};

/**
 * Object 를 반환한다.
 */
$H.prototype.$value = function() {
	return this._table;
};

/**
 * 해시 객체의 크기를 반환한다.
 * @id core.$H.length
 * @return {Number} 해시의 크기
 */
$H.prototype.length = function() {
	var i = 0;
	for(var k in this._table) {
		if (typeof Object.prototype[k] != "undeifned" && Object.prototype[k] === this._table[k]) continue;
		i++;
	}

	return i;
};

/**
 * $H 해시 객체의 각 요소에 주어진 콜백함수를 실행한다.
 * @id core.$H.forEach
 * @import core.$H[Break, Continue]
 */
$H.prototype.forEach = function(callback, thisObject) {
	var t = this._table;
	var h = this.constructor;
	
	for(var k in t) {
		if (!t.propertyIsEnumerable(k)) continue;
		try {
			callback.call(thisObject, t[k], k, t);
		} catch(e) {
			if (e instanceof h.Break) break;
			if (e instanceof h.Continue) continue;
		}
	}
	return this;
};

/**
 * $H 해시 객체에서 필터 콜백함수를 만족하는 객체의 $H 객체를 리턴한다.
 * 콜백함수는 Boolean 값을 반환해야 한다.
 * @id core.$H.map
 * @import core.$H.forEach
 * @return {$H} 해시객체
 */
$H.prototype.filter = function(callback, thisObject) {
	var h = $H();
	this.forEach(function(v,k,o) {
		if(callback.call(thisObject, v, k, o) === true) {
			h.add(k,v);
		}
	});
	return h;
};

/**
 * $H 해시 객체의 각 요소에 주어진 콜백함수를 실행하고, 함수의 반환값을 해당 요소에 대입한다.
 * @id core.$H.map
 * @import core.$H.forEach
 * @return {$H} 해시객체
 */
$H.prototype.map = function(callback, thisObject) {
	var t = this._table;
	this.forEach(function(v,k,o) {
		t[k] = callback.call(thisObject, v, k, o);
	});
	return this;
};

/**
 * 해시 테이블에 값을 추가한다.
 * @id core.$H.add
 * @return {void} 추가된 값
 */
$H.prototype.add = function(key, value) {
	this._table[key] = value;
	return this._table[key];
};

/**
 * 해시 테이블에 존재하는 값을 제거한다.
 * @id core.$H.remove
 * @return {void} 제거된 값
 */
$H.prototype.remove = function(key) {
	if (typeof this._table[key] == "undefined") return null;
	var val = this._table[key];
	delete this._table[key];
	
	return val;
};

/**
 * 해시 테이블에서 주어진 값을 검색하고, 결과가 존재하면 키를 반환한다.
 * 결과가 존재하지 않으면 false 를 반환한다.
 * @id core.$H.search
 */
$H.prototype.search = function(value) {
	var result = false;
	this.forEach(function(v,k,o) {
		if (v === value) {
			result = k;
			$H.Break();
		}
	});
	return result;
};

/**
 * 해시 테이블에 주어진 키가 있는지 확인한다.
 * @id core.$H.hasKey
 * @return {Boolean} 키의 존재 여부
 */
$H.prototype.hasKey = function(key) {
	var result = false;
	
	return (typeof this._table[key] != "undefined");
};

/**
 * 해시 테이블에 주어진 값이 있는지 확인한다.
 * @id core.$H.hasValue
 * @import core.$H.search
 * @return {Boolean} 값의 존재 여부
 */
$H.prototype.hasValue = function(value) {
	return (this.search(value) !== false);
};

/**
 * 값을 기준으로 해시 객체를 정렬하고 현재 객체를 리턴한다.
 * @id core.$H.sort
 * @import core.$H.values, core.$H.search
 * @return {$H} 해시 객체
 */
$H.prototype.sort = function() {
	var o = new Object;
	var a = this.values();
	var k = false;

	a.sort();

	for(var i=0; i < a.length; i++) {
		k = this.search(a[i]);

		o[k] = a[i];
		delete this._table[k];
	}
	
	this._table = o;
	
	return this;
};

/**
 * 키값을 기준으로 해시 객체를 정렬하고 현재 객체를 리턴한다.
 * @id core.$H.ksort
 * @import core.$H.keys
 * @return {$H} 해시 객체
 */
$H.prototype.ksort = function() {
	var o = new Object;
	var a = this.keys();

	a.sort();

	for(var i=0; i < a.length; i++) {
		o[a[i]] = this._table[a[i]];
	}

	this._table = o;

	return this;
};

/**
 * 해시 키의 배열을 반환한다.
 * @id core.$H.keys
 * @return {Array} 해시 키의 배열
 */
$H.prototype.keys = function() {
	var keys = new Array;
	for(var k in this._table) {
		keys.push(k);
	}

	return keys;
};

/**
 * 해시 값의 배열을 반환한다.
 * @id core.$H.values
 * @return {Array} 해시 값의 배열
 */
$H.prototype.values = function() {
	var values = [];
	for(var k in this._table) {
		values[values.length] = this._table[k];
	}

	return values;
};

/**
 * 해시 객체를 쿼리 스트링 형태로 만들어준다.
 * @id core.$H.toQueryString
 * @return {String} 
 */
$H.prototype.toQueryString = function() {
	var buf = [], val = null, idx = 0;
	for(var k in this._table) {
		if (typeof(val = this._table[k]) == "object" && val.constructor == Array) {
			for(i=0; i < val.length; i++) {
				buf[buf.length] = encodeURIComponent(k)+"[]="+encodeURIComponent(val[i]+"");
			}
		} else {
			buf[buf.length] = encodeURIComponent(k)+"="+encodeURIComponent(this._table[k]+"");
		}
	}
	
	return buf.join("&");
};

/**
 * forEach, filter 등의 반복문 도중 실행을 중단할 때 사용한다.
 * @id core.$H.Break
 */
$H.Break = function() {
	if (!(this instanceof arguments.callee)) throw new arguments.callee;
};

/**
 * forEach, filter 등의 반복문 도중 현재 단계를 건너뛀 때 사용한다.
 * @id core.$H.Continue
 */
$H.Continue = function() {
	if (!(this instanceof arguments.callee)) throw new arguments.callee;
};

/**
 * JSON 객체를 반환한다.첫번째 argument는 객체 혹은 JSON 문자열이 된다.
 * @id core.$Json
 */
function $Json(sObject) {
	var cl = arguments.callee;
	if (typeof sObject == "undefined") sObject = new Object;
	if (sObject instanceof cl) return sObject;
	if (!(this instanceof cl)) return new cl(sObject);
	
	if (typeof sObject == "string") {
		try {
			sObject = eval("("+sObject+")");
		} catch(e) {
			sObject = new Object;
		}
	}

	this._object = sObject;
}

/**
 * XML 문자열로부터 JSON 객체를 반환한다.
 * @id core.$Json.fromXML
 */
$Json.fromXML = function(sXML) {
	var o  = new Object;
	var re = /\s*<(\/?[\w:\-]+)((?:\s+[\w:\-]+\s*=\s*"[^"]*")*)\s*>(?:(<\/\1>)|\s*)|\s*<!\[CDATA\[([\w\W]*?)\]\]>\s*|\s*([^<]*)\s*/ig;
	var re2= /^[0-9]+(?:\.[0-9]+)?$/;
	var ec = {"&amp;":"&","&nbsp;":" ","&quot;":"\"","&lt;":"<","&gt;":">"};
	var fg = {tags:["/"],stack:[o]};
	var es = function(s){return s.replace(/&[a-z]+;/g, function(m){ return (typeof ec[m] == "string")?ec[m]:m; })};
	var at = function(s,c){s.replace(/([\w\:\-]+)\s*=\s*"([^"]*)"/g, function($0,$1,$2){ c[$1] = es($2) }) };
	var em = function(o){for(var x in o){if(Object.prototype[x])continue;return false;};return true};
	var cb = function($0,$1,$2,$3,$4,$5) {
		var cur, cdata = "";
		var idx = fg.stack.length - 1;
		
		if (typeof $1 == "string" && $1) {
			if ($1.substr(0,1) != "/") {
				var has_attr = (typeof $2 == "string" && $2);
				var closed   = (typeof $3 == "string" && $3);
				var newobj   = (!has_attr && closed)?"":{};

				cur = fg.stack[idx];
				
				if (typeof cur[$1] == "undefined") {
					cur[$1] = newobj; 
					cur = fg.stack[idx+1] = cur[$1];
				} else if (cur[$1] instanceof Array) {
					var len = cur[$1].length;
					cur[$1][len] = newobj;
					cur = fg.stack[idx+1] = cur[$1][len];  
				} else {
					cur[$1] = [cur[$1], newobj];
					cur = fg.stack[idx+1] = cur[$1][1];
				}
				
				if (has_attr) at($2,cur);

				fg.tags[idx+1] = $1;

				if (closed) {
					fg.tags.length--;
					fg.stack.length--;
				}
			} else {
				fg.tags.length--;
				fg.stack.length--;
			}
		} else if (typeof $4 == "string" && $4) {
			cdata = $4;
		} else if (typeof $5 == "string" && $5) {
			cdata = es($5);
		}
		
		if (cdata.length > 0) {
			var par = fg.stack[idx-1];
			var tag = fg.tags[idx];

			if (re2.test(cdata)) cdata = parseFloat(cdata);
			else if (cdata == "true" || cdata == "false") cdata = new Boolean(cdata);

			if (par[tag] instanceof Array) {
				var o = par[tag];
				if (typeof o[o.length-1] == "object" && !em(o[o.length-1])) {
					o[o.length-1].$cdata = cdata;
					o[o.length-1].toString = function(){ return cdata; }
				} else {
					o[o.length-1] = cdata;
				}
			} else {
				if (typeof par[tag] == "object" && !em(par[tag])) {
					par[tag].$cdata = cdata;
					par[tag].toString = function(){ return cdata; }
				} else {
					par[tag] = cdata;
				}
			}
		}
	};
	
	sXML = sXML.replace(/<(\?|\!-)[^>]*>/g, "");
	sXML.replace(re, cb);
	
	return $Json(o);
};

/**
 * JSON 객체의 값을 path 형태로 받아온다.
 * @id core.$Json.get
 * @param {String} sPath path 문자열
 * @return {Array} 객체의 배열
 */
$Json.prototype.get = function(sPath) {
	var o = this._object;
	var p = sPath.split("/");
	var re = /^([\w:\-]+)\[([0-9]+)\]$/;
	var stack = [[o]], cur = stack[0];
	var len = p.length, c_len, idx, buf, j, e;
	
	for(var i=0; i < len; i++) {
		if (p[i] == "." || p[i] == "") continue;
		if (p[i] == "..") {
			stack.length--;
		} else {
			buf = [];
			idx = -1;
			c_len = cur.length;
			
			if (c_len == 0) return [];
			if (re.test(p[i])) idx = +RegExp.$2;
			
			for(j=0; j < c_len; j++) {
				e = cur[j][p[i]];
				if (typeof e == "undefined") continue;
				if (e instanceof Array) {
					if (idx > -1) {
						if (idx < e.length) buf[buf.length] = e[idx];
					} else {
						buf = buf.concat(e);
					}
				} else if (idx == -1) {
					buf[buf.length] = e;
				}
			}
			
			stack[stack.length] = buf;
		}
		
		cur = stack[stack.length-1];
	}

	return cur;
};

/**
 * JSON 객체를 JSON 문자열로 변환한다.
 * @id core.$Json.toString
 * @return {String} JSON 문자열
 */
$Json.prototype.toString = function() {
	var func = {
		$ : function($) {
			if (typeof $ == "undefined") return '""';
			if (typeof $ == "boolean") return $?"true":"false";
			if (typeof $ == "string") return this.s($);
			if (typeof $ == "number") return $;
			if ($ instanceof Array) return this.a($);
			if ($ instanceof Object) return this.o($);
		},
		s : function(s) {
			var e = {'"':'\\"',"\\":"\\\\","\n":"\\n","\r":"\\r","\t":"\\t"};
			var c = function(m){ return (typeof e[m] != "undefined")?e[m]:m };
			return '"'+s.replace(/[\\"'\n\r\t]/g, c)+'"';
		},
		a : function(a) {
			var s = "[",c = "",n=a.length;
			for(var i=0; i < n; i++) {
				if (typeof a[i] == "function") continue;
				s += c+this.$(a[i]);
				if (!c) c = ",";
			}
			return s+"]";
		},
		o : function(o) {
			var s = "{",c = "";
			for(var x in o) {
				if (typeof o[x] == "function") continue;
				s += c+this.s(x)+":"+this.$(o[x]);
				if (!c) c = ",";
			}
			return s+"}";
		}
	}

	return func.$(this._object);
};

/**
 * JSON 객체를 XML 문자열로 변환한다.
 * @id core.$Json.toXML
 * @return {String} XML 문자열
 */
$Json.prototype.toXML = function() {
	var f = function($,tag) {
		var t = function(s,at) { return "<"+tag+(at||"")+">"+s+"</"+tag+">" };
		
		switch (typeof $) {
			case "undefined":
			case "null":
				return t("");
			case "number":
				return t($);
			case "string":
				if ($.indexOf("<") < 0) return t($.replace(/&/g,"&amp;"));
				else return t("<![CDATA["+$+"]]>");
			case "boolean":
				return t(String($));
			case "object":
				var ret = "";
				if ($ instanceof Array) {
					var len = $.length;
					for(var i=0; i < len; i++) { ret += f($[i],tag); };
				} else {
					var at = "";

					for(var x in $) {
						if (x == "$cdata" || typeof $[x] == "function") continue;
						ret += f($[x], x);
					}

					if (tag) ret = t(ret, at);
				}
				return ret;
		}
	};
	
	return f(this._object, "");
};

/**
 * JSON  데이터 객체를 반환한다.
 * @id core.$Json.toObject
 * @import core.$Json.$value
 * @return {Object} 데이터 객체
 */
$Json.prototype.toObject = function() {
	return this._object;
};

/**
 * $Json.toObject의 alias function
 * @id core.$Json.$value
 */
$Json.prototype.$value = $Json.prototype.toObject;
/**
 * $Cookie 객체를 반환한다.
 * @id core.$Cookie
 */
function $Cookie() {
	var cl = arguments.callee;
	var cached = cl._cached;
	
	if (cl._cached) return cl._cached;
	if (!(this instanceof cl)) return new cl;
	if (typeof cl._cached == "undefined") cl._cached = this;
};

/**
 * 쿠키 이름의 배열을 반환한다.
 * @id core.$Cookie.keys
 * @return {Array} 쿠키 이름의 배열
 */
$Cookie.prototype.keys = function() {
	var ca = document.cookie.split(";");
	var re = /^\s+|\s+$/g;
	var a  = new Array;
	
	for(var i=0; i < ca.length; i++) {
		a[a.length] = ca[i].substr(0,ca[i].indexOf("=")).replace(re, "");
	}
	
	return a;
};

/**
 * 이름에 해당하는 쿠키 값을 가져온다. 값이 존재하지 않는다면 null을 반환한다.
 * @id core.$Cookie.get
 * @param {String} sName 쿠키 이름
 * @return {String} 쿠키 값
 */
$Cookie.prototype.get = function(sName) {
	var ca = document.cookie.split(/\s*;\s*/);
	var re = new RegExp("^(\\s*"+sName+"\\s*=)");
	
	for(var i=0; i < ca.length; i++) {
		if (re.test(ca[i])) return ca[i].substr(RegExp.$1.length);
	}
	
	return null;
};

/**
 * 이름에 해당하는 쿠키 값을 설정한다.
 * @id core.$Cookie.set
 * @param {String} sName 쿠키 이름
 * @param {String} sValue 쿠키값
 * @param {Number} nDays 쿠키 유효 시간(일단위)
 * @return {$Cookie} 쿠키 객체
 */
$Cookie.prototype.set = function(sName, sValue, nDays) {
	var sExpire = "";
	
	if (typeof nDays == "number") {
		sExpire = ";expires="+(new Date((new Date()).getTime()+nDays*1000*60*60*24)).toGMTString();
	}
	
	document.cookie = sName+"="+escape(sValue)+sExpire+"; path=/";
	
	return this;
};

/**
 * 이름에 해당하는 쿠키 값을 제거한다.
 * @id core.$Cookie.remove
 * @import core.$Cookie.set
 * @param {String} sName 쿠키 이름
 * @return {$Cookie} 쿠키 객체
 */
$Cookie.prototype.remove = function(sName) {
	if (this.get(sName) != null) this.set(sName, "", -1);
	
	return this;
};
/**
 * $Element 객체를 반환한다.
 * @id core.$Element
 */
function $Element(el) {
	var cl = arguments.callee;
	if (el instanceof cl) return el;
	if (!(this instanceof cl)) return new cl(el);

	this._element = $(el);
	this.tag = this._element?this._element.tagName.toLowerCase():'';

	this._queue = new Array;
}

/**
 * DOMElement 객체를 반환한다.
 * @id core.$Element.$value
 */
$Element.prototype.$value = function() {
	return this._element;
};

/**
 * 객체의 display style 속성을 조사해서 none 이면 false 를 반환한다.
 * @id core.$Element.visible
 * @import core.$Element.css
 */
$Element.prototype.visible = function() {
	return (this.css("display") != "none");
};

/**
 * 객체가 화면에 보이도록 display style 속성을 변경한다.
 * @id core.$Element.show
 */
$Element.prototype.show = function() {
	var s = this._element.style;
	var b = "block";
	var c = {p:b,div:b,form:b,h1:b,h2:b,h3:b,h4:b,ol:b,ul:b,fieldset:b,td:"table-cell",th:"table-cell",li:"list-item",table:"table",thead:"table-header-group",tbody:"table-row-group",tfoot:"table-footer-group",tr:"table-row",col:"table-column",colgroup:"table-column-group",caption:"table-caption",dl:b,dt:b,dd:b};

	try {
		if(typeof c[this.tag] == "string") {
			s.display = c[this.tag];
		} else {
			s.display = "inline";
		}
	} catch(e) {
		s.display = "block";
	}

	return this;
};

/**
 * 객체가 화면에 보이지 않도록 display style 속성을 변경한다.
 * @id core.$Element.hide
 */
$Element.prototype.hide = function() {
	this._element.style.display = "none";

	return this;
};

/**
 * 객체를 보이거나 감추도록 display 속성을 toggle 한다.
 * @id core.$Element.toggle
 * @import core.$Element[visible, show, hide]
 */
$Element.prototype.toggle = function() {
	this[this.visible()?"hide":"show"]();

	return this;
};

/**
 * 투명도 값을 가져오거나 설정한다. 첫번째 argument가 설정되어있으면 해당값으로 투명도를 설정한다.
 * 투명도 값은 0 ~ 1 사이의 실수값으로 정한다.
 * @id core.$Element.opacity
 * @import core.$Element.visible
 * @return {Number} 불투명도 실수값
 */
$Element.prototype.opacity = function(value) {
	var v,e = this._element,b=this.visible();
	if (typeof value == "number") {
		value = Math.max(Math.min(value,1),0);

		if (typeof e.filters != "undefined") {
			value = Math.ceil(value*100);
			if (typeof e.filters.alpha != "undefined") {
				e.filters.alpha.opacity = value;
			} else {
				e.style.filter = (e.style.filter + " alpha(opacity=" + value + ")");
			}
		} else {
			e.style.opacity = value;
		}

		return value;
	}

	if (typeof e.filters != "undefined") {
		v = (typeof e.filters.alpha == "undefined")?(b?100:0):e.filters.alpha.opacity;
		v = v / 100;
	} else {
		v = parseFloat(e.style.opacity);
		if (isNaN(v)) v = b?1:0;
	}

	return v;
};

/**
 * 객체를 Fade-in 효과와 함께 나타나도록 한다.
 * id core.$Element.appear
 * @import core.$Element[visible,opacity,show]
 * @param {Number} duration 나타나는 시간(초단위)
 * @param {Function} 완전히 나타나고 난 후의 콜백 함수
 */
$Element.prototype.appear = function(duration, callback) {
	var self = this;
	var op   = this.opacity();

	if (op == 1) return this;
	try { clearTimeout(this._fade_timer); } catch(e){};

	callback = callback || new Function;

	var step = (1-op) / ((duration||0.3)*100);
	var func = function(){
		op += step;
		self.opacity(op);

		if (op >= 1) {
			callback(self);
		} else {
			self._fade_timer = setTimeout(func, 10);
		}
	};

	this.show();
	func();

	return this;
};

/**
 * 객체를 Fade-out 효과와 함께 사라지도록 한다. 완전히 투명해지고 나면 display 속성이 none 으로 변한다.
 * @id core.$Element.disappear
 * @import core.$Element[visible,opacity,hide]
 * @param {Number} duration 사라지는 시간(초단위)
 * @param {Function} 완전히 사라지고 난 후의 콜백 함수
 */
$Element.prototype.disappear = function(duration, callback) {
	var self = this;
	var op   = this.opacity();

	if (op == 0) return this;
	try { clearTimeout(this._fade_timer); } catch(e){};

	callback = callback || new Function;

	var step = op / ((duration||0.3)*100);
	var func = function(){
		op -= step;
		self.opacity(op);

		if (op <= 0) {
			self.hide();
			callback(self);
		} else {
			self._fade_timer = setTimeout(func, 10);
		}
	};

	func();

	return this;
};

/**
 * 객체의 CSS 속성을 얻을 수 있다. 단, 첫번째 argument 에 얻을 속성키를 입력해야 한다.
 * 만일, 첫번째 argument 가 Object 혹은 $Hash 타입이면 반대로 CSS를 주어진 값으로 적용한다.
 * @id core.$Element.css
 * @param {String,Object} sName CSS 속성이름 혹은 설정값 객체
 * @param {String} sValue 설정값
 */
$Element.prototype.css = function(sName, sValue) {
	var e = this._element;

	if (typeof sName == "string") {
		var view;

		if (typeof sValue == "string" || typeof sValue == "number") {
			var obj = new Object;
			obj[sName] = sValue;
			sName = obj;
		} else {
			if (e.currentStyle) {
				if (sName == "cssFloat") sName = "styleFloat";
				return e.currentStyle[sName]||e.style[sName];
			} else if (window.getComputedStyle) {
				if (sName == "cssFloat") sName = "float";
				return document.defaultView.getComputedStyle(e,null).getPropertyValue(sName.replace(/([A-Z])/g,"-$1").toLowerCase())||e.style[sName];
			} else {
				if (sName == "cssFloat" && /MSIE/.test(window.navigator.userAgent)) sName = "styleFloat";
				return e.style[sName];
			}

			return null;
		}
	}


	if (typeof $H != "undefined" && sName instanceof $H) {
		sName = sName.$value();
	}

	if (typeof sName == "object") {
		var v, type;

		for(var k in sName) {
			v    = sName[k];
			type = (typeof v);
			if (type != "string" && type != "number") continue;
			if (k == "cssFloat" && navigator.userAgent.indexOf("MSIE") > -1) k = "styleFloat";
			try {
				e.style[k] = v;
			} catch(err) {
				if (k == "cursor" && v == "pointer") {
					e.style.cursor = "hand";
				} else if (("#top#left#right#bottom#").indexOf(k+"#") > 0 && (type == "number" || !isNaN(parseInt(v)))) {
					e.style[k] = parseInt(v)+"px";
				}
			}
		}
	}

	return this;
};

/**
 * 객체의 속성을 구하거나 설정한다.
 * @param {String,Object} sName 속성이름 혹은 설정값 객체
 * @param {String} sValue 설정값
 */
$Element.prototype.attr = function(sName, sValue) {
	var e = this._element;

	if (typeof sName == "string") {
		if (typeof sValue != "undefined") {
			var obj = new Object;
			obj[sName] = sValue;
			sName = obj;
		} else {
			if (sName == "class" || sName == "className") return e.className;
			return e.getAttribute(sName);
		}
	}

	if (typeof $H != "undefined" && sName instanceof $H) {
		sName = sName.$value();
	}

	if (typeof sName == "object") {
		for(var k in sName) {
			if (sValue == null) e.removeAttribute(k);
			else e.setAttribute(k, sName[k]);
		}
	}

	return this;
};

/**
 * 객체의 문서상의 offset 위치값을 반환한다. top, left 값을 전달하면 해당 값으로 위치값을 정의한다.
 * @id core.$Element.offset
 * @import core.$Element.css
 * @param {Number} nTop 문서 좌상단으로부터의 top 좌표(px)
 * @param {Number} nLeft 문서 좌상단으로부터의 left 좌표(px)
 * @return {TypePos} 문서 좌상단으로부터의 좌표(px)
 */
$Element.prototype.offset = function(nTop, nLeft) {

	var oEl = this._element;
	var oPhantom = null;

	// setter
	if (typeof nTop == 'number' && typeof nLeft == 'number') {

		if (isNaN(parseInt(this.css('top')))) this.css('top', 0);
		if (isNaN(parseInt(this.css('left')))) this.css('left', 0);

		var oPos = this.offset();
		var oGap = { top : nTop - oPos.top, left : nLeft - oPos.left };

		oEl.style.top = parseInt(this.css('top')) + oGap.top + 'px';
		oEl.style.left = parseInt(this.css('left')) + oGap.left + 'px';

		return this;

	}

	// getter
	var bSafari = /Safari/.test(navigator.userAgent);
	var bIE = /MSIE/.test(navigator.userAgent);

	var fpSafari = function(oEl) {

		var oPos = { left : 0, top : 0 };

		for (var oParent = oEl, oOffsetParent = oParent.offsetParent; oParent = oParent.parentNode; ) {

			if (oParent.offsetParent) {

				oPos.left -= oParent.scrollLeft;
				oPos.top -= oParent.scrollTop;

			}

			if (oParent == oOffsetParent) {

				oPos.left += oEl.offsetLeft + oParent.clientLeft;
				oPos.top += oEl.offsetTop + oParent.clientTop ;

				if (!oParent.offsetParent) {

					oPos.left += oParent.offsetLeft;
					oPos.top += oParent.offsetTop;

				}

				oOffsetParent = oParent.offsetParent;
				oEl = oParent;
			}
		}

		return oPos;

	};

	var fpOthers = function(oEl) {

		var oPos = { left : 0, top : 0 };

		var oDoc = oEl.ownerDocument || oEl.document || document;
		var oHtml = oDoc.documentElement;
		var oBody = oDoc.body;

		if (oEl.getBoundingClientRect) { // has getBoundingClientRect

			if (!oPhantom) {

				if (bIE && window.external) {
					
					oPhantom = { left : 2, top : 2 };

					/*
					var oBase = oDoc.createElement('div');
					oBase.style.cssText = 'position:absolute !important; left:0 !important; top:0 !important; margin:0 !important; padding:0 !important;';
					oDoc.body.insertBefore(oBase, oDoc.body.firstChild);

					oPhantom = oBase.getBoundingClientRect();
					oPhantom.left += oHtml.scrollLeft || oBody.scrollLeft;
					oPhantom.top += oHtml.scrollTop || oBody.scrollTop;

					oDoc.body.removeChild(oBase);
					*/

					oBase = null;

				} else {

					oPhantom = { left : 0, top : 0 };

				}

			}

			var box = oEl.getBoundingClientRect();
			if (oEl !== oHtml && oEl !== oBody) {

				oPos.left = box.left - oPhantom.left;
				oPos.top = box.top - oPhantom.top;
				
				oPos.left += oHtml.scrollLeft || oBody.scrollLeft;
				oPos.top += oHtml.scrollTop || oBody.scrollTop;
				
			}

		} else if (oDoc.getBoxObjectFor) { // has getBoxObjectFor

			var box = oDoc.getBoxObjectFor(oEl);
			var vpBox = oDoc.getBoxObjectFor(oHtml || oBody);

			oPos.left = box.screenX - vpBox.screenX;
			oPos.top = box.screenY - vpBox.screenY;

		} else {

			for (var o = oEl; o; o = o.offsetParent) {

				oPos.left += o.offsetLeft;
				oPos.top += o.offsetTop;

			}

			for (var o = oEl.parentNode; o; o = o.parentNode) {

				if (o.tagName == 'BODY') break;
				if (o.tagName == 'TR') oPos.top += 2;

				oPos.left -= o.scrollLeft;
				oPos.top -= o.scrollTop;

			}

		}
		
		return oPos;

	};

	return (bSafari ? fpSafari : fpOthers)(oEl);

};

/**
 * 객체의 픽셀단위 실제 너비를 구하거나 설정한다.
 * @id core.$Element.width
 * @return {Number} 객체의 실제 너비
 */
$Element.prototype.width = function(width) {
	if (typeof width == "number") {
		var e = this._element;

		e.style.width = width+"px";
		if (e.offsetWidth != width) {
			e.style.width = (width*2 - e.offsetWidth) + "px";
		}
	}

	return this._element.offsetWidth;
};

/**
 * 객체의 픽셀단위 실제 높이를 구하거나 설정한다.
 * @id core.$Element.height
 * @return {Number} 객체의 실제 녺이
 */
$Element.prototype.height = function(height) {
	if (typeof height == "number") {
		var e = this._element;

		e.style.height = height+"px";
		if (e.offsetHeight != height) {
			e.style.height = (height*2 - e.offsetHeight) + "px";
		}
	}

	return this._element.offsetHeight;
};

/**
 * 클래스 이름을 설정하거나 반환한다.
 * @id core.$Element.className
 * @param {String} 클래스 이름
 */
$Element.prototype.className = function(sClass) {
	var e = this._element;

	if (typeof sClass == "undefined") return e.className;
	e.className = sClass;

	return this;
};

/**
 * 지정한 클래스 이름이 설정되어 있는지 확인한다.
 * @id core.$Element.hasClass
 * @param {String} sClass 확인할 클래스 이름
 * @return {Boolean} 클래스 이름 설정 여부
 */
$Element.prototype.hasClass = function(sClass) {
	return (" "+this._element.className+" ").indexOf(" "+sClass+" ") > -1;
};

/**
 * 지정한 클래스 이름을 추가한다.
 * @id core.$Element.addClass
 * @param {String} sClass 추가할 클래스 이름
 * @return {$Element} 현재의 객체
 */
$Element.prototype.addClass = function(sClass) {
	var e = this._element;
	if (this.hasClass(sClass)) return this;
	e.className = (e.className+" "+sClass).replace(/^\s+/, "");
	return this;
};

/**
 * 지정한 클래스 이름을 제거한다.
 * @id core.$Element.removeClass
 * @param {String} sClass 제거할 클래스 이름
 * @return {$Element} 현재의 객체
 */
$Element.prototype.removeClass = function(sClass) {
	var e = this._element;
	e.className = (e.className+" ").replace(sClass+" ", "").replace(/\s+$/, "");

	return this;
};

/**
 * 클래스 이름을 토글한다.
 * @id core.$Element.toggleClass
 * @import core.$Element[hasClass,addClass,removeClass]
 */
$Element.prototype.toggleClass = function(sClass, sClass2) {
	sClass2 = sClass2 || "";
	if (this.hasClass(sClass)) {
		this.removeClass(sClass);
		if (sClass2) this.addClass(sClass2);
	} else {
		this.addClass(sClass);
		if (sClass2) this.removeClass(sClass2);
	}

	return this;
};

/**
 * 객체의 text값을 반환한다. sText 값이 설정되면 설정된 값으로 엘리먼트의 text를 변경한다.
 * @id core.$Element.text
 * @param {String} sText 설정할 텍스트
 */
$Element.prototype.text = function(sText) {
	var prop = (typeof this._element.innerText != "undefined")?"innerText":"textContent";

	if (typeof sText == "string") {
		this._element[prop] = sText;
		return this;
	}

	return this._element[prop];
};

/**
 * 객체 내부의 html을 반환한다. sHTML 값이 설정되면 전달받은 값으로 내부 html을 설정한다.
 * @id core.$Element.html
 * @param {String} sHTML 설정할 HTML 문자열
 * @return {String} 내부 HTML
 */
$Element.prototype.html = function(sHTML) {
	if (typeof sHTML == "string") {

		var oEl = this._element;
		var bBugAgent = $Agent().navigator().ie || ($Agent().navigator().firefox && !oEl.parentNode);

		if (bBugAgent) {

			/*
				IE 나 FireFox 의 일부 상황에서 SELECT 태그나 TABLE, TR, THEAD, TBODY 태그에 innerHTML 을 셋팅해도
				문제가 생기지 않도록 보완 - hooriza
			*/
			var sId = 'R' + new Date().getTime() + parseInt(Math.random() * 100000);
			var oDoc = oEl.ownerDocument || oEl.document || document;

			var oDummy;
			var sTag = oEl.tagName.toLowerCase();

			switch (sTag) {
			case 'select':
			case 'table':
				oDummy = $('<div>');
				oDummy.innerHTML = '<' + sTag + ' class="' + sId + '">' + sHTML + '</' + sTag + '>';
				break;

			case 'tr':
			case 'thead':
			case 'tbody':
				oDummy = $('<div>');
				oDummy.innerHTML = '<table><' + sTag + ' class="' + sId + '">' + sHTML + '</' + sTag + '></table>';
				break;

			default:
				oEl.innerHTML = sHTML;
				break;
			}

			if (oDummy) {

				var oFound;
				for (oFound = oDummy.firstChild; oFound; oFound = oFound.firstChild)
					if (oFound.className == sId) break;

				if (oFound) {

					for (var oChild; oChild = oEl.firstChild;) oChild.removeNode(true); // innerHTML = '';

					for (var oChild = oFound.firstChild; oChild; oChild = oFound.firstChild)
						oEl.appendChild(oChild);

					oDummy.removeNode && oDummy.removeNode(true);

				}

				oDummy = null;

			}

		} else {

			oEl.innerHTML = sHTML;

		}

		return this;

	}

	return this._element.innerHTML;
};

/**
 * 객체의 outerHTML 을 반환한다.
 * @id core.$Element.outerHTML
 * @return {String} 외부 HTML
 */
$Element.prototype.outerHTML = function() {
	var e = this._element;
	if (typeof e.outerHTML != "undefined") return e.outerHTML;

	var div = $("<div>");
	var par = e.parentNode;

	par.insertBefore(div, e);
	div.style.display = "none";
	div.appendChild(e);

	var s = div.innerHTML;
	par.insertBefore(e, div);
	par.removeChild(div);

	return s;
};

/**
 * 객체를 HTML 로 표현한 문자열을 반환한다. outerHTML과 동일하다.
 * @id core.$Element.toString
 * @import core.$Element.outerHTML
 * @return {String} 외부 HTML
 */
$Element.prototype.toString = $Element.prototype.outerHTML;

/**
 * 현재 객체의 마지막 자식노드로 새 객체를 추가한다.
 * @id core.$Element.append
 */
$Element.prototype.append = function(oElement) {
	var o = $Element(oElement).$value();

	this._element.appendChild(o);

	return $Element(o);
};

/**
 * 현재 객체의 첫번째 자식노드로 새 객체를 추가한다.
 * @id core.$Element.prepend
 */
$Element.prototype.prepend = function(oElement) {
	var e = this._element;
	var o = $Element(oElement).$value();

	if (e.childNodes.length > 0) {
		e.insertBefore(o, e.childNodes[0]);
	} else {
		e.appendChild(o);
	}

	return $Element(o);
};

/**
 * 현재의 객체를 다른 노드로 대체한다.
 * @id core.$Element.replace
 */
$Element.prototype.replace = function(oElement) {
	var e = this._element;
	var o = $Element(oElement).$value();

	e.parentNode.insertBefore(o, e);
	e.parentNode.removeChild(e);

	return $Element(o);
};

/**
 * 현재 객체를 지정한 객체의 마지막 자식노드로 추가한다.
 * @id core.$Element.appendTo
 */
$Element.prototype.appendTo = function(oElement) {
	var o = $Element(oElement).$value();

	o.appendChild(this._element);

	return this;
};

/**
 * 현재 객체를 지정한 객체의 첫번째 자식노드로 추가한다.
 * @id core.$Element.prependTo
 */
$Element.prototype.prependTo = function(oElement) {
	var o = $Element(oElement).$value();

	if (o.childNodes.length > 0) {
		o.insertBefore(this._element, o.childNodes[0]);
	} else {
		o.appendChild(this._element);
	}

	return this;
};

/**
 * 현재 객체의 앞에 지정한 객체를 삽입한다.
 * @id core.$Element.before
 */
$Element.prototype.before = function(oElement) {
	var o = $Element(oElement).$value();

	this._element.parentNode.insertBefore(o, this._element);

	return $Element(o);
};

/**
 * 현재 객체의 뒤에 지정한 객체를 삽입한다.
 * @id core.$Element.after
 * @import core.$Element.before
 */
$Element.prototype.after = function(oElement) {
	var o = this.before(oElement);
	o.before(this);

	return o;
};

/**
 * 전체 혹은 조건에 맞는 부모 객체를 배열로 반환한다. 인자를 전달하지 않으면 바로 상위의 부모만 반환한다.
 * @id core.$Element.parent
 * @param {pFunc}  부모 노드 중 결과에 포함할 노드를 선택하는 콜백함수, 조건에 맞으면 true를 반환하면 된다. 결과 필터링을 원치 않으면 null을 대입한다.
 * @param {Number} limit 탐색할 상위 노드 깊이
 */
$Element.prototype.parent = function(pFunc, limit) {
	var e = this._element;
	var a = [], p = null;

	if (typeof pFunc == "undefined") return $Element(e.parentNode);
	if (typeof limit == "undefined" || limit == 0) limit = -1;

	while (e.parentNode && limit-- != 0) {
		p = $Element(e.parentNode);
		if (e.parentNode == document.documentElement) break;
		if (!pFunc || (pFunc && pFunc(p))) a[a.length] = p;

		e = e.parentNode;
	}

	return a;
};

/**
 * 전체 혹 조건에 맞는 자식 객체를 $Element의 배열로 반환한다. 인자를 전달하지 않으면 바로 하위의 자식노드를 반환한다.
 * @id core.$Element.child
 * @param {pFunc}  자식 노드 중 결과에 포함할 노드를 선택하는 콜백함수, 조건에 맞으면 true를 반환하면 된다.
 * @param {Number} limit 탐색할 하위 노드 깊이
 * @import $A.map
 */
$Element.prototype.child = function(pFunc, limit) {
	var e = this._element;
	var a = [], c = null, f = null;

	if (typeof pFunc == "undefined") return $A(e.childNodes).filter(function(v){ return v.nodeType == 1}).map(function(v){ return $Element(v) }).$value();
	if (typeof limit == "undefined" || limit == 0) limit = -1;

	(f = function(el, lim){
		var ch = null, o = null;

		for(var i=0; i < el.childNodes.length; i++) {
			ch = el.childNodes[i];
			if (ch.nodeType != 1) continue;

			o = $Element(el.childNodes[i]);
			if (!pFunc || (pFunc && pFunc(o))) a[a.length] = o;
			if (lim != 0) f(el.childNodes[i], lim-1);
		}
	})(e, limit-1);

	return a;
};

/**
 * 전체 혹 조건에 맞는 이전 형제객체를 $Element의 배열로 반환한다. 인자를 전달하지 않으면 바로 앞의 형제노드를 반환한다.
 * @id core.$Element.prev
 * @param {pFunc} 형제 노드 중 결과에 포함할 노드를 선택하는 콜백함수, 조건에 맞으면 true를 반환하면 된다.
 */
$Element.prototype.prev = function(pFunc) {
	var e = this._element;
	var a = [];

	if (typeof pFunc == "undefined") return $Element(e.previousSibling);

	while(e && e.nextSibling) {
		o = e.previousSibling;
		if (!pFunc || (pFunc && pFunc(o))) a[a.length] = $Element(o);
		e = e.previousSibling;
	}

	return a;
};

/**
 * 전체 혹 조건에 맞는 다음 형제객체를 $Element의 배열로 반환한다. 인자를 전달하지 않으면 바로 앞의 형제노드를 반환한다.
 * @id core.$Element.next
 * @param {pFunc} 형제 노드 중 결과에 포함할 노드를 선택하는 콜백함수, 조건에 맞으면 true를 반환하면 된다.
 */
$Element.prototype.next = function(pFunc) {
	var e = this._element;
	var a = [], o = null;

	if (typeof pFunc == "undefined") return $Element(e.nextSibling);

	while(e && e.nextSibling) {
		o = e.nextSibling;
		if (!pFunc || (pFunc && pFunc(o))) a[a.length] = $Element(o);
		e = e.nextSibling;
	}

	return a;
};

/**
 * 현재 객체가 주어진 객체의 자식인지 확인한다.
 * @id core.$Element.isChildOf
 * @param {HTMLElement,$Element} 체크할 HTMLElement 혹은 $Element 객체
 */
$Element.prototype.isChildOf = function(element) {
	var e  = this._element;
	var el = $Element(element).$value();

	while(e && e.parentNode) {
		e = e.parentNode;
		if (e == el) return true;
	}
	return false;
};

/**
 * 현재 객체가 주어진 객체의 부모인지 확인한다.
 * @id core.$Element.isParentOf
 * @param {HTMLElement,$Element} 체크할 HTMLElement 혹은 $Element 객체
 */
$Element.prototype.isParentOf = function(element) {
	var el = $Element(element).$value();

	while(el && el.parentNode) {
		el = el.parentNode;
		if (this._element == el) return true;
	}
	return false;
};

/**
 * 이벤트를 실행한다.
 * @id core.$Element.fireEvent
 * @param {String} 실행할 이벤트 이름. on 접두사는 생략한다.
 */
$Element.prototype.fireEvent = function(sEvent) {
	function IE(sEvent) {
		sEvent = (sEvent+"").toLowerCase();
		this._element.fireEvent("on"+sEvent);
		return this;
	};

	function DOM2(sEvent) {
		var sType = "HTMLEvents";
		sEvent = (sEvent+"").toLowerCase();

		if (sEvent == "click" || sEvent.indexOf("mouse") == 0) {
			sType = "MouseEvents";
			if (sEvent == "mousewheel") sEvent = "dommousescroll";
		} else if (sEvent.indexOf("key") == 0) {
			sType = "KeyEvents";
		}

		var evt   = document.createEvent(sType);

		evt.initEvent(sEvent, true, true);

		this._element.dispatchEvent(evt);
		return this;
	};

	$Element.prototype.fireEvent = (typeof this._element.dispatchEvent != "undefined")?DOM2:IE;

	return this.fireEvent(sEvent);
};

/**
 * 현재 객체의 하위 노드를 모두 제거한다.
 * @id core.$Element.empty
 */
$Element.prototype.empty = function() {
	this._element.innerHTML = "";
	return this;
};

/**
 * 현재 객체를 부모 노드로부터 제거한다.
 * @id core.$Element.leave
 */
$Element.prototype.leave = function() {
	var e = this._element;

	if (e.parentNode) {
		e.parentNode.removeChild(e);
	}

	return this;
};

/**
 * 주어진 객체로 현재 객체를 감싼다.
 * @id core.$Element.wrap
 */
$Element.prototype.wrap = function(wrapper) {
	var e = this._element;

	wrapper = $(wrapper);
	if (e.parentNode) {
		e.parentNode.insertBefore(wrapper, e);
	}
	wrapper.appendChild(e);

	return this;
};

/**
 * 목록의 객체들을 부모 노드로부터 제거한다.
 * @id core.$Element.ellipsis
 */
$Element.prototype.ellipsis = function(stringTail) {
	stringTail = stringTail || "...";

	var txt   = this.text();
	var len   = txt.length;
	var cur_h = this.height();
	var i     = 0;
	var h     = this.text('A').height();

	if (cur_h < h * 1.5) return this.text(txt);

	cur_h = h;
	while(cur_h < h * 1.5) {
		i += Math.max(Math.ceil((len - i)/2), 1);
		cur_h = this.text(txt.substring(0,i)+stringTail).height();
	}

	while(cur_h > h * 1.5) {
		i--;
		cur_h = this.text(txt.substring(0,i)+stringTail).height();
	}
};
/**
 * 함수 객체를 리턴한다.
 * @id core.$Fn
 * @param {Function} 함수 객체
 * @import core.$Fn.toFunction
 */
function $Fn(func, thisObject) {
	var cl = arguments.callee;
	if (func instanceof cl) return func;
	if (!(this instanceof cl)) return new cl(func, thisObject);

	this._events = {};
	this._tmpElm = null;

	if (typeof func == "function") {
		this._func = func;
		this._this = thisObject;
	} else if (typeof func == "string" && typeof thisObject == "string") {
		this._func = new Function(func, thisObject);
	}
}

/**
 * Function 객체를 반환한다.
 * @return {Function} 함수 객체
 */
$Fn.prototype.$value = function() {
	return this._func;
};

/**
 * 함수를 thisObject 의 메소드로 묶은 Function 을 반환한다.
 * @id core.$Fn.bind
 * @import core.$A
 */
$Fn.prototype.bind = function() {
	var a = $A(arguments).$value();
	var f = this._func;
	var t = this._this;

	var b = function() {
		var args = $A(arguments).$value();

		// fix opera concat bug
		if (a.length) args = a.concat(args);

		return f.apply(t, args);
	};

	return b;
};

/**
 *
 * @id core.$Fn.bindForEvent
 * @import core.$A
 * @import core.$Event
 */
$Fn.prototype.bindForEvent = function() {
	var a = arguments;
	var f = this._func;
	var t = this._this;
	var m = this._tmpElm || null;

	var b = function(e) {
		var args = $A(a);
		if (typeof e == "undefined") e = window.event;

		if (typeof e.currentTarget == "undefined") {
			e.currentTarget = m;
		}

		args.unshift($Event(e));

		return f.apply(t, args.$value());
	};

	return b;
};

/**
 * 함수를 특정 객체의 이벤트에 추가한다
 * @id core.$Fn.attach
 * @import core.$Fn[detach, gc]
 */
$Fn.prototype.attach = function(oElement, sEvent) {
	var f;
	
	if ((oElement instanceof Array) || ($A && (oElement instanceof $A) && (oElement=oElement.$value()))) {
		for(var i=0; i < oElement.length; i++) {
			this.attach(oElement[i], sEvent);
		}
		return this;
	}

	if ($Element && oElement instanceof $Element) {
		oElement = oElement.$value();
	}

	oElement = $(oElement);
	sEvent   = sEvent.toLowerCase();
	
	this._tmpElm = oElement;
	f = this.bindForEvent();
	this._tmpElm = null;

	if (typeof oElement.attachEvent != "undefined") {
		oElement.attachEvent("on"+sEvent, f);
	} else {
		if (sEvent == "mousewheel") sEvent = "DOMMouseScroll";

		if (sEvent == "DOMMouseScroll" && navigator.userAgent.indexOf("WebKit") > 0) {
			var events = "__jindo_wheel_events";

			if (typeof oElement[events] == "undefined") oElement[events] = new Array;
			if (typeof oElement.onmousewheel == "object") {
				oElement.onmousewheel = function(evt) {
					if (!this[events]) return;
					for(var i=0; i < this[events].length; i++) {
						this[events][i](evt);
					}
				}
			}

			oElement[events][oElement[events].length] = f;
		} else {
			oElement.addEventListener(sEvent, f, false);
		}
	}

	var key = "$"+$Fn.gc.count++;
	var inf = {element:oElement, event:sEvent, func:f};
	
	$Fn.gc.pool[key] = this._events[key] = inf;

	return this;
};

/**
 * 함수를 특정 객체의 이벤트에서 제거한다
 * @id core.$Fn.detach
 * @import core.$Fn[attach, gc]
 */
$Fn.prototype.detach = function(oElement, sEvent) {
	if ((oElement instanceof Array) || ($A && (oElement instanceof $A) && (oElement=oElement.$value()))) {
		for(var i=0; i < oElement.length; i++) {
			this.detach(oElement[i], sEvent);
		}
		return this;
	}

	if ($Element && oElement instanceof $Element) {
		oElement = oElement.$value();
	}

	oElement = $(oElement);
	sEvent   = sEvent.toLowerCase();
	
	var e = this._events;
	var f = null;
	
	for(var key in e) {
		try {
			if (e[key].element !== oElement || e[key].event !== sEvent) continue;
			f = e[key].func;
			
			delete e[key];
			delete $Fn.gc.pool[key];
			break;
		} catch(e){
		}
	}

	if (typeof oElement.detachEvent != "undefined") {
		oElement.detachEvent("on"+sEvent, f);
	} else {
		if (sEvent.toLowerCase() == "mousewheel") sEvent = "DOMMouseScroll";

		if (sEvent == "DOMMouseScroll" && navigator.userAgent.indexOf("WebKit") > 0) {
			var events = "__jindo_wheel_events", found = false;
			if (!oElement[events]) return;
			for(var i=0; i < oElement[events].length; i++) {
				if (oElement[events][i] == f) {
					found = true;
				} else if (found) {
					oElement[events][i-1] = oElement[events][i];
				}
			}
			if (oElement[events].length) oElement[events].length--;
		} else {
			oElement.removeEventListener(sEvent, f, false);
		}
	}

	return this;
};

/**
 * 정해진 시간 이후에 정해진 인자로 함수를 호출한다.
 * @id core.$Fn.delay
 * @import core.$Fn.bind
 */
$Fn.prototype.delay = function(nSec, args) {
	if (typeof args == "undefined") args = [];
	setTimeout(this.bind.apply(this, args), nSec*1000);
	
	return this;
};

/**
 * Window가 종료될 때, DOM Element 에 할당된 이벤트 핸들러를 제거한다.
 * @id core.$Fn.gc
 * @import core.$Fn.gcinit
 */
$Fn.gc = function() {
	var p = $Fn.gc.pool;
	
	for(var key in p) {
		try { $Fn(p[key].func).detach(p[key].element, p[key].event)	}catch(e){};
	}
};

$Fn.gc.count = 0;

$Fn.gc.pool = new Array;
if (typeof window != "undefined") {
	$Fn($Fn.gc).attach(window, "unload");
}

/**
 * JavaScript Core 이벤트 객체로부터 $Event 객체를 생성한다.
 * evt 를 $Event 객체의 인스턴스라고 하면, evt.element 로 이벤트가 실행된 객체를 알 수 있다.
 * @id core.$Event
 */
function $Event(e) {
	var cl = arguments.callee;
	if (e instanceof cl) return e;
	if (!(this instanceof cl)) return new cl(e);

	if (typeof e == "undefined") e = window.event;
	if (e === window.event && document.createEventObject) e = document.createEventObject(e);

	this._event = e;
	this._globalEvent = window.event;

	this.type = e.type.toLowerCase();
	if (this.type == "dommousescroll") {
		this.type = "mousewheel";
	}

	this.canceled = false;

	this.element = e.target || e.srcElement;
	this.currentElement = e.currentTarget;
	this.relatedElement = null;

	if (typeof e.relatedTarget != "undefined") {
		this.relatedElement = e.relatedTarget;
	} else if(e.fromElement && e.toElement) {
		this.relatedElement = e[(this.type=="mouseout")?"toElement":"fromElement"];
	}
}

/**
 * 마우스 이벤트 정보 객체를 반환한다.
 * @id core.$Event.mouse
 */
$Event.prototype.mouse = function() {
	var e    = this._event;
	var delta = 0;
	var left  = (e.which&&e.button==0)||!!(e.button&1);
	var mid   = (e.which&&e.button==1)||!!(e.button&4);
	var right = (e.which&&e.button==2)||!!(e.button&2);

	if (e.wheelDelta) {
		delta = e.wheelDelta / 120;
	} else if (e.detail) {
		delta = -e.detail / 3;
	}

	return {
		delta  : delta,
		left   : left,
		middle : mid,
		right  : right
	};
};

/**
 * 키보드 이벤트 정보 객체를 반환한다.
 * @id core.$Event.key
 */
$Event.prototype.key = function() {
	var e     = this._event;
	var k     = e.keyCode;

	return {
		keyCode : k,
		alt     : e.altKey,
		ctrl    : e.ctrlKey,
		meta    : e.metaKey,
		shift   : e.shiftKey,
		up      : (k == 38),
		down    : (k == 40),
		left    : (k == 37),
		right   : (k == 39),
		enter   : (k == 13)
	}
};

/**
 * 커서 위치 정보 객체를 반환한다.
 * @id core.$Event.position
 */
$Event.prototype.pos = function() {
	var e   = this._event;
	var b   = document.body;
	var de  = document.documentElement;
	var pos = [b.scrollLeft || de.scrollLeft,b.scrollTop || de.scrollTop];

	return {
		clientX : e.clientX,
		clientY : e.clientY,
		pageX   : 'pageX' in e ? e.pageX : e.clientX+pos[0]-b.clientLeft,
		pageY   : 'pageY' in e ? e.pageY : e.clientY+pos[1]-b.clientTop,
		layerX  : 'offsetX' in e ? e.offsetX : e.layerX - 1,
		layerY  : 'offsetY' in e ? e.offsetY : e.layerY - 1
	};
};

/**
 * 현재의 이벤트를 중지한다.
 * @id core.$Event.stop
 */
$Event.prototype.stop = function() {
	var e = (window.event && window.event == this._globalEvent)?this._globalEvent:this._event;
	
	this.canceled = true;

	if (typeof e.preventDefault != "undefined") e.preventDefault();
	if (typeof e.stopPropagation != "undefined") e.stopPropagation();

	e.returnValue = false;
	e.cancelBubble = true;

	return this;
};
/**
 * $ElementList 객체를 반환한다.
 * @id core.$ElementList
 */
function $ElementList(els) {
	var cl = arguments.callee;
	if (els instanceof cl) return els;
	if (!(this instanceof cl)) return new cl(els);
	
	if (els instanceof Array || ($A && els instanceof $A)) {
		els = $A(els);
	} else if (typeof els == "string" && cssquery) {
		els = $A(cssquery(els));
	} else {
		els = $A();
	}

	this._elements = els.map(function(v,i,a){ return $Element(v) });
}

$ElementList.prototype.get = function(idx) {
	return this._elements[idx];
};

$ElementList.prototype.getFirst = function() {
	return this.get(0);
};

$ElementList.prototype.getLast = function() {
	return this.get(Math.Max(this._elements.length-1,0));
};

(function(proto){
	var setters = 'show,hide,toggle,addClass,removeClass,toggleClass,fireEvent,leave,';
	setters += 'empty,appear,disappear,className,width,height,text,html,css,attr';
	
	$A(setters.split(',')).forEach(function(name){
		proto[name] = function() {
			var args = $A(arguments).$value();
			this._elements.forEach(function(el){
				el[name].apply(el, args);
			});
			
			return this;
		}
	});
	
	$A(['appear','disapeear']).forEach(function(name){
		proto[name] = function(duration, callback) {
			var len  = this._elements.length;
			var self = this;
			this._elements.forEach(function(el,idx){
				if(idx == len-1) el[name](duration, function(){callback(self)});
				else el[name](duration);
			});
		}
	});
})($ElementList.prototype);
/**
 * 문자열을 다루는 클래스
 * @id core.$S
 */
function $S(str) {
	var cl = arguments.callee;

	if (typeof str == "undefined") str = "";
	if (str instanceof cl) return str;
	if (!(this instanceof cl)) return new cl(str);

	this._str = str+"";
}

/**
 * String 객체를 반환한다.
 * @id core.$S.$value
 */
$S.prototype.$value = function() {
	return this._str;
};

/**
 * String 객체를 반환한다.
 * @id core.$S.toString
 */
$S.prototype.toString = $S.prototype.$value;

/**
 * 문자열의 양 끝 공백을 제거한다.
 * @id core.$S.trim
 */
$S.prototype.trim = function() {
	return $S(this._str.replace(/^\s+|\s+$/g, ""));
};

/**
 * HTML 특수문자를 엔티티 형식으로 변환한다.
 * @id core.$S.escapeHTML
 */
$S.prototype.escapeHTML = function() {
	var entities = {'"':'quot','&':'amp','<':'lt','>':'gt'};
	var s = this._str.replace(/[<>&"]/g, function(m0){
		return entities[m0]?'&'+entities[m0]+';':m0;
	});
	return $S(s);
};

/**
 * 문자열에서 XML/HTML 태그를 제거한다.
 * @id core.$S.stripTags
 */
$S.prototype.stripTags = function() {
	return $S(this._str.replace(/<\/?(?:h[1-5]|[a-z]+(?:\:[a-z]+)?)[^>]*>/ig, ''));
};

/**
 * 문자열을 주어진 숫자만큼 반복한다.
 * @id core.$S.times
 */
$S.prototype.times = function(nTimes) {
	var buf = [];
	for(var i=0; i < nTimes; i++) {
		buf[buf.length] = this._str;
	}

	return $S(buf.join(''));
};

/**
 * HTML 엔티티 문자열을 ASCII문자열로 변환한다.
 * @id core.$S.unescapeHTML
 */
$S.prototype.unescapeHTML = function() {
	var entities = {'quot':'"','amp':'&','lt':'<','gt':'>'};
	var s = this._str.replace(/&([a-z]+);/g, function(m0,m1){
		return entities[m1]?entities[m1]:m0;
	});
	return $S(s);
};

/**
 * 문자열을 겹따옴표에 포함될 수 있는 ASCII문자열로 이스케이프 처리한다.
 * @id core.$S.escape
 */
$S.prototype.escape = function() {
	var s = this._str.replace(/([\u0080-\uFFFF]+)|[\n\r\t"'\\]/g, function(m0,m1,_){
		if(m1) return escape(m1).replace(/%/g,'\\');
		return (_={"\n":"\\n","\r":"\\r","\t":"\\t"})[m0]?_[m0]:"\\"+m0;
	});

	return $S(s);
};

/**
 * 문자열의 실제 bytes수를 반환한다. 현재는 utf-8과 그 밖의 문자셋으로만 구분한다.
 * @id core.$S.bytes
 */
$S.prototype.bytes = function() {
	var uni_bytes = 2, bytes = 0, len = this._str.length;
	var charset = ((document.charset || document.characterSet || document.defaultCharset)+"").toLowerCase();

	if (charset == "utf-8") uni_bytes = 3;

	for(var i=0; i < len; i++) {
		bytes += (this._str.charCodeAt(i) > 128)?uni_bytes:1;
	}

	return bytes;
};

/**
 * URL 쿼리 스트링을 객체 형태로 파싱합니다.
 * @id core.$S.parseString
 */
$S.prototype.parseString = function() {
	var str = this._str.split(/&/g), pos, key, val, buf = {};

	for(var i=0; i < str.length; i++) {
		key = str[i].substring(0, pos=str[i].indexOf("="));
		val = decodeURIComponent(str[i].substring(pos+1));

		if (key.substr(key.length-2,2) == "[]") {
			key = key.substring(0, key.length-2);
			if (typeof buf[key] == "undefined") buf[key] = [];
			buf[key][buf[key].length] = val;
		} else {
			buf[key] = val;
		}
	}
	
	return buf;
};

/**
 * 형식 문자열을 주어진 인자에 맞게 반환합니다.
 * @id core.$S.format
 * @import core.$S.times
 */
$S.prototype.format = function() {
	var args = arguments;
	var idx  = 0;
	var s = this._str.replace(/%([ 0])?(-)?([1-9][0-9]*)?([bcdsoxX])/g, function(m0,m1,m2,m3,m4){
		var a = args[idx++];
		var ret = "", pad = "";

		m3 = m3?+m3:0;

		if (m4 == "s") {
			ret = a+"";
		} else if (" bcdoxX".indexOf(m4) > 0) {
			if (typeof a != "number") return "";
			ret = (m4 == "c")?String.fromCharCode(a):a.toString(({b:2,d:10,o:8,x:16,X:16})[m4]);
			if (" X".indexOf(m4) > 0) ret = ret.toUpperCase();
		}

		if (ret.length < m3) pad = $S(m1||" ").times(m3 - ret.length).toString();
		(m2 == '-')?(ret+=pad):(ret=pad+ret);

		return ret;
	});

	return $S(s);
};

/**
 * @author hooriza (ajaxUI3 team)
 */

/**
 * $Document 객체를 반환한다.
 * @id core.$Document
 */
function $Document() {
	var cl = arguments.callee;

	if (this instanceof cl) {
		this._docKey = this.renderingMode() == 'Standards' ? 'documentElement' : 'body';
		return;
	}
	
	if (cl._singleton) return cl._singleton;
	return (cl._singleton = new cl());
};

/**
 * 문서의 실제 가로, 세로 크기를 구한다
 * @id core.$Document.scrollSize
 * @import core.$Agent.navigator
 * @import core.$Document.clientSize
 */
$Document.prototype.scrollSize = function() {

	var oBrowser = $Agent().navigator();

	var oDoc = document[this._docKey];
	if (oBrowser.opera || oBrowser.safari) oDoc = document.body;
 
	// IE6 미만이면
	if (oBrowser.ie && oBrowser.version < 6) {
	 
		var aOld = [ oDoc.scrollLeft, oDoc.scrollTop ];
		var oClient = this.clientSize();
	 
		oDoc.scrollLeft = 999999;
		oDoc.scrollTop = 999999;
	 
		var aRet = {
			width : oDoc.scrollLeft + oClient.width,
			height : oDoc.scrollTop + oClient.height
		};
	 
		oDoc.scrollLeft = aOld[0];
		oDoc.scrollTop = aOld[1];
	 
		return aRet;
	 
	}
 
	return {
		width : Math.max(oDoc.scrollWidth, oDoc.clientWidth),
		height : Math.max(oDoc.scrollHeight, oDoc.clientHeight)
	};

};

/**
 * 브라우저에서 보이는 문서의 가로, 세로 크기를 구한다
 * @id core.$Document.clientSize
 */
$Document.prototype.clientSize = function() {

	var oDoc = document[this._docKey];
 
	return {
		width : oDoc.clientWidth,
		height : oDoc.clientHeight
	};

};

/**
 * 문서의 렌더링 방식을 얻는다
 * @id core.$Document.renderingMode
 * @import core.$Agent.navigator
 */
$Document.prototype.renderingMode = function() {

	var oBrowser = $Agent().navigator();
	var sRet;

	if ('compatMode' in document)
		sRet = document.compatMode == 'CSS1Compat' ? 'Standards' : (oBrowser.ie ? 'Quirks' : 'Almost');
	else
		sRet = oBrowser.safari ? 'Standards' : 'Quirks';

	return sRet;

};

/**
 * @author hooriza (ajaxUI3 team)
 */

/**
 * $Form 객체를 반환한다.
 * @id core.$Form
 */
function $Form(el) {
	var cl = arguments.callee;
	if (el instanceof cl) return el;
	if (!(this instanceof cl)) return new cl(el);
	
	el = $(el);
	
	if (!el.tagName || el.tagName.toUpperCase() != 'FORM') throw new Error('The element should be a FORM element');
	this._form = el;
}

/**
 * 원래 <form> 엘리먼트의 객체를 얻어온다
 * @id core.$Form.$value
 */
$Form.prototype.$value = function() {
	return this._form;
};

/**
 * 특정 또는 전체 입력요소를 문자열 형태로 반환한다.
 * @id core.$Form.serialize
 * @import core.$Form.element, core.$Form.value, core.$A.forEach, core.$H.toQueryString
 */
$Form.prototype.serialize = function() {

 	var self = this;
 	var oRet = {};
 	
 	var nLen = arguments.length;
 	var fpInsert = function(sKey) {
 		var sVal = self.value(sKey);
 		if (typeof sVal != 'undefined') oRet[sKey] = sVal;
 	};
 	
 	if (nLen == 0) 
	 	$A(this.element()).forEach(function(o) { if (o.name) fpInsert(o.name); });
 	else
 		for (var i = 0; i < nLen; i++) fpInsert(arguments[i]);
 	
	return $H(oRet).toQueryString();
	
};

/**
 * 특정 또는 전체 입력요소를 반환한다.
 * @id core.$Form.element
 */
$Form.prototype.element = function(sKey) {

	if (arguments.length > 0)
		return this._form[sKey];
	
	return this._form.elements;
	
};

/**
 * 입력 요소의 활성화 여부를 얻거나 설정한다.
 * @id core.$Form.enable
 * @import core.$H.forEach, core.$A.forEach, core.$A.Break, core.$Form.element
 */
$Form.prototype.enable = function() {
	
	var sKey = arguments[0];

	if (typeof sKey == 'object') {
		
		var self = this;
		$H(sKey).forEach(function(bFlag, sKey) { self.enable(sKey, bFlag); });
		return this;
		
	}
	
	var aEls = this.element(sKey);
	if (!aEls) return this;
	aEls = aEls.nodeType == 1 ? [ aEls ] : aEls;
	
	if (arguments.length < 2) {
		
		var bEnabled = true;
		$A(aEls).forEach(function(o) { if (o.disabled) {
			bEnabled = false;
			$A.Break();
		}});
		return bEnabled;
		
	} else { // setter
		
		var sFlag = arguments[1];
		$A(aEls).forEach(function(o) { o.disabled = !sFlag; });
		
		return this;
		
	}
	
};

/**
 * 입력 요소의 값을 얻거나 설정한다.
 * @id core.$Form.value
 * @import core.$H.forEach, core.$A.forEach, core.$Form.element
 */
$Form.prototype.value = function(sKey) {
	
	if (typeof sKey == 'object') {
		
		var self = this;
		$H(sKey).forEach(function(bFlag, sKey) { self.value(sKey, bFlag); });
		return this;
		
	}
	
	var aEls = this.element(sKey);
	if (!aEls) throw new Error('The element is not exist');
	aEls = aEls.nodeType == 1 ? [ aEls ] : aEls;
	
	if (arguments.length > 1) { // setter
		
		var sVal = arguments[1];
		
		$A(aEls).forEach(function(o) {
			
			switch (o.type) {
			case 'radio':
			case 'checkbox':
				o.checked = (o.value == sVal);
				break;
				
			case 'select-one':
				var nIndex = -1;
				for (var i = 0, len = o.options.length; i < len; i++)
					if (o.options[i].value == sVal) nIndex = i;
				o.selectedIndex = nIndex;

				break;
				
			default:
				o.value = sVal;
				break;
			}
			
		});
		
		return this;
	}

	// getter
	
	var aRet = [];
	
	$A(aEls).forEach(function(o) {
		
		switch (o.type) {
		case 'radio':
		case 'checkbox':
			if (o.checked) aRet.push(o.value);
			break;
		
		case 'select-one':
			if (o.selectedIndex != -1) aRet.push(o.options[o.selectedIndex].value);
			break;
			
		default:
			aRet.push(o.value);
			break;
		}
		
	});
	
	return aRet.length > 1 ? aRet : aRet[0];
	
};

/**
 * 폼을 서밋한다.
 * @id core.$Form.submit
 */
$Form.prototype.submit = function() {
	
	this._form.submit();
	return this;
	
};

/**
 * 폼을 리셋한다.
 * @id core.$Form.reset
 */
$Form.prototype.reset = function() {
	
	this._form.reset();
	return this;
	
};

/**
 * 템플릿을 실행한다.
 * @id core.$Template
 */
function $Template(str) {
    var obj = null;
    var cl  = arguments.callee;

    if (str instanceof cl) return str;
    if (!(this instanceof cl)) return new cl(str);

    if(typeof str == "undefined") str = "";
    else if((obj=$(str)) && obj.tagName.toUpperCase() == "TEXTAREA") {
            str = obj.value.replace(/^\s+|\s+$/g,"");
    }

    this._str = str+"";
}
$Template.splitter = /(?!\\)[\{\}]/g;
$Template.pattern  = /^(?:if (.+)|elseif (.+)|for (?:(.+)\:)?(.+) in (.+)|(else)|\/(if|for)|=(.+))$/;

/**
 * 템플릿 해석을 실행한다.
 * @id core.$Template.process
 * @param {Object} data 변수 및 함수 데이터
 */
$Template.prototype.process = function(data) {
    var tpl = this._str.split($Template.splitter), i = tpl.length;
    var map = {'"':'\\"','\\':'\\\\','\n':'\\n','\r':'\\r','\t':'\\t','\f':'\\f'};
    var reg = [/([a-zA-Z_][\w\.]*)/g, /[\n\r\t\f"\\]/g, /^\s+/, /\s+$/];
    var cb  = ["d.$1", function(m){return map[m]||m},"",""];
    var stm = [];

    // no pattern
    if(i<2) return tpl;

    while(i--) {
        if(i%2) {
            tpl[i] = tpl[i].replace($Template.pattern, function(){
                var m = arguments;

                // variables
                if(m[8]) return 's[s.length]=d.'+m[8]+';';

                // if
                if(m[1]) {
                    return 'if('+m[1].replace(reg[0],cb[0])+'){';
                }

                // else if
                if(m[2]) return '}else if('+m[2].replace(reg[0],cb[0])+'){';

                // for loop
                if(m[5]) {
                    return 'n=0;t=d.'+m[5]+';p=(t instanceof Array);for(var x in t){if((p&&isNaN(parseInt(x)))||(!p&&!t.propertyIsEnumerable(x)))continue;d.'+m[4]+'=t[x];'+(m[3]?'d.'+m[3]+'=x;':'')+'n++;';
                }

                // else
                if(m[6]) return '}else{';

                // end if, end for
                if(m[7]) {
                    return '};';
                }

                return m[0];
            });
        } else if(tpl[i]){
            tpl[i] = 's[s.length]="'+tpl[i].replace(reg[1],cb[1])+'";';
        }
    }

    tpl = (new Function("d",'var s=[];'+tpl.join('')+'return s.join("")'))(data);

    return tpl;
};
/**
 * $Cookie 객체를 반환한다.
 * @id core.$Date
 */
function $Date(src) {
	var a=arguments,t="";
	var cl=arguments.callee;

	if (src && src instanceof cl) return src;
	if (!(this instanceof cl)) return new cl(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);

	if ((t=typeof src) == "string") {
		this._date = cl.parse(src).$value();
	} else if (t == "number") {
		if (typeof a[1] == "undefined") this._date = new Date(src);
		else this._date = new Date(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);
	} else if (t == "object" && src.constructor == Date) {
		(this._date = new Date).setTime(src.getTime());
		this._date.setMilliseconds(src.getMilliseconds());
	} else {
		this._date = new Date;
	}
}

/**
 * 달, 요일, 오전/오후 이름. s_ 가 붙은 것은 짧은 이름이다.
 * @id core.$Date.names
 */
$Date.names = {
	month   : ["January","Febrary","March","April","May","June","July","August","September","October","Novermber","December"],
	s_month : ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
	day     : ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
	s_day   : ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
	ampm    : ["AM", "PM"]
};

/**
 * 현재 시간을 밀리초 단위의 정수로 리턴
 * @id core.$Date.now
 */
$Date.now = function() {
	return Date.now();
};

/**
 * 주어진 문자열을 해석한 값을 가지는 객체 생성
 * @id core.$Date.parse
 */
$Date.parse = function(strDate) {
	return Date.parse(strDate);
};

/**
 * 원래의 Date 객체를 반환한다.
 * @id core.$Date.$value
 */
$Date.prototype.$value = function(){
	return this._date;
};

/**
 * 지정한 형식에 맞춰서 문자열을 출력한다. 형식문자열은 PHP의 date 함수에 사용하는 것에 준한다.
 * @id core.$Date.format
 * @import core.$Date[time,isLeapYear]
 */
$Date.prototype.format = function(strFormat){
	var o = {};
	var d = this._date;
	
	return (strFormat||"").replace(/[a-z]/ig, function callback(m){
		if (typeof o[m] != "undefined") return o[m];

		switch(m) {
			case"d":
			case"j":
				o.j = d.getDate();
				o.d = (o.j>9?"":"0")+o.j;
				return o[m];
			case"l":
			case"D":
			case"w":
			case"N":
				o.w = d.getDay();
				o.N = o.w?o.w:7;
				o.D = $Date.names.s_day[o.w];
				o.j = $Date.names.day[o.w];
				return o[m];
			case"S":
				return (!!(o.S=["st","nd","rd"][d.getDate()]))?o.S:(o.S="th");
			case"z":
				o.z = Math.floor((d.getTime() - (new Date(d.getFullYear(),0,1)).getTime())/(3600*24*1000));
				return o.z;
			case"m":
			case"n":
				o.n = d.getMonth()+1;
				o.m = (o.n>9?"":"0")+o.n;
				return o[m];
			case"L":
				o.L = this.isLeapYear();
				return o.L;
			case"o":
			case"Y":
			case"y":
				o.o = o.Y = d.getFullYear();
				o.y = (o.o+"").substr(2);
				return o[m];
			case"a":
			case"A":
			case"g":
			case"G":
			case"h":
			case"H":
				o.G = d.getHours();
				o.g = (o.g=o.G%12)?o.g:12;
				o.A = o.G<12?$Date.names.ampm[0]:$Date.names.ampm[1];
				o.a = o.A.toLowerCase();
				o.H = (o.G>9?"":"0")+o.G;
				o.h = (o.g>9?"":"0")+o.g;
				return o[m];
			case"i":
				o.i = (((o.i=d.getMinutes())>9)?"":"0")+o.i;
				return o.i;
			case"s":
				o.s = (((o.s=d.getSeconds())>9)?"":"0")+o.i;
				return o.s;
			case"u":
				o.u = d.getMilliseconds();
				return o.u;
			case"U":
				o.U = this.time();
				return o.U;
			default:
				return m;
		}
	});
};

/**
 * 1970/01/01 00:00:00 UTC 기준으로 지난 시간을 설정하거나 가져온다.
 * @id core.$Date.time
 */
$Date.prototype.time = function(nTime) {
	if (typeof nTime == "number") {
		this._date.setTime(nTime);
		return this;
	}

	return this._date.getTime();
};

/**
 * 년도를 설정하거나 가져온다.
 * @id core.$Date.date
 */
$Date.prototype.year = function(nYear) {
	if (typeof nYear == "number") {
		this._date.setFullYear(nDate);
		return this;
	}

	return this._date.getFullYear();
};

/**
 * 달을 설정하거나 가져온다.
 * @id core.$Date.date
 */
$Date.prototype.month = function(nMon) {
	if (typeof nMon == "number") {
		this._date.setMonth(nDate);
		return this;
	}

	return this._date.getMonth();
};

/**
 * 날짜를 설정하거나 가져온다.
 * @id core.$Date.date
 */
$Date.prototype.date = function(nDate) {
	if (typeof nDate == "number") {
		this._date.setDate(nDate);
		return this;
	}

	return this._date.getDate();
};

/**
 * 요일을 가져온다. 0이 일요일, 6이 토요일이다.
 * @id core.$Date.day
 */
$Date.prototype.day = function() {
	return this._date.getDay();
};

/**
 * 시간을 설정하거나 가져온다.
 * @id core.$Date.hours
 */
$Date.prototype.hours = function(nHour) {
	if (typeof nHour == "number") {
		this._date.setHours(nHour);
		return this;
	}

	return this._date.getHours();
};

/**
 * 초을 설정하거나 가져온다.
 * @id core.$Date.seconds
 */
$Date.prototype.seconds = function(nSec) {
	if (typeof nSec == "number") {
		this._date.setSeconds(nSec);
		return this;
	}

	return this._date.getSeconds();
};

/**
 * 분을 설정하거나 가져온다.
 * @id core.$Date.minutes
 */
$Date.prototype.minutes = function(nMin) {
	if (typeof nMin == "number") {
		this._date.setMinutes(nMin);
		return this;
	}

	return this._date.getMinutes();
};

/**
 * 윤년인지의 여부를 반환한다.
 * @id core.$Date.isLeapYear
 */
$Date.prototype.isLeapYear = function() {
	var y = this._date.getFullYear();

	return !(y%4)&&!!(y%100)||!(y%400);
};
/**
 * CSS Selector Engine 3
 *
 * @author hooriza (ajaxUI 3 team)
 * @compatibility with IE55, IE6, IE7, FF2, Opera9, Safari3
 *
 * 아직 WebKit 및 IE8 의 querySelector 메쏘드군의 기능이 완전하지 않아 사용하지 않음
 */
var cssquery = (function() {
	
	var sVersion = '2.0.7';
	
	var debugOption = { repeat : 1 };
	
	// 빠른 처리를 위해 노드마다 유일키 값 셋팅
	var UID = 1;
	
	var cost = 0;
	var validUID = {};
	
	var getUID4HTML = function(oEl) {
		
		var sUID = oEl._cssquery_UID;
		if (sUID && validUID[sUID] == oEl) return sUID;
		
		sUID = oEl._cssquery_UID = UID++;
		validUID[sUID] = oEl;
		
		return sUID;

	};
	
	var getUID4XML = function(oEl) {
		
		var nUID = oEl.getAttribute('_cssquery_UID');
		
		if (!nUID) {
			nUID = UID++;
			oEl.setAttribute('_cssquery_UID', nUID);
		}
		
		return nUID;
		
	};
	
	var getUID = getUID4HTML;
	
	var uniqid = function(sPrefix) {
		return (sPrefix || '') + new Date().getTime() + parseInt(Math.random() * 100000000);
	};
	
	/* DON'T SHRINK THIS */
	var getChilds = function(oEl, sTagName) {
		if (sTagName == '*') return oEl.all || oEl.getElementsByTagName(sTagName);
		return oEl.getElementsByTagName(sTagName);
	};

	var clearKeys = function() {
		 backupKeys._keys = {};
	};
	
	/* DON'T SHRINK THIS */
	var oDocument = document;
	
	var bXMLDocument = false;
	
	// 따옴표, [] 등 파싱에 문제가 될 수 있는 부분 replace 시켜놓기
	var backupKeys = function(sQuery) {
		
		var oKeys = backupKeys._keys;
		
		// 작은 따옴표 걷어내기
		sQuery = sQuery.replace(/'(\\'|[^'])*'/g, function(sAll) {
			var uid = uniqid('QUOT');
			oKeys[uid] = sAll;
			return uid;
		});
		
		// 큰 따옴표 걷어내기
		sQuery = sQuery.replace(/"(\\"|[^"])*"/g, function(sAll) {
			var uid = uniqid('QUOT');
			oKeys[uid] = sAll;
			return uid;
		});
		
		// [ ] 형태 걷어내기
		sQuery = sQuery.replace(/\[(.*?)\]/g, function(sAll, sBody) {
			if (sBody.indexOf('ATTR') == 0) return sAll;
			var uid = '[' + uniqid('ATTR') + ']';
			oKeys[uid] = sAll;
			return uid;
		});
	
		// ( ) 형태 걷어내기
		var bChanged;
		
		do {
			
			bChanged = false;
		
			sQuery = sQuery.replace(/\(((\\\)|[^)|^(])*)\)/g, function(sAll, sBody) {
				if (sBody.indexOf('BRCE') == 0) return sAll;
				var uid = '_' + uniqid('BRCE');
				oKeys[uid] = sAll;
				bChanged = true;
				return uid;
			});
		
		} while(bChanged);
	
		return sQuery;
		
	};
	
	// replace 시켜놓은 부분 복구하기
	var restoreKeys = function(sQuery, bOnlyAttrBrace) {
		
		var oKeys = backupKeys._keys;
	
		var bChanged;
		var rRegex = bOnlyAttrBrace ? /(\[ATTR[0-9]+\])/g : /(QUOT[0-9]+|\[ATTR[0-9]+\])/g;
		
		do {
			
			bChanged = false;
	
			sQuery = sQuery.replace(rRegex, function(sKey) {
				
				if (oKeys[sKey]) {
					bChanged = true;
					return oKeys[sKey];
				}
				
				return sKey;
	
			});
		
		} while(bChanged);
		
		// ( ) 는 한꺼풀만 벗겨내기
		sQuery = sQuery.replace(/_BRCE[0-9]+/g, function(sKey) {
			return oKeys[sKey] ? oKeys[sKey] : sKey;
		});
		
		return sQuery;
		
	};
	
	// replace 시켜놓은 문자열에서 Quot 을 제외하고 리턴
	var restoreString = function(sKey) {
		
		var oKeys = backupKeys._keys;
		var sOrg = oKeys[sKey];
		
		if (!sOrg) return sKey;
		return eval(sOrg);
		
	};
	
	var wrapQuot = function(sStr) {
		return '"' + sStr.replace(/"/g, '\\"') + '"';
	};
	
	var getStyleKey = function(sKey) {

		if (/^@/.test(sKey)) return sKey.substr(1);
		return null;
		
	};
	
	var getCSS = function(oEl, sKey) {
		
		if (oEl.currentStyle) {
			
			if (sKey == "float") sKey = "styleFloat";
			return oEl.currentStyle[sKey] || oEl.style[sKey];
			
		} else if (window.getComputedStyle) {
			
			return oDocument.defaultView.getComputedStyle(oEl, null).getPropertyValue(sKey.replace(/([A-Z])/g,"-$1").toLowerCase()) || oEl.style[sKey];
			
		}

		if (sKey == "float" && /MSIE/.test(window.navigator.userAgent)) sKey = "styleFloat";
		return oEl.style[sKey];
		
	};
	
	var getDefineCode = function(sKey) {
		
		var sVal;
		var sStyleKey;

		if (bXMLDocument) {
			
			sVal = 'oEl.getAttribute("' + sKey + '")';
		
		} else {
		
			if (sStyleKey = getStyleKey(sKey)) {
				
				sKey = '$$' + sStyleKey;
				sVal = 'getCSS(oEl, "' + sStyleKey + '")';
				
			} else {
				
				switch (sKey) {
				case 'checked':
					sVal = 'oEl.checked + ""';
					break;
					
				case 'disabled':
					sVal = 'oEl.disabled + ""';
					break;
					
				case 'enabled':
					sVal = '!oEl.disabled + ""';
					break;
					
				case 'readonly':
					sVal = 'oEl.readOnly + ""';
					break;
					
				case 'selected':
					sVal = 'oEl.selected + ""';
					break;
					
				case 'class':
					sVal = 'oEl.className';
					break;
					
				default:
					sVal = 'oEl.getAttribute("' + sKey + '")';
				}
				
			}
			
		}
			
		return '_' + sKey + ' = ' + sVal;
	};
	
	var getReturnCode = function(oExpr) {
		
		var sStyleKey = getStyleKey(oExpr.key);
		
		var sVar = '_' + (sStyleKey ? '$$' + sStyleKey : oExpr.key);
		var sVal = oExpr.val ? wrapQuot(oExpr.val) : '';
		
		switch (oExpr.op) {
		case '~=':
			return '(' + sVar + ' && (" " + ' + sVar + ' + " ").indexOf(" " + ' + sVal + ' + " ") > -1)';
		case '^=':
			return '(' + sVar + ' && ' + sVar + '.indexOf(' + sVal + ') == 0)';
		case '$=':
			return '(' + sVar + ' && ' + sVar + '.substr(' + sVar + '.length - ' + oExpr.val.length + ') == ' + sVal + ')';
		case '*=':
			return '(' + sVar + ' && ' + sVar + '.indexOf(' + sVal + ') > -1)';
		case '!=':
			return '(' + sVar + ' != ' + sVal + ')';
		case '=':
			return '(' + sVar + ' == ' + sVal + ')';
		}
	
		return '(' + sVar + ')';
		
	};

	var getNodeIndex = function(oEl) {
		
		var nUID = getUID(oEl);
		var nIndex = oNodeIndexes[nUID] || 0;
		
		// 노드 인덱스를 구할 수 없으면
		if (nIndex == 0) {

			for (var oSib = (oEl.parentNode || oEl._IE5_parentNode).firstChild; oSib; oSib = oSib.nextSibling) {
				
				if (oSib.nodeType != 1) continue;
				nIndex++;
				
				setNodeIndex(oSib, nIndex);
				
			}
			
			nIndex = oNodeIndexes[nUID];
			
		}
		
		return nIndex;
		
	};
	
	// 몇번째 자식인지 설정하는 부분
	var oNodeIndexes = {};

	var setNodeIndex = function(oEl, nIndex) {
		var nUID = getUID(oEl);
		oNodeIndexes[nUID] = nIndex;
	};
	
	var unsetNodeIndexes = function() {
		setTimeout(function() { oNodeIndexes = {}; }, 0);
	};
	
	// 가상 클래스
	/* DON'T SHRINK THIS */
	var oPseudoes = {
	
		'contains' : function(oEl, sOption) {
			return (oEl.innerText || oEl.textContent || '').indexOf(sOption) > -1;
		},
		
		'last-child' : function(oEl, sOption) {
			for (oEl = oEl.nextSibling; oEl; oEl = oEl.nextSibling)
				if (oEl.nodeType == 1)
					return false;
			
			return true;
		},
		
		'first-child' : function(oEl, sOption) {
			for (oEl = oEl.previousSibling; oEl; oEl = oEl.previousSibling)
				if (oEl.nodeType == 1)
					return false;
					
			return true;
		},
		
		'only-child' : function(oEl, sOption) {
			var nChild = 0;
			
			for (var oChild = (oEl.parentNode || oEl._IE5_parentNode).firstChild; oChild; oChild = oChild.nextSibling) {
				if (oChild.nodeType == 1) nChild++;
				if (nChild > 1) return false;
			}
			
			return nChild ? true : false;
		},

		'empty' : function(oEl, _) {
			return oEl.firstChild ? false : true;
		},
		
		'nth-child' : function(oEl, nMul, nAdd) {
			var nIndex = getNodeIndex(oEl);
			return nIndex % nMul == nAdd;
		},
		
		'nth-last-child' : function(oEl, nMul, nAdd) {
			var oLast = (oEl.parentNode || oEl._IE5_parentNode).lastChild;
			for (; oLast; oLast = oLast.previousSibling)
				if (oLast.nodeType == 1) break;
				
			var nTotal = getNodeIndex(oLast);
			var nIndex = getNodeIndex(oEl);
			
			var nLastIndex = nTotal - nIndex + 1;
			return nLastIndex % nMul == nAdd;
		}
		
	};
	
	// 단일 part 의 body 에서 expression 뽑아냄
	var getExpression = function(sBody) {

		var oRet = { defines : '', returns : 'true' };
		
		var sBody = restoreKeys(sBody, true);
	
		var aExprs = [];
		var aDefineCode = [], aReturnCode = [];
		var sId, sTagName;
		
		// 유사클래스 조건 얻어내기
		var sBody = sBody.replace(/:([\w-]+)(\(([^)]*)\))?/g, function(_, sType, _, sOption) {
			
			switch (sType) {
			case 'not':
				var oInner = getExpression(sOption); // 괄호 안에 있는거 재귀파싱하기
				
				var sFuncDefines = oInner.defines;
				var sFuncReturns = oInner.returnsID + oInner.returnsTAG + oInner.returns;
				
				aReturnCode.push('!(function() { ' + sFuncDefines + ' return ' + sFuncReturns + ' })()');
				break;
				
			case 'nth-child':
			case 'nth-last-child':
				sOption =  restoreString(sOption);
				
				if (sOption == 'even') sOption = '2n';
				else if (sOption == 'odd') sOption = '2n+1';

				var nMul, nAdd;
				
				if (/([0-9]*)n([+-][0-9]+)*/.test(sOption)) {
					nMul = parseInt(RegExp.$1) || 1;
					nAdd = parseInt(RegExp.$2) || 0;
				} else {
					nMul = Infinity;
					nAdd = parseInt(sOption);
				}
				
				aReturnCode.push('oPseudoes[' + wrapQuot(sType) + '](oEl, ' + nMul + ', ' + nAdd + ')');
				break;
				
			case 'first-of-type':
			case 'last-of-type':
				sType = (sType == 'first-of-type' ? 'nth-of-type' : 'nth-last-of-type');
				sOption = 1;
				
			case 'nth-of-type':
			case 'nth-last-of-type':
				sOption =  restoreString(sOption);
				
				if (sOption == 'even') sOption = '2n';
				else if (sOption == 'odd') sOption = '2n+1';

				var nMul, nAdd;
				
				if (/([0-9]*)n([+-][0-9]+)*/.test(sOption)) {
					nMul = parseInt(RegExp.$1) || 1;
					nAdd = parseInt(RegExp.$2) || 0;
				} else {
					nMul = Infinity;
					nAdd = parseInt(sOption);
				}
				
				oRet.nth = [ nMul, nAdd, sType ];
				break;
				
			default:
				sOption = sOption ? restoreString(sOption) : '';
				aReturnCode.push('oPseudoes[' + wrapQuot(sType) + '](oEl, ' + wrapQuot(sOption) + ')');
				break;
			}
			
			return '';
			
		});
		
		// [key=value] 형태 조건 얻어내기
		var sBody = sBody.replace(/\[(@?[\w-]+)(([!^~$*]?=)([^\]]*))?\]/g, function(_, sKey, _, sOp, sVal) {
			
			sKey = restoreString(sKey);
			sVal = restoreString(sVal);
			
			if (sKey == 'checked' || sKey == 'disabled' || sKey == 'enabled' || sKey == 'readonly' || sKey == 'selected') {
				
				if (!sVal) {
					sOp = '=';
					sVal = 'true';
				}
				
			}
			
			aExprs.push({ key : sKey, op : sOp, val : sVal });
			return '';
	
		});
	
		// 클래스 조건 얻어내기
		var sBody = sBody.replace(/\.([\w-]+)/g, function(_, sClass) { 
			aExprs.push({ key : 'class', op : '~=', val : sClass });
			return '';
		});
		
		// id 조건 얻어내기
		var sBody = sBody.replace(/#([\w-]+)/g, function(_, sIdValue) {
			if (bXMLDocument) aExprs.push({ key : 'id', op : '=', val : sIdValue });
			else sId = sIdValue;
			return '';
		});
		
		sTagName = sBody == '*' ? '' : sBody;
	
		// match 함수 코드 만들어 내기
		var oVars = {};
		
		for (var i = 0, oExpr; oExpr = aExprs[i]; i++) {
			
			var sKey = oExpr.key;
			
			if (!oVars[sKey]) aDefineCode.push(getDefineCode(sKey));
			aReturnCode.unshift(getReturnCode(oExpr)); // 유사클래스 조건 검사가 맨 뒤로 가도록 unshift 사용
			oVars[sKey] = true;
			
		}
		
		if (aDefineCode.length) oRet.defines = 'var ' + aDefineCode.join(',') + ';';
		if (aReturnCode.length) oRet.returns = aReturnCode.join('&&');
		
		oRet.quotID = sId ? wrapQuot(sId) : '';
		oRet.quotTAG = sTagName ? wrapQuot(bXMLDocument ? sTagName : sTagName.toUpperCase()) : '';
		
		oRet.returnsID = sId ? 'oEl.id == ' + oRet.quotID + ' && ' : '';
		oRet.returnsTAG = sTagName && sTagName != '*' ? 'oEl.tagName == ' + oRet.quotTAG + ' && ' : '';
		
		return oRet;
		
	};
	
	// 쿼리를 연산자 기준으로 잘라냄
	var splitToParts = function(sQuery) {
		
		var aParts = [];
		var sRel = ' ';
		
		var sBody = sQuery.replace(/(.*?)\s*(!?[+>~ ]|!)\s*/g, function(_, sBody, sRelative) {
			
			if (sBody) aParts.push({ rel : sRel, body : sBody });
	
			sRel = sRelative.replace(/\s+$/g, '') || ' ';
			return '';
			
		});
	
		if (sBody) aParts.push({ rel : sRel, body : sBody });
		
		return aParts;
		
	};
	
	/* DO NOT SHRINK THIS */
	var isNth = function(oEl, sTagName, nMul, nAdd, sDirection) {
		
		var nIndex = 0;
		for (var oSib = oEl; oSib; oSib = oSib[sDirection])
			if (oSib.nodeType == 1 && (!sTagName || sTagName == oSib.tagName))
					nIndex++;

		return nIndex % nMul == nAdd;

	};
	
	// 잘라낸 part 를 함수로 컴파일 하기
	var compileParts = function(aParts) {
		
		var aPartExprs = [];
		
		// 잘라낸 부분들 조건 만들기
		for (var i = 0, oPart; oPart = aParts[i]; i++)
			aPartExprs.push(getExpression(oPart.body));
		
		//////////////////// BEGIN
		
		var sFunc = '';
		var sPushCode = 'aRet.push(oEl); if (oOptions.single) { bStop = true; }';

		for (var i = aParts.length - 1, oPart; oPart = aParts[i]; i--) {
			
			var oExpr = aPartExprs[i];
			var sPush = (debugOption.callback ? 'cost++;' : '') + oExpr.defines;
			
			// console.log(oExpr);

			var sReturn = 'if (bStop) {' + (i == 0 ? 'return aRet;' : 'return;') + '}';
			
			if (oExpr.returns == 'true') sPush += (sFunc ? sFunc + '(oEl);' : sPushCode) + sReturn;
			else sPush += 'if (' + oExpr.returns + ') {' + (sFunc ? sFunc + '(oEl);' : sPushCode ) + sReturn + '}';
			
			var sCheckTag = 'oEl.nodeType != 1';
			if (oExpr.quotTAG) sCheckTag = 'oEl.tagName != ' + oExpr.quotTAG;
			
			var sTmpFunc =
				'(function(oBase' +
					(i == 0 ? ', oOptions) { var bStop = false; var aRet = [];' : ') {');

			if (oExpr.nth) {
				sPush =
					'if (isNth(oEl, ' +
					(oExpr.quotTAG ? oExpr.quotTAG : 'false') + ',' +
					oExpr.nth[0] + ',' +
					oExpr.nth[1] + ',' +
					'"' + (oExpr.nth[2] == 'nth-of-type' ? 'previousSibling' : 'nextSibling') + '")) {' + sPush + '}';
			}
			
			switch (oPart.rel) {
			case ' ':
				if (oExpr.quotID) {
					
					sTmpFunc +=
						'var oEl = oDocument.getElementById(' + oExpr.quotID + ');' +
						'var oCandi = oEl;' +
						'for (; oCandi; oCandi = (oCandi.parentNode || oCandi._IE5_parentNode)) {' +
							'if (oCandi == oBase) break;' +
						'}' +
						'if (!oCandi || ' + sCheckTag + ') return aRet;' +
						sPush;
					
				} else {
					
					sTmpFunc +=
						'var aCandi = getChilds(oBase, ' + (oExpr.quotTAG || '"*"') + ');' +
							'for (var i = 0, oEl; oEl = aCandi[i]; i++) {' +
							sPush +
						'}';
					
				}
			
				break;
				
			case '>':
				if (oExpr.quotID) {
	
					sTmpFunc +=
						'var oEl = oDocument.getElementById(' + oExpr.quotID + ');' +
						'if ((oEl.parentNode || oEl._IE5_parentNode) != oBase || ' + sCheckTag + ') return aRet;' +
						sPush;
					
				} else {
	
					sTmpFunc +=
						'for (var oEl = oBase.firstChild; oEl; oEl = oEl.nextSibling) {' +
							'if (' + sCheckTag + ') { continue; }' +
							sPush +
						'}';
					
				}
				
				break;
				
			case '+':
				if (oExpr.quotID) {
	
					sTmpFunc +=
						'var oEl = oDocument.getElementById(' + oExpr.quotID + ');' +
						'var oPrev;' +
						'for (oPrev = oEl.previousSibling; oPrev; oPrev = oPrev.previousSibling) { if (oPrev.nodeType == 1) break; }' +
						'if (!oPrev || oPrev != oBase || ' + sCheckTag + ') return aRet;' +
						sPush;
					
				} else {
	
					sTmpFunc +=
						'for (var oEl = oBase.nextSibling; oEl; oEl = oEl.nextSibling) { if (oEl.nodeType == 1) break; }' +
						'if (!oEl || ' + sCheckTag + ') { return aRet; }' +
						sPush;
					
				}
				
				break;
			
			case '~':
	
				if (oExpr.quotID) {
	
					sTmpFunc +=
						'var oEl = oDocument.getElementById(' + oExpr.quotID + ');' +
						'var oCandi = oEl;' +
						'for (; oCandi; oCandi = oCandi.previousSibling) { if (oCandi == oBase) break; }' +
						'if (!oCandi || ' + sCheckTag + ') return aRet;' +
						sPush;
					
				} else {
	
					sTmpFunc +=
						'for (var oEl = oBase.nextSibling; oEl; oEl = oEl.nextSibling) {' +
							'if (' + sCheckTag + ') { continue; }' +
							'if (!markElement(oEl, ' + i + ')) { break; }' +
							sPush +
						'}';
	
				}
				
				break;
				
			case '!' :
			
				if (oExpr.quotID) {
					
					sTmpFunc +=
						'var oEl = oDocument.getElementById(' + oExpr.quotID + ');' +
						'for (; oBase; oBase = (oBase.parentNode || oBase._IE5_parentNode)) { if (oBase == oEl) break; }' +
						'if (!oBase || ' + sCheckTag + ') return aRet;' +
						sPush;
						
				} else {
					
					sTmpFunc +=
						'for (var oEl = (oBase.parentNode || oBase._IE5_parentNode); oEl; oEl = (oEl.parentNode || oEl._IE5_parentNode)) {'+
							'if (' + sCheckTag + ') { continue; }' +
							sPush +
						'}';
					
				}
				
				break;
	
			case '!>' :
			
				if (oExpr.quotID) {
	
					sTmpFunc +=
						'var oEl = oDocument.getElementById(' + oExpr.quotID + ');' +
						'var oRel = (oBase.parentNode || oBase._IE5_parentNode);' +
						'if (!oRel || oEl != oRel || (' + sCheckTag + ')) return aRet;' +
						sPush;
					
				} else {
	
					sTmpFunc +=
						'var oEl = (oBase.parentNode || oBase._IE5_parentNode);' +
						'if (!oEl || ' + sCheckTag + ') { return aRet; }' +
						sPush;
					
				}
				
				break;
				
			case '!+' :
				
				if (oExpr.quotID) {
	
					sTmpFunc +=
						'var oEl = oDocument.getElementById(' + oExpr.quotID + ');' +
						'var oRel;' +
						'for (oRel = oBase.previousSibling; oRel; oRel = oRel.previousSibling) { if (oRel.nodeType == 1) break; }' +
						'if (!oRel || oEl != oRel || (' + sCheckTag + ')) return aRet;' +
						sPush;
					
				} else {
	
					sTmpFunc +=
						'for (oEl = oBase.previousSibling; oEl; oEl = oEl.previousSibling) { if (oEl.nodeType == 1) break; }' +
						'if (!oEl || ' + sCheckTag + ') { return aRet; }' +
						sPush;
					
				}
				
				break;
	
			case '!~' :
				
				if (oExpr.quotID) {
					
					sTmpFunc +=
						'var oEl = oDocument.getElementById(' + oExpr.quotID + ');' +
						'var oRel;' +
						'for (oRel = oBase.previousSibling; oRel; oRel = oRel.previousSibling) { ' +
							'if (oRel.nodeType != 1) { continue; }' +
							'if (oRel == oEl) { break; }' +
						'}' +
						'if (!oRel || (' + sCheckTag + ')) return aRet;' +
						sPush;
					
				} else {
	
					sTmpFunc +=
						'for (oEl = oBase.previousSibling; oEl; oEl = oEl.previousSibling) {' +
							'if (' + sCheckTag + ') { continue; }' +
							'if (!markElement(oEl, ' + i + ')) { break; }' +
							sPush +
						'}';
					
				}
				
				break;
			}
	
			sTmpFunc +=
				(i == 0 ? 'return aRet;' : '') +
			'})';
			
			sFunc = sTmpFunc;
			
		}
		
		// alert(sFunc);
		eval('var fpCompiled = ' + sFunc + ';');
		//alert(fpCompiled);
		return fpCompiled;
		
	};
	
	// 쿼리를 match 함수로 변환
	var parseQuery = function(sQuery) {
		
		var sCacheKey = sQuery;
		
		var fpSelf = arguments.callee;
		var fpFunction = fpSelf._cache[sCacheKey];
		
		if (!fpFunction) {
			
			sQuery = backupKeys(sQuery);
			
			var aParts = splitToParts(sQuery);
			
			fpFunction = fpSelf._cache[sCacheKey] = compileParts(aParts);
			fpFunction.depth = aParts.length;
			
		}
		
		return fpFunction;
		
	};
	
	parseQuery._cache = {};
	
	// test 쿼리를 match 함수로 변환
	var parseTestQuery = function(sQuery) {
		
		var fpSelf = arguments.callee;
		
		var aSplitQuery = backupKeys(sQuery).split(/\s*,\s*/);
		var aResult = [];
		
		var nLen = aSplitQuery.length;
		var aFunc = [];
		
		for (var i = 0; i < nLen; i++) {

			aFunc.push((function(sQuery) {
				
				var sCacheKey = sQuery;
				var fpFunction = fpSelf._cache[sCacheKey];
				
				if (!fpFunction) {
					
					sQuery = backupKeys(sQuery);
					var oExpr = getExpression(sQuery);
					
					eval('fpFunction = function(oEl) { ' + oExpr.defines + 'return (' + oExpr.returnsID + oExpr.returnsTAG + oExpr.returns + '); };');
					
				}
				
				return fpFunction;
				
			})(restoreKeys(aSplitQuery[i])));
			
		}
		
		return aFunc;
		
	};
	
	parseTestQuery._cache = {};
	
	var distinct = function(aList) {
	
		var aDistinct = [];
		var oDummy = {};
		
		for (var i = 0, oEl; oEl = aList[i]; i++) {
			
			var nUID = getUID(oEl);
			if (oDummy[nUID]) continue;
			
			aDistinct.push(oEl);
			oDummy[nUID] = true;
		}
	
		return aDistinct;
	
	};
	
	/* DON'T SHRINK THIS */
	var markElement = function(oEl, nDepth) {
		
		var nUID = getUID(oEl);
		if (cssquery._marked[nDepth][nUID]) return false;
		
		cssquery._marked[nDepth][nUID] = true;
		return true;

	};
	
	var oResultCache = null;
	var bUseResultCache = false;
		
	var cssquery = function(sQuery, oParent, oOptions) {
		
		if (typeof sQuery == 'object') {
			
			var oResult = {};
			
			for (var k in sQuery)
				oResult[k] = arguments.callee(sQuery[k], oParent, oOptions);
			
			return oResult;
		}
		
		cost = 0;
		
		var executeTime = new Date().getTime();
		var aRet;
		
		for (var r = 0, rp = debugOption.repeat; r < rp; r++) {
			
			aRet = (function(sQuery, oParent, oOptions) {
				
				oOptions = oOptions || {};
				
				if (!oParent) oParent = document;
					
				// ownerDocument 잡아주기
				oDocument = oParent.ownerDocument || oParent.document || oParent;
				
				// 브라우저 버젼이 IE5.5 이하
				if (/\bMSIE\s([0-9]+(\.[0-9]+)*);/.test(navigator.userAgent) && parseFloat(RegExp.$1) < 6) {
					oDocument.firstChild = oDocument.getElementsByTagName('html')[0];
					oDocument.firstChild._IE5_parentNode = oDocument;
				}
				
				// XMLDocument 인지 체크
				bXMLDocument = (typeof XMLDocument != 'undefined') ? (oDocument.constructor === XMLDocument) : (!oDocument.location);
				getUID = bXMLDocument ? getUID4XML : getUID4HTML;
		
				clearKeys();
				
				// 쿼리를 쉼표로 나누기
				var aSplitQuery = backupKeys(sQuery).split(/\s*,\s*/);
				var aResult = [];
				
				var nLen = aSplitQuery.length;
				
				for (var i = 0; i < nLen; i++)
					aSplitQuery[i] = restoreKeys(aSplitQuery[i]);
				
				// 쉼표로 나눠진 쿼리 루프
				for (var i = 0; i < nLen; i++) {
					
					var sSingleQuery = aSplitQuery[i];
					var aSingleQueryResult = null;
					
					var sResultCacheKey = sSingleQuery + (oOptions.single ? '_single' : '');
		
					// 결과 캐쉬 뒤짐
					var aCache = bUseResultCache ? oResultCache[sResultCacheKey] : null;
					if (aCache) {
						
						// 캐싱되어 있는게 있으면 parent 가 같은건지 검사한후 aSingleQueryResult 에 대입
						for (var j = 0, oCache; oCache = aCache[j]; j++) {
							if (oCache.parent == oParent) {
								aSingleQueryResult = oCache.result;
								break;
							}
						}
						
					}
					
					if (!aSingleQueryResult) {
						
						var fpFunction = parseQuery(sSingleQuery);
						// alert(fpFunction);
						
						cssquery._marked = [];
						for (var j = 0, nDepth = fpFunction.depth; j < nDepth; j++)
							cssquery._marked.push({});
						
						aSingleQueryResult = distinct(fpFunction(oParent, oOptions));
						
						// 결과 캐쉬를 사용중이면 캐쉬에 저장
						if (bUseResultCache) {
							if (!(oResultCache[sResultCacheKey] instanceof Array)) oResultCache[sResultCacheKey] = [];
							oResultCache[sResultCacheKey].push({ parent : oParent, result : aSingleQueryResult });
						}
						
					}
					
					aResult = aResult.concat(aSingleQueryResult);
					
				}
		
				unsetNodeIndexes();
		
				return aResult;
				
			})(sQuery, oParent, oOptions);
			
		}
		
		executeTime = new Date().getTime() - executeTime;

		if (debugOption.callback) debugOption.callback(sQuery, cost, executeTime);
		
		return aRet;
		
	};

	cssquery.test = function(oEl, sQuery) {

		clearKeys();
		
		var aFunc = parseTestQuery(sQuery);
		
		for (var i = 0, nLen = aFunc.length; i < nLen; i++)
			if (aFunc[i](oEl)) return true;
			
		return false;
		
	};

	cssquery.useCache = function(bFlag) {
	
		if (typeof bFlag != 'undefined') {
			bUseResultCache = bFlag;
			cssquery.clearCache();
		}
		
		return bUseResultCache;
		
	};
	
	cssquery.clearCache = function() {
		oResultCache = {};
	};
	
	cssquery.getSingle = function(sQuery, oParent) {
		return cssquery(sQuery, oParent, { single : true })[0] || null;
	};
	
	cssquery.xpath = function(sXPath, oParent) {
		
		var sXPath = sXPath.replace(/\/(\w+)(\[([0-9]+)\])?/g, function(_, sTag, _, sTh) {
			sTh = sTh || '1';
			return '>' + sTag + ':nth-of-type(' + sTh + ')';
		});
		
		return cssquery.getSingle(sXPath, oParent);
		
	};
	
	cssquery.debug = function(fpCallback, nRepeat) {
		
		debugOption.callback = fpCallback;
		debugOption.repeat = nRepeat || 1;
		
	};
	
	cssquery.version = sVersion;
	
	return cssquery;
	
})();

if (typeof window.$$ == "undefined") window.$$ = cssquery;
function completeInsertContent(ret_obj) {
    var error = ret_obj['error'];
    var message = ret_obj['message'];
    var document_srl = ret_obj['document_srl'];
    location.href = current_url;
}


function completeCreate(ret_obj, response_tags, params, fo_obj) {
    var mid_url = ret_obj['mid_url'];
    var mid = ret_obj['mid'];

    if(fo_obj.photo.value) {
        fo_obj.mid.value = mid;
        fo_obj.act.value = "procPlanetPhotoModify";
        fo_obj.submit();
    } else {
        location.href = mid_url;
    }
}


function completeUpdateContentTag(ret_obj) {
    var error = ret_obj['error'];
    //var message = ret_obj['message'];
    var document_srl = ret_obj['document_srl'];
    //alert(message);
    location.reload();
    location.href = current_url;
}


function completePlanetLogin(ret_obj, response_tags, params, fo_obj) {
    var url =  current_url.setQuery('act','');
    if(typeof(fo_obj.return_act)!='undefined') {
        url =  url.setQuery('act',fo_obj.return_act.value);
    }
    location.href = url;
}

function completeInsertMemo(ret_obj, response_tags, params, fo_obj) {
    toggle('form');
    fo_obj.planet_memo.value = "";
    $('planetMemo').innerHTML = ret_obj['tpl'];
}

function doDeleteMemo(planet_memo_srl) {
    var params = new Array();
    params['planet_memo_srl'] = planet_memo_srl;
    var response_tags = new Array('error','message','tpl');
    exec_xml('planet', 'procPlanetDeleteMemo', params, completeDeleteMemo, response_tags);
}

function completeDeleteMemo(ret_obj, response_tags, params) {
    $('planetMemo').innerHTML = ret_obj['tpl'];
}

function memoPageMove(module_srl, page) {
    var params = new Array();
    params['target_module_srl'] = module_srl;
    params['page'] = page;
    var response_tags = new Array('error','message','tpl');
    exec_xml('planet', 'getPlanetMemoList', params, completePlanetPageMove, response_tags);
}

function completePlanetPageMove(ret_obj, response_tags, params) {
    $('planetMemo').innerHTML = ret_obj['tpl'];
}

function updatePlanetInfo(f,target){
    if(target == 'photo') {
        if(f.photo.value) {
            f.act.value = "procPlanetPhotoModify";
            f.submit();
        }
    } else {
        f.target.value = target;
        procFilter(f, modify_planet_info);
    }
}

function completeUpdatePlanetInfo(ret_obj){
    var error = ret_obj['error'];
    var message = ret_obj['message'];
    location.reload();
}

function deletePlanetTag(f,deltag){
    $('planet_tag').value = $A($('planet_tag').value.trim().split(',')).refuse(deltag.trim())._array.join(',').trim();
    updatePlanetInfo(f,'planet_tag');
}


function doPlanetVoteContent(document_srl){
    var params = new Array();
    params['document_srl'] = document_srl;
    var response_tags = new Array('error','message');
    exec_xml('planet', 'procPlanetVoteContent', params, completeVoteContent, response_tags, params);
}
function completeVoteContent(ret_obj,response_tags, params, fo_obj) {
    var error = ret_obj['error'];
    var message = ret_obj['message'];
    var document_srl = params['document_srl'];
    if (error == '0') {
        $('content_voted:'+document_srl).innerHTML = parseInt($('content_voted:'+document_srl).innerHTML) + 1
    }
}

function completeInsertInterestTag(ret_obj) {
    $('myFavoriteTag').innerHTML = ret_obj['tpl'];
    toggle('myFavoriteTag');
}

function doDeleteInterestTags(tag) {
    var params = new Array();
    params['tag'] = tag;
    var response_tags = new Array('error','message','tpl');
    exec_xml('planet', 'procPlanetDeleteInterestTag', params, completeDeleteInterestTag, response_tags);
}

function completeDeleteInterestTag(ret_obj) {
    $('myFavoriteTag').innerHTML = ret_obj['tpl'];
    toggle('myFavoriteTag');
}

function doAddFavorite(module_srl) {
    var params = new Array();
    params['module_srl'] = module_srl;
    var response_tags = new Array('error','message');
    exec_xml('planet', 'procPlanetInsertFavorite', params, completeAddFavorite, response_tags);
}

function completeAddFavorite(ret_obj) {
    $$('.addFavorite')[0].style.display = 'none';
}


function completeInsertReply(ret_obj, response_tags, params, fo_obj) {

    $('reply_count:'+ ret_obj['document_srl']).innerHTML = parseInt($('reply_count:'+ ret_obj['document_srl']).innerHTML)+1;
    showPlanetReply(ret_obj['document_srl'],'open');
}

function showPlanetReply(document_srl,f){
    if(toggleObject($('reply:'+document_srl),f) =='open'){
        if($('writeReply:'+document_srl)) $('writeReply:'+document_srl).planet_reply_content.focus();

        var params = new Array();
        params['document_srl'] = document_srl;
        var response_tags = new Array('error','message','tpl','document_srl');
        exec_xml('planet', 'getPlanetReplyList', params, completeShowPlanetReply, response_tags);
    }

}

function completeShowPlanetReply(ret_obj, response_tags, params, fo_obj) {
    if($('writeReply:'+ret_obj['document_srl'])) $('writeReply:'+ret_obj['document_srl']).reset();
    $('reply_content:'+ret_obj['document_srl']).innerHTML = ret_obj['tpl'] == null ?'':ret_obj['tpl'];
}

function doEnableRss() {
    var params = new Array();
    var response_tags = new Array('error','message');
    exec_xml('planet', 'procPlanetEnableRss', params, function() { location.reload() }, response_tags);
}

function doDisableRss() {
    var params = new Array();
    var response_tags = new Array('error','message');
    exec_xml('planet', 'procPlanetDisableRss', params, function() { location.reload() }, response_tags);
}

function planetPreview(obj) {
    if($('btn_preview').checked){
        $Element('preview').removeClass('off');
        var text = obj.value;
        text = text.replace(/</ig,'&lt;');
        text = text.replace(/>/ig,'&gt;');
        text = text.replace(/\.\.\./g, '…');
        text = text.replace(/--/g, '—');
        $('preview_text').innerHTML = text.replace(/"([^"]*)":(mms|http|ftp|https)([^ ]+)/ig,'<a href="$2$3">$1</a>');
    }else{
        $Element('preview').addClass('off');
        $('preview_text').innerHTML = '';
    }

}

function doUpdateColorset(obj) {
    var colorset = obj.parentNode.className;
    var params = new Array();
    params['colorset'] = colorset;
    var response_tags = new Array('error','message');
    exec_xml('planet', 'procPlanetColorsetModify', params, completeUpdateColorset);
}

function completeUpdateColorset(ret_obj) {
    location.reload();
}

function completeMe2Api(ret_obj) {
    alert(ret_obj['message']);
    $Element('Me2ApiProtocol').toggleClass('open','close');
}

function toggleWriteFormHelp(obj) {
    obj.style.display = 'none';
    obj.nextSibling.style.display = 'block';
    obj.nextSibling.focus();
}



function toggle(objclass,f,type){
    var obj = $$('.'+objclass)[0];
    return toggleObject(obj,f,type);
}


function toggleObject(obj,f,type){
    var otype = {};
    if (typeof(type) == 'undefined') {
        otype = {open:'open',close:'close'};
    } else {
        var tmp = type.match(/([^|]*)|(.*)/);
        otype = {open: tmp[1],close: tmp[2]};
    }

    var act = (typeof(f)=='undefined' || f=='')?$Element(obj).hasClass(otype.open)?otype.close:otype.open:f;

    if(act == otype.close){
        $Element(obj).removeClass(otype.open);
        if(otype.close) $Element(obj).addClass(otype.close);
    }else{
        if(otype.close) $Element(obj).removeClass(otype.close);
        $Element(obj).addClass(otype.open);
    }
    return act;
}
function doFocusPlanetUserId(obj_id) {
    if(xScrollTop()) return;
    xAddEventListener(window,'load', function() {xGetElementById(obj_id).focus();} );
}
function _getPlanetContentTagEditForm(oBtn){
    for (oChild = oBtn; oChild; oChild = oChild.parentNode) {
        if (oChild.tagName.toLowerCase() == 'div' && $Element(oChild).hasClass('tag'))
            return oChild;
    }
    return false;
}

function showPlanetContentTagEditForm(oBtn,document_srl){
    var oTag = _getPlanetContentTagEditForm(oBtn);
    if(!oTag) return false;
    $Element(oTag).addClass('edit');

    $('form_planet_content_tag:'+document_srl).planet_content_tag.focus();
    return false;
}

function closePlanetContentTagEditForm(oBtn){
    var oTag = _getPlanetContentTagEditForm(oBtn);
    if(!oTag) return false;
    $Element(oTag).removeClass('edit');
}

function doPlanetPhotoUpload(obj) {
    obj.form.submit();
}


function notReadWelcome(){
    var c=$('welcome_msg');
    var params = new Array();
    params['module_srl'] = c.value;
    var response_tags = new Array('error','message');
    exec_xml('planet', 'procNotReadWelcome', params, function(){ $('welcome').style.display = 'none'; }, response_tags);
}


function getPlanetContentTags(no){
    no = parseInt(no);
    var rtn = new Array();
    var obj = document.getElementsByName('planet_content_tag:'+no);
    if(obj && obj.length>0){
        for(var i=0,c=obj.length;i<c;i++){
            rtn.push(obj[i].innerHTML);
        }
    }
    return rtn;
}

function deletePlanetContentTag(no,i){
    var arrNoTags = $A(getPlanetContentTags(no));
    $('form_planet_content_tag:'+no).planet_content_tag.value = arrNoTags.refuse(arrNoTags.$value()[i]).$value().join(',');
    procFilter($('form_planet_content_tag:'+no), modify_content_tag);
}


function doPlanetLogout() {
    var params = new Array();
    var response_tags = new Array('error','message');
    exec_xml('member', 'procMemberLogout', params, completeLogout, response_tags);
}

function completeLogout() {
    location.reload();
}

function showWritePost(){

    var o = $Element('writePost');

    // do close
    if(!o.hasClass('open')){
        toggleWritePost();
    }
    //$('writePostForm').content.focus();
    $('writePost_content').focus();
}

function closeWritePost(){
    toggle('writePost');
    //$('writePost').reset();
    //$('writePost_content').reset();
}


function toggleWritePost(){
    var o = $Element('writePost');
    var t = $Element('writeBody');

    // do close
    if(o.hasClass('open')){

        if($Agent().navigator().ie){
            closeWritePost();
        }else{
            t.attr('style','overflow:hidden');
            moveHeight('writeBody',{end:140,callback:function(){t.attr('style','');toggle('writePost');}});
        }

        $Cookie().set('writePost','close',30);
        //$('writePostForm').reset();
    // do open
    }else{
        if ($Agent().navigator().ie) {
          toggle('writePost');
        }else{
            toggle('writePost');
            t.attr('style','overflow:hidden');
            t.height(0);
            moveHeight('writeBody',{start:0,end:30,callback:function(){t.attr('style','');}});

        }

        $Cookie().set('writePost','open',30);
        $('writePost_content').focus();

    }
}



function showWriteMemo(){
    toggle('memo','close');
    toggle('form');
    $('planet_memo').focus();
}


function showBtnDeleteTag(o){
    toggleObject(o,'hover','hover|');
}

function closeBtnDeleteTag(o){
    toggleObject(o,'','hover|');
}

function togglePreview(){
    var e = $Element('preview');

    if ($Cookie().get('preview') == 'off') {
        $Cookie().set('preview', '', 30);
        if ($('writePostForm').content.value.length>1) {
            planetPreview($('writePostForm').content);
        }
    } else {
        $Cookie().set('preview', 'off', 30);
        if(!e.hasClass('off')) e.addClass('off');

    }
    $('writePostForm').content.focus();
}

function toggleTagRank(){
    var o = $Element($$('.layer')[0]);
    // do close
    if($Element($$('.tagRank')[0]).hasClass('open')){
        o.disappear(0,function(){toggle('tagRank','close');o.attr('style','');})

    // do open
    }else{
        o.appear(0,function(){toggle('tagRank','open');})
    }

}


function moveHeight(obj,option){
    var self = this;
    this.obj = $Element(obj);
    this.start = typeof option.start == 'undefined' ? this.obj.height() : option.start;
    this.end = option.end;
    this.p = this.start < this.end ? 1 : -1;
    this.s = 9;
    this.callback = option.callback || new Function;

    var func = function(){
        self.s *= 1.2;
        if (self.p >0 ? self.start <= self.end : self.start >= self.end) {
            self.start = self.obj.height() + p*self.s;
            self.obj.height(self.start);
            self._timer = setTimeout(func, 4);
        }else{
            self.obj.height(self.end);
            self.callback();
        }
    };
    func();
}

function toggleMemo(){

    var p = $Element('planetMemo');
    var f = $Element('planetMemoFirst');
    var ul = $Element('planetMemoList');
    if(ul.visible()){
        p.removeClass('open');
        //f.show();
        ul.hide();

    }else{
        p.addClass('open');
        //f.hide();
        ul.show();
        p.opacity(0);
        p.appear(0,function(){});
    }

}
function showWriteMemoForm(){
    if($Element('planetMemoList').visible()){
        toggleMemo();
    }
    toggle('form');
    $('planet_memo').focus();
}

xAddEventListener(window,'load', function() {
    if(!$('btn_preview')) return;
    if($Cookie().get('preview')=='off'){
        $('btn_preview').checked = false;
    }else{
        $('btn_preview').checked = true;
    }
});

xAddEventListener(window,'load', function() {
    if(!$('writePost')) return;
    if($Cookie().get('writePost')!='close'){
        toggleObject('writePost','open');
        //$Cookie().set('writePost','open',30);
    }else{
        toggleObject('writePost','close');
        //$Cookie().set('writePost','',30);
    }

});




function showInsertPhoneNumber(){
    var p = $Element(cssquery('form.mobile dl')[0]);
    if(p.hasClass('open')){
        closeInsertPhoneNumber();
    }else{
        p.addClass('open');
        cssquery('form.mobile input[name=phone_number]')[0].focus();
    }
}

function closeInsertPhoneNumber(){
    $Element(cssquery('form.mobile dl')[0]).removeClass('open');
}

function setPhoneNumber(f){
    var phone_number = f.phone_number[0].value + f.phone_number[1].value + f.phone_number[2].value;
    if(phone_number.length >= 10){
        var response_tags = new Array('error','message');
        exec_xml('planet','procPlanetSetSMS',{'phone_number':phone_number},resultSetPhoneNumber,response_tags);
    }
}

function resultSetPhoneNumber(ret_obj, response_tags, params) {
    if(ret_obj.message) alert(ret_obj.message);
    closeInsertPhoneNumber();
}


function setTag(tag){
    tag = tag.trim();
    toggleWriteFormHelp(cssquery('input[name=about_tag]')[0]);
    var input_tag = cssquery('input[name=content_tag]')[0];
    var ck = 0;
    if(input_tag.value){
        var taglist = input_tag.value + ','+tag;
        taglist = taglist.split(',');
        for(var i=0,c=taglist.length;i<c;i++){
            taglist[i] = taglist[i].trim();
            if(taglist[i] == tag) ck++;
        }

        if(ck>1){
            taglist = $A(taglist).refuse(tag).$value();
        }

        input_tag.value = $A(taglist).unique().$value().join(',');
    }else{
        input_tag.value = tag;
    }
}
function modify_planet_info(fo_obj) {
	var oFilter = new XmlJsFilter(fo_obj, "planet", "procPlanetInfoModify", completeUpdatePlanetInfo);
	oFilter.addFieldItem("mid",true,0,0,"","");
	oFilter.addFieldItem("target",true,0,0,"","");
	oFilter.addFieldItem("planet_tag",false,0,250,"","");
	oFilter.addFieldItem("planet_name",false,0,250,"","");
	oFilter.addFieldItem("browser_title",false,0,250,"","");
	oFilter.addFieldItem("planet_info_photo",false,0,250,"","");
	oFilter.addParameterItem("mid","mid");
	oFilter.addParameterItem("target","target");
	oFilter.addParameterItem("planet_tag","planet_tag");
	oFilter.addParameterItem("planet_name","planet_name");
	oFilter.addParameterItem("browser_title","browser_title");
	oFilter.addParameterItem("planet_info_photo","planet_info_photo");
	oFilter.addResponseItem("error");
	oFilter.addResponseItem("message");
	return oFilter.proc();
}
alertMsg["mid"] = "모듈이름";
alertMsg["target"] = "대상";
alertMsg["planet_tag"] = "planet_tag";
alertMsg["planet_name"] = "planet_name";
alertMsg["browser_title"] = "브라우저 제목";
alertMsg["planet_info_photo"] = "planet_info_photo";
target_type_list["mid"] = "";
target_type_list["target"] = "";
target_type_list["planet_tag"] = "";
target_type_list["planet_name"] = "";
target_type_list["browser_title"] = "";
target_type_list["planet_info_photo"] = "";
alertMsg["isnull"] = "%s의 값을 입력해주세요";
alertMsg["outofrange"] = "%s의 글자 길이를 맞추어 주세요.";
alertMsg["equalto"] = "%s의 값이 잘못 되었습니다.";
alertMsg["invalid_email"] = "%s의 형식이 잘못되었습니다. (예: zbxe@zeroboard.com)";
alertMsg["invalid_userid"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_user_id"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_homepage"] = "%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)";
alertMsg["invalid_korean"] = "%s의 형식이 잘못되었습니다. 한글로만 입력해주셔야 합니다";
alertMsg["invalid_korean_number"] = "%s의 형식이 잘못되었습니다. 한글과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_alpha"] = "%s의 형식이 잘못되었습니다. 영문으로만 입력해주셔야 합니다";
alertMsg["invalid_alpha_number"] = "%s의 형식이 잘못되었습니다. 영문과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_number"] = "%s의 형식이 잘못되었습니다. 숫자로만 입력해주셔야 합니다";

function insert_interest_tag(fo_obj) {
	var oFilter = new XmlJsFilter(fo_obj, "planet", "procPlanetInsertInterestTag", completeInsertInterestTag);
	oFilter.addFieldItem("tag",true,1,255,"","");
	oFilter.addResponseItem("error");
	oFilter.addResponseItem("message");
	oFilter.addResponseItem("tpl");
	return oFilter.proc();
}
alertMsg["tag"] = "태그";
target_type_list["tag"] = "";
alertMsg["isnull"] = "%s의 값을 입력해주세요";
alertMsg["outofrange"] = "%s의 글자 길이를 맞추어 주세요.";
alertMsg["equalto"] = "%s의 값이 잘못 되었습니다.";
alertMsg["invalid_email"] = "%s의 형식이 잘못되었습니다. (예: zbxe@zeroboard.com)";
alertMsg["invalid_userid"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_user_id"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_homepage"] = "%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)";
alertMsg["invalid_korean"] = "%s의 형식이 잘못되었습니다. 한글로만 입력해주셔야 합니다";
alertMsg["invalid_korean_number"] = "%s의 형식이 잘못되었습니다. 한글과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_alpha"] = "%s의 형식이 잘못되었습니다. 영문으로만 입력해주셔야 합니다";
alertMsg["invalid_alpha_number"] = "%s의 형식이 잘못되었습니다. 영문과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_number"] = "%s의 형식이 잘못되었습니다. 숫자로만 입력해주셔야 합니다";

// Hide And Show Toggle
var cc=0
function hideShow(id) {
    if (cc==0) {
        cc=1
        document.getElementById(id).style.display="none";
    } else {
        cc=0
        document.getElementById(id).style.display="block";
    }
}

// Show And Hide Toggle
var cc=0
function showHide(id) {
    if (cc==0) {
        cc=1
        document.getElementById(id).style.display="block";
    } else {
        cc=0
        document.getElementById(id).style.display="none";
    }
}

// Local Navigation Toggle
function lnbToggle(id) {
	for(num=1; num<=3; num++) document.getElementById('D3MG'+num).style.display='none'; //D4MG1~D4MG3 까지 숨긴 다음
	document.getElementById(id).style.display='block'; //해당 ID만 보임
}

// IS
function chkIsKind(key, value) {
    showHide('selectOrder');
    xGetElementById('search_target'+key).checked = true;
    xInnerHtml('search_target_label', value);
}

// bookmark
function bookmarksite(title,url) {
   if (window.sidebar) // firefox 
   window.sidebar.addPanel(title, url, ""); 
   else if(window.opera && window.print)

   { // opera 
      var elem = document.createElement('a'); 
      elem.setAttribute('href',url); 
      elem.setAttribute('title',title); 
      elem.setAttribute('rel','sidebar'); 
      elem.click(); 
   } 

   else if(document.all) // ie
   window.external.AddFavorite(url, title);
}

// background color
function tile(){
if (!document.all)
return
var source=event.srcElement
if (source.tagName=="IMG")
document.body.style.backgroundImage="url("+source.src+")"
}


// mini menu
function divDisplay(divId,flag){

	if (flag == "true")
	{			
		document.getElementById("minimenu"+divId).style.display = "block";
		document.getElementById("arrow"+divId).src="/images/button/btn_mini_on.gif" // 마우스 오버시 이미지경로
		
	}else{
		document.getElementById("minimenu"+divId).style.display = "none";
		document.getElementById("arrow"+divId).src="/images/button/btn_mini_off.gif" // 마우스 아웃시 이미지경로
	}

}






var browserType=''; 

if(navigator.userAgent.indexOf("MSIE") >-1) {
   browserType = 'IE'; 
} else if(navigator.userAgent.indexOf("Firefox") >-1) {
   browserType = 'FF'; 
} else {
   browserType = 'OTHER'; 
}

function gnbinToggle(id, mmblock) {
	if(browserType == 'FF') {
		gnbinToggleFF(id, mmblock);
	} else {
		gnbinToggleIE(id, mmblock);
	}
}

// Local Navigation Toggle
function gnbinToggleIE(id, mmblock) {
//	var mmid_count = document.forms['form_menu']['mmid_count'].value;

	for(num=0; num<mmid_count; num++) {
		document.getElementById('mmid'+num).style.display='none';
		document.getElementById('mmli'+num).setAttribute('className', 'off');
	}
//	alert(mmid_count);
//	alert(document.getElementById('mmli0').className);
	document.getElementById('mmid'+id).style.display='block';
	mmblock.className = "on";
}

// Local Navigation Toggle
function gnbinToggleFF(id, mmblock) {
//    var mobj = document.getElementsByName('mmli');

	for(var num=0; num<mmid_count; num++) {
//		mobj[num].className = null;

		document.getElementById('mmid'+num).style.display='none';
		document.getElementById('mmli'+num).className = null;
	}
	document.getElementById('mmid'+id).style.display = '';
	mmblock.className = 'on';
}

// Hide And Show Toggle
var cc=0
function hideShow(id) {
    if (cc==0) {
        cc=1
        document.getElementById(id).style.display="none";
    } else {
        cc=0
        document.getElementById(id).style.display="block";
    }
}

// Show And Hide Toggle
var cc=0
function showHide(id) {
    if (cc==0) {
        cc=1
        document.getElementById(id).style.display="block";
    } else {
        cc=0
        document.getElementById(id).style.display="none";
    }
}

// Local Navigation Toggle
function lnbToggle(id) {
	for(num=1; num<=3; num++) document.getElementById('D3MG'+num).style.display='none'; //D4MG1~D4MG3 까지 숨긴 다음
	document.getElementById(id).style.display='block'; //해당 ID만 보임
}

// IS
function chkIsKind(key, value) {
    showHide('selectOrder');
    xGetElementById('search_target'+key).checked = true;
    xInnerHtml('search_target_label', value);
}

 function resizeFrame(iframeObj){
/* 아이프레임에서 읽어들인 페이지의 body */
var innerBody = iframeObj.contentWindow.document.body;

/* 높이 다시설정 */
var innerHeight = innerBody.scrollHeight + (innerBody.offsetHeight - innerBody.clientHeight);
iframeObj.style.height = innerHeight;

/* 넓이 다시설정 */
var innerWidth = innerBody.scrollWidth + (innerBody.offsetWidth - innerBody.clientWidth);
iframeObj.style.width = innerWidth;     

this.scrollTo(1,1); 
}

/**
 * @brief 뉴스티커 형식으로 표시하기 위한 초기화 작업
 **/

var newsTickerMoveUpStep = new Array();
function doStartScroll(id, itemHeight, scrollSpeed) {
    var pObj = xGetElementById(id);
    var childObj = pObj.firstChild;

    while(childObj) {
        if(childObj.nodeName == 'UL') {
            childObj.id = id+'_first';
            var cloneObj = childObj.cloneNode(true);
            cloneObj.id = id+'_second';
            childObj.parentNode.insertBefore(cloneObj, childObj);

            var ticker = {"pObj":pObj, "child":childObj, "itemHeight":itemHeight, "scrollSpeed":scrollSpeed}

            newsTickerMoveUpStep[id] = 1;

            xAddEventListener(pObj, 'mouseover', function() { newsTickerMoveUpStep[id] = 0; } );
            xAddEventListener(pObj, 'mouseout', function() { newsTickerMoveUpStep[id] = 1; } );

            doScroll(ticker);
            return;
        }
        childObj = childObj.nextSibling;
    }

}
function doScroll(obj) {
    var st = obj.pObj.scrollTop;
    st += newsTickerMoveUpStep[obj.pObj.id];

    if(st > xHeight(obj.child)) st = 0;
    obj.pObj.scrollTop = st;

    if(obj.pObj.scrollTop % obj.itemHeight == 0) setTimeout( function() { doScroll(obj); }, 2500 );
    else setTimeout( function() { doScroll(obj); }, obj.scrollSpeed );

}

function widget_login(fo_obj) {
	var oFilter = new XmlJsFilter(fo_obj, "member", "procMemberLogin", completeLogin);
	oFilter.addFieldItem("user_id",true,0,0,"","user_id");
	oFilter.addFieldItem("password",true,0,0,"","");
	oFilter.addResponseItem("error");
	oFilter.addResponseItem("message");
	return oFilter.proc();
}
alertMsg["user_id"] = "아이디";
alertMsg["password"] = "비밀번호";
target_type_list["user_id"] = "user_id";
target_type_list["password"] = "";
alertMsg["isnull"] = "%s의 값을 입력해주세요";
alertMsg["outofrange"] = "%s의 글자 길이를 맞추어 주세요.";
alertMsg["equalto"] = "%s의 값이 잘못 되었습니다.";
alertMsg["invalid_email"] = "%s의 형식이 잘못되었습니다. (예: zbxe@zeroboard.com)";
alertMsg["invalid_userid"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_user_id"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_homepage"] = "%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)";
alertMsg["invalid_korean"] = "%s의 형식이 잘못되었습니다. 한글로만 입력해주셔야 합니다";
alertMsg["invalid_korean_number"] = "%s의 형식이 잘못되었습니다. 한글과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_alpha"] = "%s의 형식이 잘못되었습니다. 영문으로만 입력해주셔야 합니다";
alertMsg["invalid_alpha_number"] = "%s의 형식이 잘못되었습니다. 영문과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_number"] = "%s의 형식이 잘못되었습니다. 숫자로만 입력해주셔야 합니다";

function openid_login(fo_obj) {
	var oFilter = new XmlJsFilter(fo_obj, "member", "procMemberOpenIDLogin", completeOpenIDLogin);
	oFilter.addFieldItem("user_id",true,0,0,"","");
	oFilter.addResponseItem("error");
	oFilter.addResponseItem("message");
	return oFilter.proc();
}
alertMsg["user_id"] = "아이디";
target_type_list["user_id"] = "";
alertMsg["isnull"] = "%s의 값을 입력해주세요";
alertMsg["outofrange"] = "%s의 글자 길이를 맞추어 주세요.";
alertMsg["equalto"] = "%s의 값이 잘못 되었습니다.";
alertMsg["invalid_email"] = "%s의 형식이 잘못되었습니다. (예: zbxe@zeroboard.com)";
alertMsg["invalid_userid"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_user_id"] = "%s의 형식이 잘못되었습니다.\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
alertMsg["invalid_homepage"] = "%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)";
alertMsg["invalid_korean"] = "%s의 형식이 잘못되었습니다. 한글로만 입력해주셔야 합니다";
alertMsg["invalid_korean_number"] = "%s의 형식이 잘못되었습니다. 한글과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_alpha"] = "%s의 형식이 잘못되었습니다. 영문으로만 입력해주셔야 합니다";
alertMsg["invalid_alpha_number"] = "%s의 형식이 잘못되었습니다. 영문과 숫자로만 입력해주셔야 합니다";
alertMsg["invalid_number"] = "%s의 형식이 잘못되었습니다. 숫자로만 입력해주셔야 합니다";

/* 로그인 영역에 포커스 */
function doFocusUserId(fo_id) {
    if(xScrollTop()) return;
    var fo_obj = xGetElementById(fo_id);
    if(fo_obj.user_id) {
        try{
            fo_obj.user_id.focus();
        } catch(e) {};
    }
}

/* 로그인 후 */
function completeLogin(ret_obj, response_tags, params, fo_obj) {
    var url =  current_url.setQuery('act','');
    location.href = url;
}

/* 오픈아이디 로그인 후 */
function completeOpenIDLogin(ret_obj, response_tags) {
    var redirect_url =  ret_obj['redirect_url'];
    location.href = redirect_url;
}

/* 오픈 아이디 폼 변환 */
function toggleLoginForm(obj) {
    if(xGetElementById('login').style.display != "none") {
        xGetElementById('login').style.display = "none";
        xGetElementById('openid_login').style.display = "block";
        xGetElementById('use_open_id_2').checked = true;
    } else {
        xGetElementById('openid_login').style.display = "none";
        xGetElementById('login').style.display = "block";
        xGetElementById('use_open_id').checked = false;
        xGetElementById('use_open_id_2').checked = false;
    }
}

/* 폼 이미지 */
function clrImg(obj){obj.style.backgroundImage="";obj.onkeydown=obj.onmousedown=null;}
