/* modsAX Javascript Library, Version 1.0
 * modsAX.com 2009-2010 squall
 * update : modsAX.js 2010-11-09 V1.1
 * modsAX are licensed under a Creative Commons Attribution 3.0 license.
 * http://creativecommons.org/licenses/by/3.0/deed.ko
 * If you don't want to author Link
 * You must register. Join the modsAX license member then you free use modsAX
 * http://www.modsAX.com
-------------------------------------------------------------------------------------------------------------------------------------------------  */


/* jQuery easing plugin */
jQuery.extend(true, {
  easing: {
    backIn    :function(p, n, f, d){var c=f+d;var s = 1.70158;return c*(p/=1)*p*((s+1)*p - s) + f;},
    backOut   :function(p, n, f, d){var c=f+d;var s = 1.70158;return c*((p=p/1-1)*p*((s+1)*p + s) + 1) + f;},
    backInOut :function(p, n, f, d){var c=f+d;var s = 1.70158;if ((p/=0.5) < 1) return c/2*(p*p*(((s*=(1.525))+1)*p - s)) + f;else return c/2*((p-=2)*p*(((s*=(1.525))+1)*p + s) + 2) + f;},
    bounceIn  :function(p, n, f, d){var c=f+d;var inv = this.bounceOut (1-p, 1, 0, d);return c - inv + f;},
    bounceOut :function(p, n, f, d){var c=f+d;if (p < (1/2.75)) return c*(7.5625*p*p) + f;else if (p < (2/2.75)) return c*(7.5625*(p-=(1.5/2.75))*p + .75) + f; else if (p < (2.5/2.75)) return c*(7.5625*(p-=(2.25/2.75))*p + .9375) + f;else return c*(7.5625*(p-=(2.625/2.75))*p + .984375) + f;},
    circIn    :function(p, n, f, d){var c=f+d;return -c * (Math.sqrt(1 - (p/=1)*p) - 1) + f;},
    circOut   :function(p, n, f, d){var c=f+d;return c * Math.sqrt(1 - (p=p/1-1)*p) + f;},
    circInOut :function(p, n, f, d){var c=f+d;if ((p/=0.5) < 1) return -c/2 * (Math.sqrt(1 - p*p) - 1) + f;else return c/2 * (Math.sqrt(1 - (p-=2)*p) + 1) + f;},
    cubicIn   :function(p, n, f, d){var c=f+d;return c*(p/=1)*p*p + f;},
    cubicOut  :function(p, n, f, d){var c=f+d;return c*((p=p/1-1)*p*p + 1) + f;},
    cubicInOut:function(p, n, f, d){var c=f+d;if ((p/=0.5) < 1) return c/2*p*p*p + f;else return c/2*((p-=2)*p*p + 2) + f;},
    elasticIn :function(p, n, f, d){var c=f+d;if (p==0) return f;if (p==1) return c;var peroid = 0.25;var s;var amplitude = c;if (amplitude < Math.abs(c)){amplitude = c;s = peroid/4;}else{s = peroid/(2*Math.PI) * Math.asin (c/amplitude);}return -(amplitude*Math.pow(2,10*(p-=1)) * Math.sin( (p*1-s)*(2*Math.PI)/peroid )) + f;},
    elasticOut:function(p, n, f, d){var c=f+d;if (p==0) return f;if (p==1) return c;var peroid = 0.25;var s;var amplitude = c;if (amplitude < Math.abs(c)){amplitude = c;s = peroid/4;}else{s = peroid/(2*Math.PI) * Math.asin (c/amplitude);}return -(amplitude*Math.pow(2,-10*p) * Math.sin( (p*1-s)*(2*Math.PI)/peroid )) + c;},
    expoIn    :function(p, n, f, d){var c=f+d;return (p==0) ? f : c * Math.pow(2, 10 * (p - 1)) + f - c * 0.001;},
    expoOut   :function(p, n, f, d){var c=f+d;return (p==1) ? c : d * 1.001 * (-Math.pow(2, -10 * p) + 1) + f;},
    expoInOut :function(p, n, f, d){var c=f+d;if (p==0) return f;if (p==1) return c;if ((p/=0.5) < 1) return c/2 * Math.pow(2, 10 * (p - 1)) + f - c * 0.0005;else return c/2 * 1.0005 * (-Math.pow(2, -10 * --p) + 2) + f;},
    quadIn    :function(p, n, f, d){var c=f+d;return c*(p/=1)*p + f;},
    quadOut   :function(p, n, f, d){var c=f+d;return -c *(p/=1)*(p-2) + f;},
    quadInOut :function(p, n, f, d){var c=f+d;if ((p/=0.5) < 1) return c/2*p*p + f;else return -c/2 * ((--p)*(p-2) - 1) + f;},
    quartIn   :function(p, n, f, d){var c=f+d;return c*(p/=1)*p*p*p + f;},
    quartOut  :function(p, n, f, d){var c=f+d;return -c * ((p=p/1-1)*p*p*p - 1) + f;},
    quartInOut:function(p, n, f, d){var c=f+d;if ((p/=0.5) < 1) return c/2*p*p*p*p + f;else return -c/2 * ((p-=2)*p*p*p - 2) + f;},
    quintIn   :function(p, n, f, d){var c=f+d;return c*(p/=1)*p*p*p*p + f;},
    quintOut  :function(p, n, f, d){var c=f+d;return c*((p=p/1-1)*p*p*p*p + 1) + f;},
    quintInOut:function(p, n, f, d){var c=f+d;if ((p/=0.5) < 1) return c/2*p*p*p*p*p + f;else return c/2*((p-=2)*p*p*p*p + 2) + f;},
    sineIn    :function(p, n, f, d){var c=f+d;return -c * Math.cos(p * (Math.PI/2)) +c + f;},
    sineOut   :function(p, n, f, d){var c=f+d;return c * Math.sin(p * (Math.PI/2)) + f;},
    sineInOut :function(p, n, f, d){var c=f+d;return -c/2 * (Math.cos(Math.PI*p) - 1) + f;}
  }
});
/* jQuery easing plugin
-------------------------------------------------------------------------------------------------------------------------------------------------  */

/* jQuery misc plugin */
jQuery.fn.scrollToDiv = function(margin, boxDim){
  var pElement  = this.offsetParent();
  var pBox = {width:pElement.width, height:pElement.height()};
  if(boxDim){
    if(boxDim.width > 0) pBox.width = boxDim.width;
    if(boxDim.height > 0) pBox.height = boxDim.height;
  }
  var pos       = this.position();
  if(margin)  var m   = {left:margin.left||0, top:margin.top||0, right:margin.right||0, bottom:margin.bottom||0};
  else        var m = {left:0, top:0, right:0, bottom:0};
  var ePos      = {left:pos.left + this.outerWidth(), top:pos.top + this.outerHeight()};
  var pEbox     = {width:pBox.width - m.right, height:pBox.height - m.bottom}
  var pES       = {left:pElement.scrollLeft(), top:pElement.scrollTop()}
  if(ePos.top > pEbox.height){
    pElement.scrollTop(ePos.top - pEbox.height + pES.top + 1 );
  }else if( (ePos.top - this.outerHeight() - m.top) < 0 ){
    pElement.scrollTop( pES.top + (ePos.top - this.outerHeight() - m.top) );
  }
  if(ePos.left > pEbox.width){
    pElement.scrollLeft(ePos.left - pEbox.width + pES.left + 1 );
  }else if( (ePos.left - this.outerWidth() - m.left) < 0 ){
    pElement.scrollLeft( pES.left + (ePos.left - this.outerWidth() - m.left) );
  }
  //$("#msg").html( this[0].id + "," + (ePos.top - this.height().number() - m.top) + "," + (pElement.scrollTop()) + "," + pElement.height() )
  return this;
};
/* jQuery misc plugin
-------------------------------------------------------------------------------------------------------------------------------------------------  */

