/* modsAX Javascript Library, Version 1.0
 * modsAX.com 2009-2010 squall
 * update : modsAX.js 2010-04-15 V1.0
 * 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, leftScroll) {
    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 (!pos) return;
    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() }

    //alert((ePos.top + "." + this.outerHeight() + "." + m.top))

    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));
    } else {
        if (pElement[0].tagName == "BODY")
            window.scroll(0, pES.top + (ePos.top - m.top));
    }
    if(leftScroll){
	    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));
	    }
	}
    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\n"+this};
    } catch (e) {
      return {result:"err", msg:"JSON syntax error.\n"+this, 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 (this.number&0xFFFF)+" : "+this;
  }
  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",
  okCode: "ok",
  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;
    },
    _getPObj: function(liID) {
        var p = this.config.spliter;
        var IDs = liID.split("_");
        var nums = IDs[1].split(p);
        var Obj = this.trees;
        var rObj;
        for (var a = 0; a < nums.length - 1; a++) {
            try {
                rObj = Obj[nums[a]];
                Obj = Obj[nums[a]].cn;
            } catch (e) { }
        }
        return rObj;
    },
    _getObj: function(liID) {
        var p = this.config.spliter;
        var IDs = liID.split("_");
        var nums = IDs[1].split(p);
        var Obj = this.trees;
        try{
	        for (var a = 0; a < nums.length; a++) {
	            if (a == 0) Obj = Obj[nums[a]];
	            else Obj = Obj.cn[nums[a]];
	        }
    	}catch(e){}
        return Obj;
    },
    /* _set */
    setConfig: function(configs) {
        var _self = this;
        jQuery.each(configs, function(key, val) { // update to {this.config}
            _self.config[key] = val;
        });
        this.init();
    },
    _setConfigLoad: function(configs) {
        var _self = this;
        jQuery.each(configs, function(key, val) { // update to {this.config}
            _self.loader[key] = val;
        });
    },
    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 modsreq = Class.create({
  version: "modsreq v1.0",
  initialize: function(url, configs){
    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.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:300, easing:"backOut", 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:300, easing:"backOut", 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.5",
	author        : "SQUALL",
	createDate    : "2010.01.04",
	lastModifyDate: "2011.07.22",
	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){
		var myTarget = event.target;
		if(myTarget){
			while(!$(myTarget).hasClass(this.config.selectClassName) && myTarget.parentNode){
				myTarget = myTarget.parentNode;
			}
		}
		if(!jQuery(myTarget).hasClass(this.config.selectClassName)){
			this.clearSelects();
			return;
		}
		var selectElement = myTarget;
		if(selectElement){
		  if(event.shiftKey){
		    this.shiftSelects(selectElement);
		  }else if(event.ctrlKey){
		    this.toggleSelects(selectElement);
		  }else{
		    this.clickSelects(selectElement);
		  }
		}
	},
	/* ------------------------------------------------------------------------------------------------------------------ */
	/* class method ~~~~~~ */
	collect: function(){
		//alert("collect");
		// 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
   -------------------------------------------------------------------------------------------------------------------------------------------------  */