/* Based on Prototype JavaScript framework, version 1.6.1 inheritance implementation */
var Class=(function(){function subclass(){};function create(){var parent=null,properties=$A(arguments);if(Object.isFunction(properties[0]))parent=properties.shift();function klass(){this.initialize.apply(this, arguments);}Object.extend(klass, Class.Methods);klass.superclass=parent;klass.subclasses=[];if(parent){subclass.prototype=parent.prototype;klass.prototype=new subclass;parent.subclasses.push(klass);}for (var i=0; i < properties.length; i++)klass.addMethods(properties[i]);if(!klass.prototype.initialize)klass.prototype.initialize=Prototype.emptyFunction;klass.prototype.constructor=klass;return klass;}function addMethods(source){var ancestor=this.superclass && this.superclass.prototype;var properties=Object.keys(source);if(!Object.keys({ toString: true }).length){if(source.toString != Object.prototype.toString)properties.push("toString");if(source.valueOf != Object.prototype.valueOf)properties.push("valueOf");}for (var i=0, length=properties.length; i < length; i++){var property=properties[i], value=source[property];if(ancestor && Object.isFunction(value) && value.argumentNames().first() == "$super"){var method=value;value=(function(m){return function(){ return ancestor[m].apply(this, arguments); };})(property).wrap(method);value.valueOf=method.valueOf.bind(method);value.toString=method.toString.bind(method);}this.prototype[property]=value;}return this;}return {create:create,Methods:{addMethods: addMethods}};})();(function(){var _toString=Object.prototype.toString;function extend(destination,source){for(var property in source) destination[property]=source[property];return destination;}function inspect(obj){try {if(isUndefined(obj)) return 'undefined';if(obj === null) return 'null';return obj.inspect ? obj.inspect() : String(obj);} catch (e){if(e instanceof RangeError) return '...';throw e;}}
function toJSON(object) {
  var type = typeof object;
  switch (type) {
    case 'undefined':
    case 'function':
    case 'unknown': return;
    case 'boolean': return object.toString();
  }
  if (object === null) return 'null';
  if (object.toJSON) return object.toJSON();
  if (isElement(object)) return;
  var results = [];
  for (var property in object) {
    var value = toJSON(object[property]);
    if (!isUndefined(value))
      results.push(property.toJSON() + ': ' + value);
  }
  return '{' + results.join(', ') + '}';
}
function toHTML(obj){return obj && obj.toHTML ? obj.toHTML() : String.interpret(obj);}function keys(obj){var results=[];for (var property in obj)results.push(property);return results;}function values(obj){var results=[];for(var property in obj)results.push(obj[property]);return results;}function clone(obj){return extend({ }, obj);}function isElement(obj){return !!(obj && obj.nodeType == 1);}function isArray(obj){return _toString.call(obj) == "[object Array]";}function isHash(obj){return obj instanceof Hash;}function isFunction(obj){return typeof obj==="function";}function isString(obj){return _toString.call(obj)=="[object String]";}function isNumber(obj){return _toString.call(obj)=="[object Number]";}function isUndefined(obj){return typeof obj==="undefined";}
extend(Object,{extend:extend,inspect:inspect,toJSON:toJSON,toHTML:toHTML,keys:keys,values:values,clone:clone,isElement:isElement,isArray:isArray,isHash:isHash,isFunction:isFunction,isString:isString,isNumber:isNumber,isUndefined:isUndefined});})();
Object.extend(Function.prototype,(function(){var slice=Array.prototype.slice;function update(array,args){var arrayLength=array.length, length=args.length;while(length--)array[arrayLength+length]=args[length];return array;}function merge(array, args){array=slice.call(array, 0);return update(array, args);}function argumentNames(){var names=this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1].replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '').replace(/\s+/g, '').split(',');return names.length == 1 && !names[0] ? [] : names;}function bind(context){if(arguments.length < 2 && Object.isUndefined(arguments[0])) return this;var __method=this, args=slice.call(arguments, 1);return function(){var a=merge(args, arguments);return __method.apply(context, a);}}function bindAsEventListener(context){var __method=this, args=slice.call(arguments, 1);return function(event){var a=update([event || window.event], args);return __method.apply(context, a);}}function curry(){if(!arguments.length) return this;var __method=this, args=slice.call(arguments, 0);return function(){var a=merge(args, arguments);return __method.apply(this, a);}}function delay(timeout){var __method=this, args=slice.call(arguments, 1);timeout=timeout * 1000;return window.setTimeout(function(){return __method.apply(__method, args);}, timeout);}function defer(){var args=update([0.01], arguments);return this.delay.apply(this, args);}function wrap(wrapper){var __method=this;return function(){var a=update([__method.bind(this)], arguments);return wrapper.apply(this, a);}}function methodize(){if(this._methodized) return this._methodized;var __method=this;return this._methodized=function(){var a=update([this], arguments);return __method.apply(null, a);};}return {argumentNames:argumentNames,bind:bind,bindAsEventListener:bindAsEventListener,curry:curry,delay:delay,defer:defer,wrap:wrap,methodize:methodize}})());
/*  Based on Prototype JavaScript framework End
-------------------------------------------------------------------------------------------------------------------------------------------------  */


/* Object prototype extend - modsAX Prototypes
   String, Number, Date, Error */
Object.extend(String.prototype, (function(){
  function left(strLen){ return this.toString().substr(0, strLen); }
  function right(strLen){ return this.substring(this.length-strLen, this.length); }
  function dec(){ return decodeURIComponent(this.replace(/\+/g, " ")); }
  function enc(){ return encodeURIComponent(this); }
  function object(){
    try{var res = this.evalJSON();}
    catch(e){ 
      res = {result:"err", msg:"to object error, "+e.print()+", "+this};
      try{
        mask.close();
      }catch(e){}
    }
    return res;
  }
  function array(){
    try{ var res = "["+this+"]".evalJSON(); }
    catch(e){ res = {result:"err", msg:"to object error, "+e.print()+", "+this}; }
    return res;
  }
  function toDate(separator){
    if(this.length == 10){
      try{
        var aDate = this.split(separator || "-");
    		return new Date(aDate[0], (parseFloat(aDate[1])-1), parseFloat(aDate[2]));
  		}catch(e){
  		  return new Date();
  		}
		}else{
		  return new Date();
		}
  }
  function toNum(){
    var pair = this.replace(/,/g, "").split(".");
    pair[0] = pair[0].replace(/[^-][\D]/gi, "");
    if(pair[1]){
      pair[1] = pair[1].replace(/\D/gi, "");
      return parseFloat(pair[0]+"."+pair[1]) || 0;
    }else{
      return parseFloat(pair[0]) || 0; 
    }
  }
  function parseF(){
    return parseFloat(this); 
  }
  function strip(){ return this.replace(/^\s+/, '').replace(/\s+$/, ''); }
  function stripTags(){ return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); }
  function times(count){
    return count < 1 ? '' : new Array(count + 1).join(this);
  }
  function inspect(useDoubleQuotes) {
    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
      if (character in String.specialChar) {
        return String.specialChar[character];
      }
      return '\\u00' + character.charCodeAt().pad(2, 16);
    });
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  }
  function toJSON() {
    return this.inspect(true);
  }
  function blank() {
    return /^\s*$/.test(this);
  }
  function isJSON() {
    var str = this;
    if (str.isBlank()) return false;
    str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
  }
  function unfilterJSON(filter) {
    return this.replace(filter || mods.JSONFilter, '$1');
  }
  function evalJSON(sanitize) {
    var json = this.unfilterJSON();
    try {
      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
      else return {result:"err", msg:"JSON syntax error. fail to convert Object"};
    } catch (e) {
      return {result:"err", msg:"JSON syntax error. fail to convert Object", body:this};
    }
  }
  function queryToObject(separator) {
    var match = this.trim().match(/([^?#]*)(#.*)?$/);
    if (!match) return { };
    var rs = match[1].split(separator || '&');
    var returnObj = {};
    var i=0;
    while(i < rs.length){
      var pair = rs[i].split("=");
      var k = pair[0], v = pair[1];
      if(returnObj[k] != undefined){
        if (!Object.isArray(returnObj[k])) returnObj[k] = [returnObj[k]];
        returnObj[k].push(v);
      }else{
        returnObj[k] = v;
      }
      i++;
    }
    return returnObj;
  }
  function crlf(replaceTarget, replacer){
    return this.replace((replaceTarget || /\n/g), (replacer || "<br/>")); 
  }
  function ecrlf(replaceTarget, replacer){
    return this.replace((replaceTarget || /%0A/g), (replacer || "<br/>")); 
  }
  function toPad(length, radix) {
    var string = this.toString(radix || 10);
    return '0'.times(length - string.length) + string;
  }
  function toColor(){
	if(this.left(3) == "rgb"){
		var val = this;
		var reAt = /rgb\((.+)\)/;
		val.match(reAt);
		var vals = RegExp.$1.split(", ");
	    for(var a=0;a<vals.length;a++){
	    	vals[a] = vals[a].number().pad(2, 16);
	    }
	    return vals.join("");
	}else{
		return this.replace("#", "");	
	}
  }
  function getFileName(){
    var sToMatch = this;
    var reAt = /[\/\\]?([^\/\\]?\.?[^\/\\]+)$/;
    var reArr = sToMatch.match(reAt);
  	return RegExp.$1;
  }
  return {
    left: left,
    right: right,
    dec: dec,
    enc: enc,
    object: object,
    array: array,
    date: toDate,
    number: toNum,
    num: parseF,
    trim: strip,
    delHtml: stripTags,
    times: times,
    inspect: inspect,
    toJSON: toJSON,
    isBlank: blank,
    isJSON: isJSON,
    unfilterJSON: unfilterJSON,
    evalJSON: evalJSON,
    queryToObject: queryToObject,
    crlf: crlf,
    ecrlf: ecrlf,
    pad: toPad,
    toColor: toColor,
    getFileName: getFileName
  }
})());

Object.extend(Number.prototype, (function(){
  function left(strLen){
    return this.toString().substr(0, strLen);
  }
  function right(strLen){
    return this.toString().substring(this.toString().length-strLen, this.toString().length);
  }
  function toMoney(){
    var txtNumber = '' + this;
  	if (isNaN(txtNumber) || txtNumber == "") {
  	  return "";
  	}else{
  		var rxSplit = new RegExp('([0-9])([0-9][0-9][0-9][,.])');
  		var arrNumber = txtNumber.split('.');
  		arrNumber[0] += '.';
      do {
  		arrNumber[0] = arrNumber[0].replace(rxSplit, '$1,$2');
  	  } while (rxSplit.test(arrNumber[0]));
  		if (arrNumber.length > 1) {
  			return arrNumber.join('');
  		} else {
  			return arrNumber[0].split('.')[0];
  		}
  	}
  }
  function toByte(){
	var n_unit = "KB"
	var myByte = this / 1024;
	if(myByte/1024 > 1){
		n_unit = "MB"
		myByte = myByte/1024;
	}
	if(myByte/1024 > 1){
		n_unit = "GB"
		myByte = myByte/1024;
	}
	return myByte.round(1) + n_unit;	
  }
  function toNum(){
    return this;
  }
  function toPad(length, radix) {
    var string = this.toString(radix || 10);
    return '0'.times(length - string.length) + string;
  }
  function range(start){
    var ra =  [];
    for(var a=(start || 0);a < this + 1;a++)
      ra.push(a);
    return ra;
  }
  function toJSON(){
    return this.toString();
  }
  function abs() {
    return Math.abs(this);
  }
  function round(digit) {
    return Math.round(this * Math.pow(10, (digit || 0))) / Math.pow(10, (digit || 0));
  }
  function ceil() {
    return Math.ceil(this);
  }
  function floor() {
    return Math.floor(this);
  }
  function date(){
    return new Date(this);
  }
  function div(divisor){
    if(divisor != 0)
    return this / divisor;
    else
    return 0;
  }
  function none() {
	    return this;
	}
  return {
    left: left,
    right: right,
    abs: abs,
    round: round,
    ceil: ceil,
    floor: floor,
    money: toMoney,
    byte: toByte,
    num: toNum,
    number: toNum,
    pad: toPad,
    date: date,
    div:  div,
    dec: none,
	enc: none,
    rangeFrom: range
  }
})());

Object.extend(Date.prototype, (function(){
  function dateAdd(daynum, interval){
    interval = interval || "d";
    var interval = interval.toLowerCase();
    var DyMilli = ((1000 * 60) * 60) * 24;
    var aDate = new Date(this.getUTCFullYear(), this.getMonth(), this.getDate());
    if(interval == "d"){
      aDate.setTime(this.getTime() + (daynum*DyMilli));
    }else if(interval == "m"){
      var yy = aDate.getFullYear();
  	  var mm = aDate.getMonth();
  		var dd = aDate.getDate();
		  if(mm == 0 && dd == 1) yy += 1;
  		yy = yy + parseInt(daynum / 12);
  		mm += daynum % 12;
  		var mxdd = mods.monthLength(yy, mm);
  		if(mxdd < dd) dd = mxdd;  		
  		aDate = new Date(yy, mm, dd);
    }else if(interval == "y"){
      aDate.setTime(this.getTime() + ((daynum*365)*DyMilli));
    }else{

    }
    return aDate;
  }

  function dayDiff(edDate){
    var DyMilli = ((1000 * 60) * 60) * 24;
	  function dateObj(myDate){
	    if(typeof(myDate) == "string"){
	      var aDate = myDate.date();
		    return new Date( aDate.getUTCFullYear(), aDate.getMonth(), aDate.getDate() );
	    }else if(typeof(myDate) == "object"){
	      return myDate;
	    }else{
	      return new Date();
	    }
	  }
	  return Math.round((dateObj(edDate) - this) / DyMilli);
  }

  function toString(format){
    if(format == undefined){
      var sSeper = "-";
      if(this.getMonth() == 0 && this.getDate() == 1) return (this.getUTCFullYear()+1) +sSeper+(this.getMonth()+1).pad(2)+sSeper+this.getDate().pad(2);
  		else return this.getUTCFullYear() +sSeper+(this.getMonth()+1).pad(2)+sSeper+this.getDate().pad(2);
    }else if(format == "0"){
      var sSeper = "/";
      if(this.getMonth() == 0 && this.getDate() == 1) return (this.getUTCFullYear()+1) +sSeper+(this.getMonth()+1).pad(2)+sSeper+this.getDate().pad(2);
  		else return this.getUTCFullYear() +sSeper+(this.getMonth()+1).pad(2)+sSeper+this.getDate().pad(2);
    }else if(format == "1"){
      var sSeper = "-";
      if(this.getMonth() == 0 && this.getDate() == 1) return (this.getUTCFullYear()+1).right(2) +sSeper+(this.getMonth()+1).pad(2)+sSeper+this.getDate().pad(2);
  		else return this.getUTCFullYear().right(2) +sSeper+(this.getMonth()+1).pad(2)+sSeper+this.getDate().pad(2);
    }else if(format == "2"){
      var sSeper = "/";
      if(this.getMonth() == 0 && this.getDate() == 1) return (this.getUTCFullYear()+1).right(2) +sSeper+(this.getMonth()+1).pad(2)+sSeper+this.getDate().pad(2);
  		else return this.getUTCFullYear().right(2) +sSeper+(this.getMonth()+1).pad(2)+sSeper+this.getDate().pad(2);
    }else if(format == "3"){
      var sSeper = "-";
      return (this.getMonth()+1).pad(2)+sSeper+this.getDate().pad(2);
    }else if(format == "4"){
      var sSeper = "/";
      return (this.getMonth()+1).pad(2)+sSeper+this.getDate().pad(2);
    }else if(format == "5"){
      return this.getDate().pad(2);
    }else if(format == "6"){
      return this.getDate();
    }
  }
  
  function date(){
    return this; 
  }

  function toJSON(){
    return '"' + this.getUTCFullYear() + '-' +
      (this.getUTCMonth() + 1).pad(2) + '-' +
      this.getUTCDate().pad(2) + 'T' +
      this.getUTCHours().pad(2) + ':' +
      this.getUTCMinutes().pad(2) + ':' +
      this.getUTCSeconds().pad(2) + 'Z"';
  }
  return {
    add: dateAdd,
    gap: dayDiff,
    say: toString,
    date: date,
    toJSON: toJSON
  }
})());

Object.extend(Error.prototype, (function(){
  function print(){
    return "EN:"+(this.number&0xFFFF)+" : "+this+"\n"+this.description;
  }
  return {
    print: print
  }
})());

Object.extend(Array.prototype, (function(){
  function clear() {
    this.length = 0;
    return this;
  }
  function m_notall(context){
    context = context || function(x){return x;};
    var result = true;
    var i=0;
    while(i < this.length){
      result = !Boolean(context(this[i]));
      if(!result) break;
      i++;
    }
    return result;
  }
  function m_any(context){
    context = context || function(x){return x;};
    var result = false;
    var i=0;
    while(i < this.length){
      result = Boolean(context(this[i], i));
      if(result) break;
      i++;
    }
    return result;
  }
  function m_find(context){
    context = context || function(x){return false;};
    var myselect;
    var i=0;
    while(i < this.length){
      if(context(this[i], i)){
        myselect = this[i];
        break;
      }
      i++;
    }
    return myselect;
  }
  function m_find2(context){
    if(!Object.isFunction(context)){
      findObj = context;
      context = function(x){ return (x == findObj); }
    }
    var myselect, myindex;
    var i=0;
    while(i < this.length){
      if(context(this[i], i)){
        myselect = this[i];
        myindex  = i;
        break;
      }
      i++;
    }
    return {obj:myselect, index:myindex};
  }
  function m_findAll(context){
    context = context || function(x){return false;};
    var myselect = [];;
    var i=0;
    while(i < this.length){
      if(context(this[i], i)) myselect.push(this[i]);
      i++;
    }
    return myselect;
  }
  function first() {
    return this[0];
  }
  function last() {
    return this[this.length - 1];
  }
  function toJSON() {
    var results = [];
    jQuery.each(this, function(i, object) {
      var value = Object.toJSON(object);
      if (!Object.isUndefined(value)) results.push(value);
    });
    return '[' + results.join(', ') + ']';
  }
  function isMember(member){
  	var result = false;
    var i=0;
    while(i < this.length){
      result = this[i] == member;
      if(result) break;
      i++;
    }
    return result;
  }
  
  return {
    clear: clear,
    first: first,
    last: last,
    not: m_notall,
    or: m_any,
    get: m_find,
    gets: m_findAll,
    getObj: m_find2,
    toJSON: toJSON,
    have: isMember
  }
})());
/* Object prototype extend - modsAX Prototypes
   -------------------------------------------------------------------------------------------------------------------------------------------------  */

/* Miscellaneous methds - modsAX methds
   */
function $A(iterable){if(!iterable) return [];if('toArray' in Object(iterable))return iterable.toArray();var length=iterable.length || 0, results=new Array(length);while(length--)results[length]=iterable[length];return results;}
function $M(id){return document.getElementById(id);}
/* Miscellaneous methds - modsAX methds
   -------------------------------------------------------------------------------------------------------------------------------------------------  */

/* Miscellaneous methods group The mods
   */
var mods = {
  version: "modsAX 1.0",
  browser: (function(){
    var browserName = "";
    with(jQuery){
      if(browser.webkit) browserName = "wk";
      else if(browser.msie) browserName = "ie";
      else if(browser.mozilla) browserName = "moz";
      else if(browser.opera) browserName = "op";
      return {
        browser: browserName,
        version: parseFloat(browser.version)
      }
    }
  })(),
  supportDomRanges: (function(){
  	return document.implementation.hasFeature("Range", "2.0");
  })(),
  docTD: (function(){
    if(!document.compatMode || document.compatMode == 'BackCompat') return "Q";
    else return "S";
  })(),
  dummy: (function(){
   var d = new Date();
   return("U" + d.getUTCHours() + d.getUTCMinutes() + d.getUTCSeconds() + d.getUTCMilliseconds());
  })(),
  consonantKR: function(cword){
    var cons = [
      {c:"ㄱ", re:"[가-깋]"}, {c:"ㄲ", re:"[까-낗]"}, {c:"ㄴ", re:"[나-닣]"}, {c:"ㄷ", re:"[다-딯]"}, {c:"ㄸ", re:"[따-띻]"}, {c:"ㄹ", re:"[라-맇]"},
      {c:"ㅁ", re:"[마-밓]"}, {c:"ㅂ", re:"[바-빟]"}, {c:"ㅃ", re:"[빠-삫]"}, {c:"ㅅ", re:"[사-싷]"}, {c:"ㅆ", re:"[싸-앃]"}, {c:"ㅇ", re:"[아-잏]"}, {c:"ㅈ", re:"[자-짛]"},
      {c:"ㅉ", re:"[짜-찧]"}, {c:"ㅊ", re:"[차-칳]"}, {c:"ㅋ", re:"[카-킿]"}, {c:"ㅌ", re:"[타-팋]"}, {c:"ㅍ", re:"[파-핗]"}, {c:"ㅎ", re:"[하-힣]"}
    ];
    var rword = "";
    var cwords = cword.split("");
    jQuery.each(cwords, function(i, n){
      var fo = cons.get(function(m){
        return m.c == n;
      });
      if(fo) rword += fo.re;
      else rword += n;
    });
    return rword;
  },
  setCookie: function( name, value, expiredays ){
    if(expiredays){
      var todayDate = new Date();
      todayDate.setDate( todayDate.getDate() + expiredays );
      document.cookie = name + '=' + escape( value ) + '; path=/; expires=' + todayDate.toGMTString() + ';';
    }else{
      document.cookie = name + '=' + escape( value ) + '; path=/;';
    }
  },
  getCookie: function( name ){
    var nameOfCookie = name + "=";
    var x = 0;
    while ( x <= document.cookie.length )
    {
      var y = (x+nameOfCookie.length);
      if ( document.cookie.substring( x, y ) == nameOfCookie ) {
      if ( (endOfCookie=document.cookie.indexOf( ";", y )) == -1 )
      endOfCookie = document.cookie.length;
      return unescape( document.cookie.substring( y, endOfCookie ) );
      }
      x = document.cookie.indexOf( " ", x ) + 1;
      if ( x == 0 )
      break;
    }
    return "";
  },
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
  alert: function(){
    var po = [];
    var i = 0;
    while(i < arguments.length){
      po.push(i+"="+Object.toJSON(arguments[i]));
      i++; 
    } 
    alert(po.join(',\n'));
  },
  print: function(){
    var po = [];
    var i = 0;
    while(i < arguments.length){
      po.push(i+"="+Object.toJSON(arguments[i]));
      i++; 
    } 
    return po.join(',\n');
  },
  monthLength: function (y, m){
		//Day Length for Month
		if([3,5,8,10].or(function(n){return n == m;})){
			return 30;
		}else if(m == 1){
			if (((y % 4 == 0) && (y % 100 !=0)) || (y % 400 == 0)) {
				return 29;
			}else{
				return 28;
			}
		}else{
			return 31;
		}
	},
	ctype: function(val, ty, exts){
		if(ty == "float"){
			if(isNaN(val)) return 0;
			else if(val == "") return 0;
			else return parseFloat(val);
		}else if(ty == "money"){
			if(isNaN(val)) return 0;
			else if(val == "") return 0;
			else return val.number().money();
		}else if(ty == "int"){
			if(isNaN(val)) return 0;
			else if(val == "") return 0;
			else return parseInt(val);
		}else if(ty == "string"){
			if(val == undefined) return "";
			else return val.toString().dec().trim();
		}else if(ty == "date"){
			if(val == "") return "";
			else return val.toString();
		}else if(ty == "checkbox"){
			return "<input type=\"checkbox\" name=\""+exts+"\" value=\""+val+"\" />";
		}else if(ty == "radio"){
			return "<input type=\"radio\" name=\""+exts+"\" value=\""+val+"\" />";
		}else if( Object.isFunction(ty) ){
			return ty(val);
		}else{
		return val;
		}
	},
	rtype: function(val, ty){
		if(ty == "float"){
			return parseFloat(val);
		}else if(ty == "money"){
			if(isNaN(val)) return 0;
			else if(val == "") return 0;
			else return val.number();
		}else if(ty == "int"){
			if(isNaN(val)) return 0;
			else if(val == "") return 0;
			else return parseInt(val);
		}else if(ty == "string"){
			if(val == undefined) return "";
			else return val.toString().enc();
		}else if(ty == "date"){
			if(val == "") return "";
			else return val;
		}else if(ty == "checkbox"){
			return "<input type=\"checkbox\" name=\""+exts+"\" value=\""+val+"\" />";
		}else if(ty == "radio"){
			return "<input type=\"radio\" name=\""+exts+"\" value=\""+val+"\" />";
		}else if( Object.isFunction(ty) ){
			return ty(val);
		}else{
			return val;
		}
	},
	sortType: function(val, ty){
	  if(ty == "float"){
	    if(typeof val != "number") return val.toString().num();
	    else                       return val;
	  }else if(ty == "money"){
	    if(typeof val != "number") return val.toString().num();
	    else                       return val;
	  }else if(ty == "int"){
	    if(typeof val != "number") return val.toString().num();
	    else                       return val;
	  }else if(ty == "string"){
	    return val.toString().dec().trim();
	  }else if(ty == "date"){
	    return val.toString();
	  }else if( Object.isFunction(ty) ){
	    return ty(val);
	  }else{
	    return val;
	  }
	},
  Event: {
    KEY_BACKSPACE: 8,
    KEY_TAB:       9,
    KEY_RETURN:   13,
    KEY_ESC:      27,
    KEY_LEFT:     37,
    KEY_UP:       38,
    KEY_RIGHT:    39,
    KEY_DOWN:     40,
    KEY_DELETE:   46,
    KEY_HOME:     36,
    KEY_END:      35,
    KEY_PAGEUP:   33,
    KEY_PAGEDOWN: 34,
    KEY_INSERT:   45,
    cache: {}
  }
};

/* Miscellaneous methods group The mods
   -------------------------------------------------------------------------------------------------------------------------------------------------  */

/* Antetype of modsAX
   */
var modsAX = Class.create({
  version       : "modsAX V1.0",
  author        : "SQUALL",
  createDate    : "2009.12.28",
  lastModifyDate: "2010.04.06",
  initialize: function(){
    // any position initialize able.
    this.selects = "";
    this.config = {
      /*
      * id : user identify, nm : name, fm : format, at : attribute, cn : childNodes, _id : process identify [hidden value]
      * _cn : have child node[hidden value], _op : open child
      */
      columns       : ["id", "nm", "fm", "at", "cn", "_id", "_cn", "_op"],
      rootElementID : null,
      dataType      : "script", // [script|load]
      spliter       : (function(){return "-"})()
    };
    this.loader = {
      load:"", add:"", save:"", del:"", pars:"", activePars:["id","nm"]
    };
    this.mouse = {x:0, y:0};
  },
  init: function(){
    alert(Object.toJSON(this.config));
  },
  outMsg: function(sStr){
    alert(this.version+" Message : \n" + sStr);
  },
  /* _get */
  _getUrl: function(typ){
    return this.loader[typ];
  },
  _getPars: function(obj){
    var p = "";
    if(this.loader.pars) p += this.loader.pars;
    if(this.page){
      if(p == "") p += jQuery.param(this.page);
      else        p += "&"+jQuery.param(this.page);
    }
    if(obj){
      jQuery.each(this.loader.activePars, function(i, n){
        if(obj[n]){
          var parstr = "";
          if(typeof(obj[n]) == "String") parstr = obj[n].enc();
          else parstr = obj[n];
          if(p == "") p += n + "=" + parstr;
          else        p += "&" + n + "=" + parstr;
        }
      });
    }
    return (p == "") ? "dum="+mods.dummy : p + "&dum="+mods.dummy;
  },
  _getPaObj: function(liID){
    var p = this.config.spliter;
    var IDs = liID.split("_");
    var nums = IDs[1].split(p);
    var Obj = this.trees;
    for(var a=0;a < nums.length-1;a++){
      try{
      Obj = Obj[nums[a]].cn;
      }catch(e){}
    }
    return Obj;
  },
  _getObj: function(liID){
    var p = this.config.spliter;
    var IDs = liID.split("_");
    var nums = IDs[1].split(p);
    var Obj = this.trees;
    for(var a=0;a < nums.length;a++){
      if(a == 0) Obj = Obj[nums[a]];
      else Obj = Obj.cn[nums[a]];
    }
    return Obj;
  },
  /* _set */
  setConfig: function(configs){
    var _self = this;
    jQuery.each(Object.keys(configs), function(i, n){ // update to {this.config}
      _self.config[n] = configs[n];
    });
    this.init();
  },
  _setConfigLoad: function(configs){
    var _self = this;
    jQuery.each(Object.keys(configs), function(i, n){ // update to {this.config}
      _self.loader[n] = configs[n];
    });
  },
  uniqTree: function(o, z){
    var p = this.config.spliter;
    var l = o.length;
    var s = 0;
    while(s < l){
      if(z == undefined) o[s]._id = s;
      else o[s]._id = z+p+s;
      if(o[s].cn){
        o[s]._cn = 1;
        o[s].cn = this.uniqTree(o[s].cn, o[s]._id);
      }
      s++;
    }
    return o;
  },
  _GID: function(ids){
  	var myid = [];
  	for(var a=0;a<ids.length;a++){
  		myid.push(ids[a]);
  	}
  	return myid.join("_");
  },
  _GPT: function(myid, idx){
  	var ids = myid.split(/_/g);
  	if(idx == undefined){
  		return ids.last();
  	}else{
  		return ids[idx];
  	}	
  }
});
/* Antetype of modsAX
   -------------------------------------------------------------------------------------------------------------------------------------------------  */

/* modsreq
   */
var modsreqQue = Class.create({
	version: "modsreqQue v1.0",
	initialize: function(){
		this.que = [];
		this.config = {
			pars : "",
			type: "post",
			onsucc: "",
			responseType: "object"
		};
		this.busy = false;
	},
	add: function(obj){
		this.que.push(obj);
		this.start();
	},
	start: function(){
		if(this.que.length == 0) return;
		if(this.busy) return;
		this.busy = true;
		var myQue = this.que.first();
		
		var _self = this;
		_self.config = {
			pars : "",
			type: "post",
			onsucc: "",
			responseType: "object"
		};
		jQuery.each(myQue.configs, function(k, v){ // update to {this.config}
			_self.config[k] = v;
		});

		var onerr = this.onerror.bind(this);
		var ontimeout = this.ontimeout.bind(this);
		var onsucc = this.onsucc.bind(this);
	
		if(typeof this.config.pars == "object"){
			this.config.pars.dummy = mods.dummy;
		}else if(typeof this.config.pars == "string"){
			if(this.config.pars == "") this.config.pars += "dummy="+mods.dummy;
			else this.config.pars += "&dummy="+mods.dummy;
		}

		jQuery.ajax({
			url: myQue.url,
			data: this.config.pars,
			type: this.config.type,
			success: onsucc,
			error: onerr,
			timeout: ontimeout
		});

	},
	onsucc: function(req){
		if(req != ""){
			if(this.config.debug) alert(req);
			if(this.config.responseType == "object"){
				var res = req.object();
			}else{
				var res = req;
			}
			if(this.config.onsucc) this.config.onsucc(res);
			this.que.shift();
			this.busy = false;
			this.start();
		}
	},
	onerror: function(req){
		alert("onFail:"+req.responseText);
			this.que.shift();
			this.busy = false;
		try{
			mask.close();
		}catch(e){}
	},
	ontimeout: function(req){
		alert("onTimeout:"+req.responseText);
			this.que.shift();
			this.busy = false;
		try{
			mask.close();
		}catch(e){}
	}
});
var MYmodsreqQue = new modsreqQue();
var modsreq = Class.create({
	version: "modsreq v2.0",
	initialize: function(url, configs){
		MYmodsreqQue.add({url:url, configs:configs});
		/*
		return;
		this.url = url;
		this.config = {
			pars : "",
			type: "post",
			onsucc: "",
			responseType: "object"
		};
		
		var _self = this;
		jQuery.each(Object.keys(configs), function(i, n){ // update to {this.config}
			_self.config[n] = configs[n];
		});
	
		var onerr = this.onerror.bind(this);
		var ontimeout = this.ontimeout.bind(this);
		var onsucc = this.onsucc.bind(this);
	
		if(typeof this.config.pars == "object"){
			this.config.pars.dummy = mods.dummy;
		}else if(typeof this.config.pars == "string"){
			if(this.config.pars == "") this.config.pars += "dummy="+mods.dummy;
			else this.config.pars += "&dummy="+mods.dummy;
		}
	
		jQuery.ajax({
			url: this.url,
			data: this.config.pars,
			type: this.config.type,
			success: onsucc,
			error: onerr,
			timeout: ontimeout
		});
		*/
	}
	/*
	,
	onsucc: function(req){
		if(req != ""){
			if(this.config.debug) alert(req);
			if(this.config.responseType == "object"){
				var res = req.object();
			}else{
				var res = req;
			}
			if(this.config.onsucc) this.config.onsucc(res);
		}
	},
	onerror: function(req){
		alert("onFail:"+req.responseText);
		try{
			mask.close();
		}catch(e){}
	},
	ontimeout: function(req){
		alert("onTimeout:"+req.responseText);
		try{
			mask.close();
		}catch(e){}
	}
	*/
});

/* modsreq
   -------------------------------------------------------------------------------------------------------------------------------------------------  */

/* modsQmenu
   */
var modsQmenu = Class.create(modsAX, {
  version       : "modsQmenu v1.0",
  author        : "SQUALL",
  createDate    : "2009.12.16",
  lastModifyDate: "2009.12.20",
  initialize: function($super){
    $super();
    this.coverA = "href=\"#modsExceptionScript\"";
  },
  init: function(){
    this.trees = this.uniqTree(this.config.menuSet); // convert tree
    this.containerInit();
  },
  containerInit: function(){
    this.container = jQuery("<div class='"+this.config.className+"' id='"+this.config.menuID+"'></div>");
    this.insertTree(this.container, this.trees);

    var onmouseover = this.onmouseover.bind(this);
    this.container.bind("mouseover", function(event){
      onmouseover(this, event);
    });

    var rootOnclick = this.rootOnclick.bind(this);
    this.container.bind("click", function(event){
      rootOnclick(this, event);
    });
  },
  /* ------------------------------------------------------------------------------------------------------------------ */
  /* class method ~~~~~~ */
  insertTree: function(_parent, _obj){
    var coverA = this.coverA;
    var etags = [];
    etags.push("<ul>");
    var l = _obj.length;
    var s = 0;
    while(s < l){
      if(_obj[s].nm != null){
        var objID = this.config.menuID+"_"+_obj[s]._id;
        var objClass = "menu";
        etags.push("<li>");
        etags.push("<div class=\""+objClass+"\" id=\""+objID+"\">");
        etags.push("<a "+coverA+" class=\"t "+_obj[s].fm+"\" id=\""+objID+"_t\">"+_obj[s].nm.dec()+"</a>");
        if(_obj[s]._cn){
        etags.push("<a "+coverA+" class=\"i\" id=\""+objID+"_i\">+</a>");
          if(_obj[s]._op) this.removeSubMenu(_obj[s]);
        }
        etags.push("</div>");
        etags.push("</li>");
      }else{
        var objClass = "hline";
        if(_obj[s].className) objClass = _obj[s].className;
        etags.push("<li class=\""+objClass+"\">");
        etags.push("<div class=\"line\"></div>");
        etags.push("</li>");
      }
      s++;
    }
    etags.push("</ul>");
    //Element.insert(_parent, etags.join(''));
    jQuery(_parent).append(etags.join(''));
  },
  show: function(req){
    var targetElement = req.target;
    var pointer = {x:req.pointer.x||0, y:req.pointer.y||0};
    this.message = req.message;

    //주 메뉴 박스 삽입
    this.container.appendTo(jQuery("#"+targetElement));

    var offSetParent = this.container.offsetParent();
    var dimParent = {width:offSetParent[0].scrollWidth, height:offSetParent[0].scrollHeight}; //offSetParent.getDimensions(); //

    if(offSetParent.innerHeight() > dimParent.height) dimParent.height = offSetParent.innerHeight();

    var containerLeft = pointer.x;
    var containerTop  = pointer.y;

    if(!req.norepos){
	    if(offSetParent[0].tagName != "BODY" && offSetParent[0].tagName != "HTML"){
	      var opOffset = offSetParent.position();
	      
	      var marginTop = offSetParent.css("margin-top").number() || 0;
	      containerLeft = pointer.x - opOffset.left + offSetParent.scrollLeft();
	      containerTop  = pointer.y - opOffset.top + offSetParent.scrollTop() - marginTop;
	    }else{
	      //containerLeft = pointer.x-offSetParent.scrollLeft;
	      //containerTop  = pointer.y-offSetParent.scrollTop;
	    }
	
	    var dimContainer = {width:this.container.width(), height:this.container.height()};// this.container.getDimensions();
	    var containerRight = containerLeft + dimContainer.width;
	    var containerBottom = containerTop + dimContainer.height;
	
	    if(dimParent.width < containerRight) containerLeft -= (containerRight - dimParent.width) + 10;
	    if(dimParent.height < containerBottom) containerTop -= (containerBottom - dimParent.height) + 10;
	}
    try{
      this.container.css({left:containerLeft+"px", top:containerTop+"px"});
    }catch(e){
      alert(e.print());
    }

    this.container.hide();
    this.container.slideDown({duration:500, easing:"elasticOut", complete:function(){
      }});

    //자식개체 정리
    var removeSubMenu = this.removeSubMenu.bind(this);
    jQuery.each(this.trees, function(i, n){
      removeSubMenu(n);
    });

    // observe init
    if(this.clickToHideMenu) jQuery(document).unbind('click', this.clickToHideMenu);
    if(this.keyDownToHideMenu) jQuery(document).unbind('keydown', this.keyDownToHideMenu);

    this.clickToHideMenu = this.hide.bind(this);
    jQuery(document).bind("click", this.clickToHideMenu);
    this.keyDownToHideMenu = this.KeydownHide.bind(this);
    jQuery(document).bind("keydown", this.keyDownToHideMenu);
  },
  subTreeAlign: function(objBox, paObj){
    var paObjBox = paObj.parents("div"); //호출개체의 DIV
    var containerOffset = this.container.position(); //메뉴 시작개체 포지션
    var containerDimensions = {width:this.container.width(), height:this.container.height()}; //메뉴 시작개체 크기
    var objBoxDimensions = {width:objBox.width(), height:objBox.height()}; // 현재 개체 크기
    var paObjBoxOffset = paObjBox.position(); // 호출 개체DIV 포지션
    var paObjBoxDimensions = {width:paObjBox.width(), height:paObjBox.height()}; // 호출 개체DIV 크기
    var paObjOffset = paObj.position(); // 호출개체 포지션
    var offSetParent = this.container.offsetParent();

    var parentDimensions = {width:offSetParent[0].scrollWidth, height:offSetParent[0].scrollHeight};
    if(offSetParent.innerHeight() > parentDimensions.height) parentDimensions.height = offSetParent.innerHeight();

    if(paObjBox[0] == this.container[0]){ // 호출개체가 메뉴 시작개체 라면 첫번째 자식의경우 시작개체와의 관계만 계산.
       var myLeft = containerDimensions.width - 5;
       var myTop  = paObjOffset.top - 5;
       var tWidth = containerOffset.left + myLeft + objBoxDimensions.width;
       var tHeight = containerOffset.top + myTop + objBoxDimensions.height;
       if(tWidth > parentDimensions.width) myLeft = -myLeft;
       if(tHeight > parentDimensions.height) myTop -= tHeight - parentDimensions.height + 10;
    }else{
       var myLeft = paObjBoxOffset.left + paObjBoxDimensions.width - 5;
       var myTop  = paObjBoxOffset.top + paObjOffset.top - 5;
       var tWidth = containerOffset.left + myLeft + objBoxDimensions.width;
       var tHeight = containerOffset.top + myTop + objBoxDimensions.height;
       if(tWidth > parentDimensions.width) myLeft -= objBoxDimensions.width + paObjBoxDimensions.width - 10;
       if(tHeight > parentDimensions.height) myTop -= tHeight - parentDimensions.height + 10;
    }

    objBox.css({left:myLeft+"px", top:myTop+"px"});
    objBox.slideDown({duration:500, easing:"elasticOut", complete:function(){
      }});
  },
  hide: function(event){
    if(event)
      if(event.button != 0) return;

      //end event observe
      var remove = this.containerRemove.bind(this);
      this.container.slideUp(200, remove);
      
      if(this.clickToHideMenu) jQuery(document).unbind('click', this.clickToHideMenu);
      if(this.keyDownToHideMenu) jQuery(document).unbind('keydown', this.keyDownToHideMenu);
  },
  containerRemove: function(){
    this.container.remove();
    this.containerInit();
  },
  KeydownHide: function(event){
    if(event.keyCode == mods.Event.KEY_ESC) this.hide();
  },
  onmouseover: function(element, event){
    if(!(event.target.tagName == "A")) return;
    var _reID = this.config.menuID;
    var eA = event.target;
    if(!eA) return;
    if(!eA.id) return;
    var clickIDs = eA.id.split("_"); // 0 : menuID, 1:_id, 2:클릭위치
    var clickLiID = clickIDs[0]+"_"+clickIDs[1];
    if(clickIDs[2] == "i"){ // 무시

    }else if(clickIDs[2] == "t"){ //오픈 시도
      var p = this.config.spliter;
      var nums = clickIDs[1].split(p);
      var myIndex = nums.last();
      var Obj = this.trees;
      for(var a=0;a < nums.length-1;a++) Obj = Obj[nums[a]].cn;

      var insertTree = this.insertTree.bind(this);
      var subTreeAlign = this.subTreeAlign.bind(this);
      var removeSubMenu = this.removeSubMenu.bind(this);

      jQuery.each(Obj, function(index, n){
        if(index == myIndex){
          if(n._cn){
            var objID = _reID+"_"+n._id+"_s";
            n._op = true;
            if($M(objID)) $("#"+objID).remove();
            var myDiv = $("<div id='"+objID+"' class='modsQmenu_sub' style='display:none;'></div>");
            $("#"+_reID).append(myDiv);
            insertTree($("#"+objID), n.cn);
            subTreeAlign($("#"+objID), $("#"+_reID+"_"+n._id));
          }
        }else{
          if(n._op) removeSubMenu(n);
        }
      });
    }
  },
  removeSubMenu: function(Obj){
    var removeSubMenu = this.removeSubMenu.bind(this);
    Obj._op = false;
    var objID = this.config.menuID+"_"+Obj._id+"_s";
    if($M(objID)) $("#"+objID).remove();
    if(Obj.cn)
      jQuery.each(Obj.cn, function(i, n){
        if(n._op) removeSubMenu(n);
      });
  },
  rootOnclick: function(element, event){
    if(!(event.target.tagName == "A")) return;
    var eA = event.target;
    if(!eA) return;
    if(!eA.id) return;
    var clickIDs = eA.id.split("_"); // 0 : menuID, 1:_id, 2:클릭위치
    var clickLiID = clickIDs[0]+"_"+clickIDs[1];
    var Obj = this._getObj(clickLiID);
    if(this.config.onclick) this.config.onclick({clickMenu:Obj, message:this.message});
  },
  rootOnKeydown: function(event){

  }
});
/* modsQmenu
   -------------------------------------------------------------------------------------------------------------------------------------------------  */
   
/* modsMselect
   */
var modsMselect = Class.create(modsAX, {
  version       : "modsMselect v1.0",
  author        : "SQUALL",
  createDate    : "2010.01.04",
  lastModifyDate: "2010.01.04",
  initialize: function($super){
    $super();
    this.selects = [];
    this.config.selectClassName   = "readySelect";
    this.config.beselectClassName = "beSelected";
  },
  init: function(){
    var mouseClick = this.onmouseClick.bind(this);
    jQuery("#"+this.config.selectStage).bind("mousedown", function(event){
      mouseClick(this, event);
    });
    this.collect();
  },
  /* ------------------------------------------------------------------------------------------------------------------ */
  /* observe method ~~~~~~ */
  onmouseClick: function(element, event){
    if(!jQuery(event.target).hasClass(this.config.selectClassName)){
      this.clearSelects();
      return;
    }

    var selectElement = event.target;
    if(selectElement){
      if(event.shiftKey){
        this.shiftSelects(selectElement);
      }else if(event.ctrlKey){
        this.toggleSelects(selectElement);
      }else{
        this.clickSelects(selectElement);
      }
    }
  },
  /* ------------------------------------------------------------------------------------------------------------------ */
  /* class method ~~~~~~ */
  collect: function(){
    // collect selected element
    this.selectTargets = $("#"+this.config.selectStage+" ."+this.config.selectClassName).get();
  },
  clearSelects: function(){
    var beselectClassName = this.config.beselectClassName;
    jQuery.each(this.selects, function(i, n){
      jQuery(n).removeClass(beselectClassName);
    });
    this.selects.clear();
  },
  pushSelects: function(Obj){
    var hasSelect = this.selects.or(function(n){
      return n == Obj;
    });
    if(!hasSelect) this.selects.push(Obj);
  },
  clickSelects: function(Obj){
    var hasSelect = this.selects.or(function(n){
      return n == Obj;
    });
    if(!hasSelect) this.clearSelects();
    var beselectClassName = this.config.beselectClassName;
    jQuery(Obj).addClass(beselectClassName);
    this.pushSelects(Obj);
  },
  toggleSelects: function(Obj){
    var beselectClassName = this.config.beselectClassName;
    var hasSelect = this.selects.or(function(n){
      return n == Obj;
    });
    if(hasSelect){
      jQuery(Obj).removeClass(beselectClassName);
      var collects = [];
      collects = jQuery.grep(this.selects, function(n, i){
        return (Obj != n);
      });      
      this.selects = collects;
    }else{
      jQuery(Obj).addClass(beselectClassName);
      this.pushSelects(Obj);
    }
  },
  shiftSelects: function(Obj){
    var beselectClassName = this.config.beselectClassName;
    var selectTargets = this.selectTargets;
    var addSelect = function(Obj){
      this.selects.push(Obj);
    };
    var addSelectBind = addSelect.bind(this);

    if(this.selects.length == 0){
      this.clickSelects(Obj);
    }else{
    //마지막 selects 개체를 찾는다.
      var lastElement = this.selects.last();      
      var li = this.selectTargets.getObj($(lastElement)[0]).index;
      var si = this.selectTargets.getObj($(Obj)[0]).index;
      if(si == li) return;

      this.clearSelects();
      var objParent = $(Obj).parent()[0];
      
      
      if(si > li){
        jQuery.each(si.rangeFrom(li), function(i, n){
          if(objParent == $(selectTargets[n]).parent()[0]){
            $(selectTargets[n]).addClass(beselectClassName);
            addSelectBind(selectTargets[n]);
          }
        });
      }else{
        jQuery.each(li.rangeFrom(si), function(i, n){
          if(objParent == $(selectTargets[n]).parent()[0]){
            $(selectTargets[n]).addClass(beselectClassName);
            addSelectBind(selectTargets[n]);
          }
        });
      }
    }
  },
  getSelects: function(){
    return this.selects;
  },
  size: function(){
    return this.selects.length;
  }
});
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* modsMselect
   -------------------------------------------------------------------------------------------------------------------------------------------------  */
   
/* modsMask
   */
var modsMask = Class.create(modsAX, {
  version       : "modsMask v1.0",
  author        : "SQUALL",
  createDate    : "2010.05.09",
  lastModifyDate: "2010.05.09",
  initialize: function($super){
    $super();
    this.selects = [];
    this.config.maskCss = "modsMask";
    this.config.progressCss = "modsMaskProgress";
    this.config.percentCss = "modsMaskPercent";
    this.config.content = "disable content"
  },
  init: function(){
    this.mask = jQuery("<div class=\""+this.config.maskCss+"\"></div>"
    +"<div class=\""+this.config.progressCss+"\"><div class=\"bar\">&nbsp;</div><span>"+this.config.content+"<a class=\""+this.config.percentCss+"\"></a></span></div>");
  },
  setSimple: function(){
  	this.mask = $("<div class=\""+this.config.maskCss+"\"></div>");
  },
  open: function(val){
    jQuery(document.body).append(this.mask);
    if(val != undefined){
      val = parseInt(val);
      jQuery("."+this.config.progressCss+" .bar").css({"width":val+"%"});
      jQuery("."+this.config.percentCss).text(val+"%");
    }else{
      jQuery("."+this.config.progressCss+" .bar").css({"width":"100%"});
      jQuery("."+this.config.percentCss).empty();
    }
  },
  progress: function(val){
    val = parseInt(val);
    jQuery("."+this.config.progressCss+" .bar").animate({"width":val+"%"}, {easing:"swing", duration:200});
    jQuery("."+this.config.percentCss).text(val+"%");
  },
    close: function(delay) {
        if (!delay) {
            this.mask.detach();
        } else {
            var maskHide = this.hide.bind(this);
            setTimeout(maskHide, delay);
        }
    },
    hide: function(){
        this.mask.detach();
    }
});
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* modsMask
   -------------------------------------------------------------------------------------------------------------------------------------------------  */
