/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > Core > Prototype
 *
 * base : prototype.js v1.5.1.1
 */

var Prototype = {
	Version: '1.5.1.1',

	Browser: {
		IE: !!(window.attachEvent && !window.opera),
		Opera: !!window.opera,
		WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
		Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
	},

	BrowserFeatures: {
		XPath: !!document.evaluate,
		ElementExtensions: !!window.HTMLElement,
		SpecificElementExtensions:
			(document.createElement('div').__proto__ !== document.createElement('form').__proto__)
	},

	ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
	JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,

	emptyFunction: function() {},
	K: function(x) { return x }
};

function $T(element) {
	return typeof element;
};

var Class = {
	create: function() {
		return function() { this.initialize.apply(this, arguments); }
	}
};

Object.extend = function(destination, source) {
	for (var property in source) {
		destination[property] = source[property];
	}
	
	return destination;
};

Object.extend(Object, {
	toJSON: function(object) {
		var type = $T(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 (object.ownerDocument === document) return;
		var results = [];
		for (var property in object) {
			var value = Object.toJSON(object[property]);
			if (value !== undefined)
				results.push(property.toJSON() + ': ' + value);
		}
		return '{' + results.join(', ') + '}';
	},
	
	clone: function(object) {
		return Object.extend({}, object);
	}
});

Function.prototype.bind = function() {
	var __method = this, args = $A(arguments), object = args.shift();
	return function() {
		return __method.apply(object, args.concat($A(arguments)));
	}
};

Function.prototype.bindAsEventListener = function(object) {
	var __method = this, args = $A(arguments), object = args.shift();
	return function(event) {
		return __method.apply(object, [event || window.event].concat(args));
	}
};

Object.extend(Number.prototype, {
	toJSON: function() {
		return isFinite(this) ? this.toString() : 'null';
	}
});

Date.prototype.toJSON = function() {
	return '"' + this.getFullYear() + '-' +
		(this.getMonth() + 1).toPaddedString(2) + '-' +
		this.getDate().toPaddedString(2) + 'T' +
		this.getHours().toPaddedString(2) + ':' +
		this.getMinutes().toPaddedString(2) + ':' +
		this.getSeconds().toPaddedString(2) + '"';
};

//--------------------------------------------------------------------------
// PeriodicalExecuter
//--------------------------------------------------------------------------

var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
	initialize: function(callback, frequency) {
		this.callback = callback;
		this.frequency = frequency;
		this.currentlyExecuting = false;

		this.registerCallback();
	},

	registerCallback: function() {
		this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
	},

	stop: function() {
		if (!this.timer) return;
		clearInterval(this.timer);
		this.timer = null;
	},
	
	onTimerEvent: function() {
		if (!this.currentlyExecuting) {
			try {
				this.currentlyExecuting = true;
				this.callback(this);
			} finally {
				this.currentlyExecuting = false;
			}
		}
	}
};

//--------------------------------------------------------------------------
// String
//--------------------------------------------------------------------------

Object.extend(String, {
	interpret: function(value) {
		return value == null ? '' : String(value);
	},
	
	specialChar: {
		'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\\': '\\\\' 
	}
});

Object.extend(String.prototype, {
	gsub: function(pattern, replacement) {
		var result = '', source = this, match;
		replacement = arguments.callee.prepareReplacement(replacement);

		while (source.length > 0) {
			if ((match = source.match(pattern))) {
				result += source.slice(0, match.index);
				result += String.interpret(replacement(match));
				source  = source.slice(match.index + match[0].length);
			} else {
				result += source;
				source = '';
			}
		}
	
		return result;
	},

	scan: function(pattern, iterator) {
		this.gsub(pattern, iterator);
		return this;
	},

	strip: function() {
		return this.replace(/^\s+/, '').replace(/\s+$/, '');
	},

	stripScripts: function() {
		return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
	},

	extractScripts: function() {
		var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
		var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
		return (this.match(matchAll) || []).map(function(scriptTag) {
			return (scriptTag.match(matchOne) || ['', ''])[1];
		});
	},

	evalScripts: function() {
		return this.extractScripts().map(function(script) { return eval(script) });
	},
  
	toQueryParams: function(separator) {
		var match = this.strip().match(/([^?#]*)(#.*)?$/);
		if (!match) return {};

		return match[1].split(separator || '&').inject({}, function(hash, pair) {
			if ((pair = pair.split('='))[0]) {
				var key = decodeURIComponent(pair.shift());
				var value = pair.length > 1 ? pair.join('=') : pair[0];
				if (value != undefined) value = decodeURIComponent(value);
	
				if (key in hash) {
					if (hash[key].constructor != Array) hash[key] = [hash[key]];
					hash[key].push(value);
				}
				else hash[key] = value;
			}
			
			return hash;
		});
	},

	toArray: function() {
		return this.split('');
	},

	camelize: function() {
		var parts = this.split('-'), len = parts.length;
		if (len == 1) return parts[0];

		var camelized = this.charAt(0) == '-'
			? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) : parts[0];

		for (var i = 1; i < len; i++)
			camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

		return camelized;
	},

	inspect: function(useDoubleQuotes) {
		var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
			var character = String.specialChar[match[0]];
			return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
		});
		
		if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
		return "'" + escapedString.replace(/'/g, '\\\'') + "'";
	},

	toJSON: function() {
		return this.inspect(true);
	},

	unfilterJSON: function(filter) {
		return this.gsub(filter || Prototype.JSONFilter, '#{1}');
	},

	isJSON: function() {
		var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
		return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
	},

	evalJSON: function(sanitize) {
		var json = this.unfilterJSON();

		try {
			if (!sanitize || json.isJSON()) return eval('(' + json + ')');
		} catch (e) { }
		throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
	},

	include: function(pattern) {
		return this.indexOf(pattern) > -1;
	},

	empty: function() {
		return this == '';
	},
	
	bytes: function() {
	    var l = 0;
		
		var len = this.length;
    	for(var i=0;i<len;i++)
        	l += this.charCodeAt(i)>128 ? 2:1;
			
		return l;
	}
});

String.prototype.gsub.prepareReplacement = function(replacement) {
	if ($T(replacement) == 'function') return replacement;
	var template = new Template(replacement);
	return function(match) { return template.evaluate(match) };
};

var Template = Class.create();
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
	
Template.prototype = {
	initialize: function(template, pattern) {
		this.template = template.toString();
		this.pattern  = pattern || Template.Pattern;
	},

	evaluate: function(object) {
		return this.template.gsub(this.pattern, function(match) {
			var before = match[1];
			if (before == '\\') return match[2];
			return before + String.interpret(object[match[3]]);
		});
	}
};

//--------------------------------------------------------------------------
// Enumerable
//--------------------------------------------------------------------------

var $break = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead');

var Enumerable = {
	each: function(iterator) {
		var index = 0;
		try {
			this._each(function(value) {
				iterator(value, index++);
			});
		} catch (e) {
			if (e != $break) throw e;
		}
		
		return this;
	},

	map: function(iterator) {
		var results = [];
		this.each(function(value, index) {
			results.push((iterator || Prototype.K)(value, index));
		});
		return results;
	},

	findAll: function(iterator) {
		var results = [];
		this.each(function(value, index) {
			if (iterator(value, index)) results.push(value);
		});
		return results;
	},

	include: function(object) {
		var found = false;
		this.each(function(value) {
			if (value == object) {
				found = true;
				throw $break;
			}
		});
		
		return found;
	},

	inject: function(memo, iterator) {
		this.each(function(value, index) {
			memo = iterator(memo, value, index);
		});
		return memo;
	},

	invoke: function(method) {
		var args = $A(arguments).slice(1);
		return this.map(function(value) {
			return value[method].apply(value, args);
		});
	},
	
	max: function(iterator) {
    	var result;
		this.each(function(value, index) {
			value = (iterator || Prototype.K)(value, index);
			if (result == undefined || value >= result)
				result = value;
		});
		return result;
	},
  
	pluck: function(property) {
		var results = [];
		this.each(function(value, index) {
			results.push(value[property]);
		});
		return results;
	},

	reject: function(iterator) {
		var results = [];
		this.each(function(value, index) {
		if (!iterator(value, index))
			results.push(value);
		});
		return results;
	},
  
	toArray: function() {
		return this.map();
	},

	size: function() {
		return this.toArray().length;
	}
};

Object.extend(Enumerable, {
	select:  Enumerable.findAll
});

//--------------------------------------------------------------------------
// Array
//--------------------------------------------------------------------------

Array.from = function(iterable) {
	if (!iterable) return [];
	if (iterable.toArray) {
		return iterable.toArray();
	} else {
		var results = [];
		for (var i = 0, length = iterable.length; i < length; i++)
			results.push(iterable[i]);
		return results;
	}
};

var $A = Array.from;

if (Prototype.Browser.WebKit) {
	$A = Array.from = function(iterable) {
		if (!iterable) return [];
		if (!($T(iterable) == 'function' && iterable == '[object NodeList]') &&
			iterable.toArray) {
			return iterable.toArray();
		} else {
			var results = [];
			for (var i = 0, length = iterable.length; i < length; i++)
				results.push(iterable[i]);
			return results;
		}
	}
};

Object.extend(Array.prototype, Enumerable);

if (!Array.prototype._reverse)
	Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {
	_each: function(iterator) {
		for (var i = 0, length = this.length; i < length; i++)
			iterator(this[i]);
	},

	clear: function() {
		this.length = 0;
		return this;
	},

	first: function() {
		return this[0];
	},

	last: function() {
		return this[this.length - 1];
	},

	compact: function() {
		return this.select(function(value) {
			return value != null;
		});
	},

	without: function() {
		var values = $A(arguments);
		return this.select(function(value) {
			return !values.include(value);
		});
	},

	indexOf: function(object) {
		for (var i = 0, length = this.length; i < length; i++)
			if (this[i] == object) return i;
		return -1;
	},

	reverse: function(inline) {
		return (inline !== false ? this : this.toArray())._reverse();
	},
	
	clone: function() {
		return [].concat(this);
	},

	size: function() {
		return this.length;
	},

	toJSON: function() {
		var results = [];
		this.each(function(object) {
			var value = Object.toJSON(object);
			if (value !== undefined) results.push(value);
		});
		
		return '[' + results.join(', ') + ']';
	}
});

Array.prototype.toArray = Array.prototype.clone;

if (Prototype.Browser.Opera){
	Array.prototype.concat = function() {
		var array = [];
		for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
		for (var i = 0, length = arguments.length; i < length; i++) {
			if (arguments[i].constructor == Array) {
				for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
					array.push(arguments[i][j]);
			} else {
				array.push(arguments[i]);
			}
		}
		return array;
	};
};

//--------------------------------------------------------------------------
// Hash
//--------------------------------------------------------------------------

var Hash = function(object) {
	if (object instanceof Hash) this.merge(object);
	else Object.extend(this, object || {});
};

Object.extend(Hash, {
	toQueryString: function(obj) {
		var parts = [];
		parts.add = arguments.callee.addPair;

		this.prototype._each.call(obj, function(pair) {
			if (!pair.key) return;
			
			var value = pair.value;

			if (value && $T(value) == 'object') { 
				if (value.constructor == Array) value.each(function(value) {
					parts.add(pair.key, value);
				});
				
				return;
			}
	  
			parts.add(pair.key, value);
		});

		return parts.join('&');
	},

	toJSON: function(object) {
		var results = [];
		this.prototype._each.call(object, function(pair) {
			var value = Object.toJSON(pair.value);
			if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
		});
		
		return '{' + results.join(', ') + '}';
	}
});

Hash.toQueryString.addPair = function(key, value, prefix) {
	key = encodeURIComponent(key);
	if (value === undefined) this.push(key);
	else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value)));
};

Object.extend(Hash.prototype, Enumerable);
Object.extend(Hash.prototype, {
	_each: function(iterator) {
		for (var key in this) {
			var value = this[key];
			if (value && value == Hash.prototype[key]) continue;

			var pair = [key, value];
			pair.key = key;
			pair.value = value;
			iterator(pair);
		}
	},

	keys: function() {
		return this.pluck('key');
	},
  
	merge: function(hash) {
		return $H(hash).inject(this, function(mergedHash, pair) {
			mergedHash[pair.key] = pair.value;
			return mergedHash;
		});
	},

	toQueryString: function() {
		return Hash.toQueryString(this);
	},

	toJSON: function() {
		return Hash.toJSON(this);
	}
});

function $H(object) {
	if (object instanceof Hash) return object;
	return new Hash(object);
};

// Safari iterates over shadowed properties
if (function() {
	var i = 0, Test = function(value) { this.key = value };
	Test.prototype.key = 'foo';
	for (var property in new Test('bar')) i++;
	return i > 1;
}()) Hash.prototype._each = function(iterator) {
	var cache = [];
	for (var key in this) {
		var value = this[key];
		if ((value && value == Hash.prototype[key]) || cache.include(key)) continue;
		cache.push(key);
		var pair = [key, value];
		pair.key = key;
		pair.value = value;
		iterator(pair);
	}
};

//--------------------------------------------------------------------------
// Element
//--------------------------------------------------------------------------

function $(element) {
	if (arguments.length > 1) {
		for (var i = 0, elements = [], length = arguments.length; i < length; i++)
			elements.push($(arguments[i]));
		return elements;
	}
	
	if ($T(element) == 'string') 
		element = document.getElementById(element);
	
	return Element.extend(element);
};

if (Prototype.BrowserFeatures.XPath) {
	document._getElementsByXPath = function(expression, parentElement) {
		var results = [];
		var query = document.evaluate(expression, $(parentElement) || document,
			null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
		for (var i = 0, length = query.snapshotLength; i < length; i++)
			results.push(query.snapshotItem(i));
		return results;
	};

	document.getElementsByClassName = function(className, parentElement) {
		var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
		return document._getElementsByXPath(q, parentElement);
	};
} else document.getElementsByClassName = function(className, parentElement) {
	var children = ($(parentElement) || document.body).getElementsByTagName('*');
	var elements = [], child, pattern = new RegExp("(^|\\s)" + className + "(\\s|$)");

	for (var i = 0, length = children.length; i < length; i++) {
		child = children[i];
		var elementClassName = child.className;
		if (elementClassName.length == 0) continue;
		if (elementClassName == className || elementClassName.match(pattern))
		elements.push(Element.extend(child));
	}

	return elements;
};

if (!window.Element) var Element = {};

Element.extend = function(element) {
	var F = Prototype.BrowserFeatures;
	
	if (!element || !element.tagName || element.nodeType == 3 ||
		element._extended || F.SpecificElementExtensions || element == window)
		return element;

	var methods = {}, tagName = element.tagName, cache = Element.extend.cache,
	T = Element.Methods.ByTag;

	// extend methods for all tags (Safari doesn't need this)
	if (!F.ElementExtensions) {		
		Object.extend(methods, Element.Methods);
		Object.extend(methods, Element.Methods.Simulated);
	}

	// extend methods for specific tags
	if (T[tagName]) Object.extend(methods, T[tagName]);

	for (var property in methods) {
		var value = methods[property];
		if ($T(value) == 'function' && !(property in element))
			element[property] = cache.findOrStore(value);
	}

	element._extended = Prototype.emptyFunction;
	return element;
};

Element.extend.cache = {
	findOrStore: function(value) {
		return this[value] = this[value] || function() {
			return value.apply(null, [this].concat($A(arguments)));
		}
	}
};

Element.Methods = {
	visible: function(element) {
		return $(element).style.display != 'none';
	},

	toggle: function(element) {
		element = $(element);
		Element[Element.visible(element) ? 'hide' : 'show'](element);
		return element;
	},

	hide: function(element) {
		$(element).style.display = 'none';
		return element;
	},

	show: function(element) {
		$(element).style.display = 'block';
		return element;
	},

	remove: function(element) {
		element = $(element);
		element.parentNode.removeChild(element);
		return element;
	},

	update: function(element, html) {
		html = $T(html) == 'undefined' ? '' : html.toString();
	    $(element).innerHTML = html.stripScripts();
		setTimeout(function() {html.evalScripts()}, 10);
	    return element;
	},

	getElementsByClassName: function(element, className) {
		return document.getElementsByClassName(className, element);
	},
	
	getHeight: function(element) {
		return $(element).getDimensions().height;
	},

	getWidth: function(element) {
		return $(element).getDimensions().width;
	},

	classNames: function(element) {
		return new Element.ClassNames(element);
	},
	
	getDimensions: function(element) {
		element = $(element);
		var display = $(element).getStyle('display');
		// Safari bug
		if (display != 'none' && display != null) 
			return {width: element.offsetWidth, height: element.offsetHeight};

		// All *Width and *Height properties give 0 on elements with display none,
		// so enable the element temporarily
		var els = element.style;
		var originalVisibility = els.visibility;
		var originalPosition = els.position;
		var originalDisplay = els.display;
		els.visibility = 'hidden';
		els.position = 'absolute';
		els.display = 'block';
		var originalWidth = element.clientWidth;
		var originalHeight = element.clientHeight;
		els.display = originalDisplay;
		els.position = originalPosition;
		els.visibility = originalVisibility;
		
		return {width: originalWidth, height: originalHeight};
	},
	
	makePositioned: function(element) {
		element = $(element);
		var pos = Element.getStyle(element, 'position');
		if (pos == 'static' || !pos) {
			element._madePositioned = true;
			element.style.position = 'relative';
			// Opera returns the offset relative to the positioning context, when an
			// element is position relative but top and left have not been defined
			if (window.opera) {
				element.style.top = 0;
				element.style.left = 0;
			}
		}
		
		return element;
	},

	undoPositioned: function(element) {
		element = $(element);
		if (element._madePositioned) {
			element._madePositioned = undefined;
			element.style.position =
			element.style.top =
			element.style.left =
			element.style.bottom =
			element.style.right = '';
		}
		return element;
	},

	makeClipping: function(element) {
		element = $(element);
		if (element._overflow) return element;
		element._overflow = element.style.overflow || 'auto';
		if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
			element.style.overflow = 'hidden';
		return element;
	},

	undoClipping: function(element) {
		element = $(element);
		if (!element._overflow) return element;
		element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
		element._overflow = null;
		return element;
	},

	hasClassName: function(element, className) {
		if (!(element = $(element))) return;
		var elementClassName = element.className;
		if (elementClassName.length == 0) return false;
		if (elementClassName == className ||
			elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
			return true;
		return false;
	},

	addClassName: function(element, className) {
		if (!(element = $(element))) return;
		Element.classNames(element).add(className);
		return element;
	},

	removeClassName: function(element, className) {
		if (!(element = $(element))) return;
		Element.classNames(element).remove(className);
		return element;
	},
  
	getStyle: function(element, style) {
		element = $(element);
		style = style == 'float' ? 'cssFloat' : style.camelize();
		var value = element.style[style];
		if (!value) {
			var css = document.defaultView.getComputedStyle(element, null);
			value = css ? css[style] : null;
		}
		if (style == 'opacity') return value ? parseFloat(value) : 1.0;
		return value == 'auto' ? null : value;
	},

	getOpacity: function(element) {
		return $(element).getStyle('opacity');
	},

	setStyle: function(element, styles, camelized) {
		element = $(element);
		var elementStyle = element.style;

		for (var property in styles)
			if (property == 'opacity')
				element.setOpacity(styles[property]);
			else
				elementStyle[(property == 'float' || property == 'cssFloat') ?
					(elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
					(camelized ? property : property.camelize())] = styles[property];
		return element;
	},

	setOpacity: function(element, value) {
		element = $(element);
		element.style.opacity = (value == 1 || value === '') ? '' : (value < 0.00001) ? 0 : value;
		return element;
	},
	
	observe: function() {
		Event.observe.apply(Event, arguments);
		return $A(arguments).first();
	},
	
	stopObserving: function() {
		Event.stopObserving.apply(Event, arguments);
		return $A(arguments).first();
	},

	// removes whitespace-only text node children
	cleanWhitespace: function(element) {
		element = $(element);
		var node = element.firstChild;
		while (node) {
			var nextNode = node.nextSibling;
			if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
				element.removeChild(node);
			node = nextNode;
		}
		return element;
	},
  
	readAttribute: function(element, name) {
		element = $(element);
		if (Prototype.Browser.IE) {
			if (!element.attributes) return null;
			var t = Element._attributeTranslations;
			if (t.values[name]) return t.values[name](element, name);
			if (t.names[name])  name = t.names[name];
			var attribute = element.attributes[name];
			return attribute ? attribute.nodeValue : null;
		}
		return element.getAttribute(name);
	}
};

if (Prototype.Browser.Opera) {
	Element.Methods._getStyle = Element.Methods.getStyle;
	Element.Methods.getStyle = function(element, style) {
		switch(style) {
			case 'left':
			case 'top':
			case 'right':
			case 'bottom':
				if (Element._getStyle(element, 'position') == 'static') return null;
			default: return Element._getStyle(element, style);
		}
	};
}
else if (Prototype.Browser.IE) {
	Element.Methods.getStyle = function(element, style) {
		element = $(element);
		style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
		var value = element.style[style];
		if (!value && element.currentStyle) value = element.currentStyle[style];

		if (style == 'opacity') {
			if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
				if (value[1]) return parseFloat(value[1]) / 100;
			return 1.0;
		}

		if (value == 'auto') {
			if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
				return element['offset'+style.capitalize()] + 'px';
			return null;
		}
		
		return value;
	};

	Element.Methods.setOpacity = function(element, value) {
		element = $(element);
		var filter = element.getStyle('filter'), style = element.style;
		if (value == 1 || value === '') {
			style.filter = filter.replace(/alpha\([^\)]*\)/gi,'');
			return element;
		} else if (value < 0.00001) value = 0;
			style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') + 
				'alpha(opacity=' + (value * 100) + ')';
			return element;
	};
}
else if (Prototype.Browser.Gecko) {
	Element.Methods.setOpacity = function(element, value) {
		element = $(element);
		element.style.opacity = (value == 1) ? 0.999999 :
			(value === '') ? '' : (value < 0.00001) ? 0 : value;
		return element;
	};
};

Element._attributeTranslations = {
	names: {
		colspan:   "colSpan",
		rowspan:   "rowSpan",
		valign:    "vAlign",
		datetime:  "dateTime",
		accesskey: "accessKey",
		tabindex:  "tabIndex",
		enctype:   "encType",
		maxlength: "maxLength",
		readonly:  "readOnly",
		longdesc:  "longDesc"
	},
	values: {
		_getAttr: function(element, attribute) {
				return element.getAttribute(attribute, 2);
		},
		_flag: function(element, attribute) {
			return $(element).hasAttribute(attribute) ? attribute : null;
		},
		style: function(element) {
			return element.style.cssText.toLowerCase();
		},
		title: function(element) {
			var node = element.getAttributeNode('title');
			return node.specified ? node.nodeValue : null;
		}
	}
};

(function() {
	Object.extend(this, {
		href: this._getAttr,
		src:  this._getAttr,
		type: this._getAttr,
		disabled: this._flag,
		checked:  this._flag,
		readonly: this._flag,
		multiple: this._flag
	});
}).call(Element._attributeTranslations.values);

Element.Methods.Simulated = {
	hasAttribute: function(element, attribute) {
		var t = Element._attributeTranslations, node;
		attribute = t.names[attribute] || attribute;
		node = $(element).getAttributeNode(attribute);
		return node && node.specified;
	}
};

Element.Methods.ByTag = {};

Object.extend(Element, Element.Methods);

Element.hasAttribute = function(element, attribute) {
	if (element.hasAttribute) return element.hasAttribute(attribute);
	return Element.Methods.Simulated.hasAttribute(element, attribute);
};

if (!Prototype.BrowserFeatures.ElementExtensions &&
		document.createElement('div').__proto__) {
	window.HTMLElement = {};
	window.HTMLElement.prototype = document.createElement('div').__proto__;
	Prototype.BrowserFeatures.ElementExtensions = true;
};

Element.addMethods = function(methods) {
	var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;

	if (arguments.length == 2) {
		var tagName = methods;
		methods = arguments[1];
	}

	if (!tagName)
		Object.extend(Element.Methods, methods || {});
	else {
		if (tagName.constructor == Array)
			tagName.each(extend);
		else
			extend(tagName);
	}

	function extend(tagName) {
		tagName = tagName.toUpperCase();
		if (!Element.Methods.ByTag[tagName])
			Element.Methods.ByTag[tagName] = {};
		Object.extend(Element.Methods.ByTag[tagName], methods);
	}

	function copy(methods, destination, onlyIfAbsent) {
		onlyIfAbsent = onlyIfAbsent || false;
		var cache = Element.extend.cache;
		for (var property in methods) {
			var value = methods[property];
			if (!onlyIfAbsent || !(property in destination))
				destination[property] = cache.findOrStore(value);
		}
	}

	function findDOMClass(tagName) {
		var klass;
		var trans = {
			"OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
			"FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
			"DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
			"H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
			"INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
			"TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
			"TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
			"TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
			"FrameSet", "IFRAME": "IFrame"
		};
		
		if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
		if (window[klass]) return window[klass];
			klass = 'HTML' + tagName + 'Element';
		if (window[klass]) return window[klass];
			klass = 'HTML' + tagName.capitalize() + 'Element';
		if (window[klass]) return window[klass];

		window[klass] = {};
		window[klass].prototype = document.createElement(tagName).__proto__;
		
		return window[klass];
	}

	if (F.ElementExtensions) {
		copy(Element.Methods, HTMLElement.prototype);
		copy(Element.Methods.Simulated, HTMLElement.prototype, true);
	}

	if (F.SpecificElementExtensions) {
		for (var tag in Element.Methods.ByTag) {
			var klass = findDOMClass(tag);
			if ($T(klass) == "undefined") continue;
			copy(T[tag], klass.prototype);
		}
	}

	Object.extend(Element, Element.Methods);
	delete Element.ByTag;
};

Element.addMethods();

//--------------------------------------------------------------------------
// Element > ClassNames
//--------------------------------------------------------------------------

Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
	initialize: function(element) {
		this.element = $(element);
	},

	_each: function(iterator) {
		this.element.className.split(/\s+/).select(function(name) {
			return name.length > 0;
		})._each(iterator);
	},

	set: function(className) {
		this.element.className = className;
	},

	add: function(classNameToAdd) {
		if (this.include(classNameToAdd)) return;
		this.set($A(this).concat(classNameToAdd).join(' '));
	},

	remove: function(classNameToRemove) {
		if (!this.include(classNameToRemove)) return;
		this.set($A(this).without(classNameToRemove).join(' '));
	},

	toString: function() {
		return $A(this).join(' ');
	}
};

Object.extend(Element.ClassNames.prototype, Enumerable);

//--------------------------------------------------------------------------
// Event
//--------------------------------------------------------------------------

if (!window.Event) var Event = new Object();

Object.extend(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,

	element: function(event) {
		return $(event.target || event.srcElement);
	},

	isLeftClick: function(event) {
		return (((event.which) && (event.which == 1)) ||
				((event.button) && (event.button == 1)));
	},

	pointerX: function(event) {
		return event.pageX || (event.clientX +
			(document.documentElement.scrollLeft || document.body.scrollLeft));
	},

	pointerY: function(event) {
		return event.pageY || (event.clientY +
			(document.documentElement.scrollTop || document.body.scrollTop));
	},

	stop: function(event) {
		if (event.preventDefault) {
			event.preventDefault();
			event.stopPropagation();
		} else {
			event.returnValue = false;
			event.cancelBubble = true;
		}
	},

	observers: false,

	_observeAndCache: function(element, name, observer, useCapture) {
		if (!this.observers) this.observers = [];
		if (element.addEventListener) {
			this.observers.push([element, name, observer, useCapture]);
			element.addEventListener(name, observer, useCapture);			
		} else if (element.attachEvent) {
			this.observers.push([element, name, observer, useCapture]);
			element.attachEvent('on' + name, observer);
		}
	},

	unloadCache: function() {
		if (!Event.observers) return;
		for (var i = 0, length = Event.observers.length; i < length; i++) {
			Event.stopObserving.apply(this, Event.observers[i]);
			Event.observers[i][0] = null;
		}
		Event.observers = false;
	},

	observe: function(element, name, observer, useCapture) {
		element = $(element);
		useCapture = useCapture || false;

		if (name == 'keypress' && (Prototype.Browser.WebKit || element.attachEvent))
			name = 'keydown';

		Event._observeAndCache(element, name, observer, useCapture);
	},

	stopObserving: function(element, name, observer, useCapture) {
		element = $(element);
		useCapture = useCapture || false;

		if (name == 'keypress' && (Prototype.Browser.WebKit || element.attachEvent))
			name = 'keydown';

		if (element.removeEventListener) {
			element.removeEventListener(name, observer, useCapture);
		} else if (element.detachEvent) {
			try {
				element.detachEvent('on' + name, observer);
			} catch (e) {}
		}
	}
});

// prevent memory leaks in IE
if (Prototype.Browser.IE)
{
	Event.observe(window, 'unload', Event.unloadCache, false);	
}

//--------------------------------------------------------------------------
// Position
//--------------------------------------------------------------------------	

var Position = {
	// set to true if needed, warning: firefox performance problems
	// NOT neeeded for page scrolling, only if draggable contained in
	// scrollable elements
	includeScrollOffsets: false,

	// must be called before calling withinIncludingScrolloffset, every time the
	// page is scrolled
	prepare: function() {
		this.deltaX =  window.pageXOffset
				|| document.documentElement.scrollLeft
				|| document.body.scrollLeft || 0;
		this.deltaY =  window.pageYOffset
				|| document.documentElement.scrollTop
				|| document.body.scrollTop || 0;
	},

	realOffset: function(element) {
		var valueT = 0, valueL = 0;
		do {
			valueT += element.scrollTop  || 0;
			valueL += element.scrollLeft || 0;
			element = element.parentNode;
		} while (element);
		return [valueL, valueT];
	},

	cumulativeOffset: function(element) {
		var valueT = 0, valueL = 0;
		do {
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;
			element = element.offsetParent;
		} while (element);
		return [valueL, valueT];
	},

	positionedOffset: function(element) {
		var valueT = 0, valueL = 0;
		do {
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;
			element = element.offsetParent;
			if (element) {
				if(element.tagName=='BODY') break;
				var p = Element.getStyle(element, 'position');
				if (p == 'relative' || p == 'absolute') break;
			}
		} while (element);
		return [valueL, valueT];
	},

	offsetParent: function(element) {
		if (element.offsetParent) return element.offsetParent;
		if (element == document.body) return element;

		while ((element = element.parentNode) && element != document.body)
			if (Element.getStyle(element, 'position') != 'static')
				return element;

		return document.body;
	},

	// caches x/y coordinate pair to use with overlap
	within: function(element, x, y) {
		if (this.includeScrollOffsets)
			return this.withinIncludingScrolloffsets(element, x, y);
		this.xcomp = x;
		this.ycomp = y;
		this.offset = this.cumulativeOffset(element);

		return (y >= this.offset[1] &&
				y <  this.offset[1] + element.offsetHeight &&
				x >= this.offset[0] &&
				x <  this.offset[0] + element.offsetWidth);
	},

	withinIncludingScrolloffsets: function(element, x, y) {
		var offsetcache = this.realOffset(element);

		this.xcomp = x + offsetcache[0] - this.deltaX;
		this.ycomp = y + offsetcache[1] - this.deltaY;
		this.offset = this.cumulativeOffset(element);

		return (this.ycomp >= this.offset[1] &&
				this.ycomp <  this.offset[1] + element.offsetHeight &&
				this.xcomp >= this.offset[0] &&
				this.xcomp <  this.offset[0] + element.offsetWidth);
	},

	// within must be called directly before
	overlap: function(mode, element) {
		if (!mode) return 0;
		if (mode == 'vertical')
			return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
				element.offsetHeight;
		if (mode == 'horizontal')
			return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
				element.offsetWidth;
	},

	page: function(forElement) {
		var valueT = 0, valueL = 0;

		var element = forElement;
		do {
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;

			// Safari fix
			if (element.offsetParent == document.body)
			if (Element.getStyle(element,'position')=='absolute') break;
		} while (element = element.offsetParent);

		element = forElement;
		do {
			if (!window.opera || element.tagName=='BODY') {
				valueT -= element.scrollTop  || 0;
				valueL -= element.scrollLeft || 0;
			}
		} while (element = element.parentNode);

		return [valueL, valueT];
	},

	absolutize: function(element) {
		element = $(element);
		if (element.style.position == 'absolute') return;
		Position.prepare();

		var offsets = Position.positionedOffset(element);
		var top     = offsets[1];
		var left    = offsets[0];
		var width   = element.clientWidth;
		var height  = element.clientHeight;

		element._originalLeft   = left - parseFloat(element.style.left  || 0);
		element._originalTop    = top  - parseFloat(element.style.top || 0);
		element._originalWidth  = element.style.width;
		element._originalHeight = element.style.height;

		element.style.position = 'absolute';
		element.style.top    = top + 'px';
		element.style.left   = left + 'px';
		element.style.width  = width + 'px';
		element.style.height = height + 'px';
	},

	relativize: function(element) {
		element = $(element);
		if (element.style.position == 'relative') return;
		Position.prepare();

		element.style.position = 'relative';
		var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
		var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

		element.style.top    = top + 'px';
		element.style.left   = left + 'px';
		element.style.height = element._originalHeight;
		element.style.width  = element._originalWidth;
	},
	
	getWindowSize: function(w) {
		w = w ? w : window;
		var width = w.innerWidth || (w.document.documentElement.clientWidth || w.document.body.clientWidth);
		var height = w.innerHeight || (w.document.documentElement.clientHeight || w.document.body.clientHeight);
		return { width: width, height: height };
	},

	center: function(element){
		var options = Object.extend({
			zIndex: 9999,
			update: false
		}, arguments[1] || {});

		element = $(element);

		if(!element._centered){
			Element.setStyle(element, {position: 'absolute', zIndex: options.zIndex });
			element._centered = true;
		}

		var dims = Element.getDimensions(element);

		Position.prepare();
		var winSize = Position.getWindowSize();
		var winWidth = winSize.width;
		var winHeight = winSize.height;

		var offLeft = (Position.deltaX + Math.floor((winWidth-dims.width)/2));
		var offTop = (Position.deltaY + Math.floor((winHeight-dims.height)/2));

		element.style.top = ((offTop != null && offTop > 0) ? offTop : '0')+ 'px';
		element.style.left = ((offLeft != null && offLeft > 0) ? offLeft :'0') + 'px';

		if (options.update) {
			Event.observe(window, 'resize', function(evt) { Position.center(element); }, false);
			Event.observe(window, 'scroll', function(evt) { Position.center(element); }, false);
		}
	}
};

// Safari returns margins on body which is incorrect if the child is absolutely
// positioned.  For performance reasons, redefine Position.cumulativeOffset for
// KHTML/WebKit only.
if (Prototype.Browser.WebKit) {
	Position.cumulativeOffset = function(element) {
		var valueT = 0, valueL = 0;
		do {
			valueT += element.offsetTop  || 0;
			valueL += element.offsetLeft || 0;
			if (element.offsetParent == document.body)
			if (Element.getStyle(element, 'position') == 'absolute') break;

			element = element.offsetParent;
		} while (element);

		return [valueL, valueT];
	}
}

//--------------------------------------------------------------------------
// Add Functions By ifsnow
//--------------------------------------------------------------------------	

// IE 6,7 check
if (Prototype.Browser.IE)
{
	Prototype.Browser[window.XMLHttpRequest ? 'IE7' : 'IE6'] = true;
	
	// enables background image cache for internet explorer 6
	if (Prototype.Browser.IE6)
	{
		try {document.execCommand("BackgroundImageCache", false, true);} catch(e){}
	}	
}

function $C(tag) {
	return $(document.createElement(tag));
}

function $F(element) {
	return $(element).value;	
}

function $D(element) {
	return (typeof element=="undefined" || element==null) ? false:true;
}

function $B(val) {
	return val=="true" ? true: val=="false" ? false:val;
}

function $ATTR(element, name) {
	var attr = $(element).readAttribute(name);

	// IEÀÏ °æ¿ì ¿¹¾àµÈ ¼Ó¼ºÀº ¼Ó¼º¸íÀº ¹ÝÈ¯
	if (attr==name) return true;
	
	if (!Prototype.Browser.IE && attr!=null && attr.empty())
		return true;
	
	// ¼Ó¼ºÀÌ ¾ø´Â °æ¿ì
	if (attr==null || ($T(attr)=="string" && attr.empty())) return false;	

	return $B(attr);
}

function $LOADJS(file) {
	var script = document.createElement("script");
	script.type = "text/javascript";
	script.src = file;
	document.getElementsByTagName('head')[0].appendChild(script); 
}

function $FLASH(file, options) {
	options = Object.extend({
		id: '',
		width: '100%',
		height: '100%',
		access: 'sameDomain'
	}, options || {});
	
	var id ='id="'+ options.id +'" name="'+ options.id +'"';
	
	if (Prototype.Browser.IE)
    {
		var html = '<object ' + id + ' type="application/x-shockwave-flash" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" ';
		html += 'width="' + options.width + '" height="' + options.height + '">';
		html += '<param name="movie" value="' + file + '" />';
		html += '<param name="quality" value="high" />';
		html += '<param name="wmode" value="transparent" />';
		html += '<param name="allowScriptAccess" value="' + options.access + '" />';
		html += '</object>';
	}
	else
	{
		var html = '<embed '+ id + ' src="' + file +'" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" ';
		html += ' width="' + options.width + '" height="' + options.height + '" ';
		html += ' allowScriptAccess="' + options.access + '"> </embed>';
	}

	document.write(html);
}

function $PRIVACY() {
	document.oncontextmenu = new Function ("return false");
	document.ondragstart = new Function ("return false");
	document.onselectstart = new Function ("return false");
}

function $ONDOMLOAD(func) {
	Prototype.onDomLoadFunc = func;
	
	if (Prototype.Browser.Gecko || Prototype.Browser.Opera)	{
		Event.observe(window, "DOMContentLoaded", $ONDOMLOAD_FUNCTION);
	} else if (Prototype.Browser.IE) {
		document.write("<scr" + "ipt id=__ie_init defer=true " + "src=//:><\/script>");	
		var script = $("__ie_init");		
		
		if ( script ) {
			script.onreadystatechange = function() {
				if ( this.readyState != "complete" ) return;
				$ONDOMLOAD_FUNCTION();
			};
		}
				
		script = null;
	} else if (Prototype.Browser.WebKit) {
		new PeriodicalExecuter(function(pe){
			// loaded and complete are both valid states
			if ( document.readyState == "loaded" || 
				document.readyState == "complete" ) {				
				pe.stop();	
				$ONDOMLOAD_FUNCTION();
			}
		}, 0.01); 
	}
}

function $ONDOMLOAD_FUNCTION() {
	if ($D(Prototype.onDomLoadFunc)) {
		Prototype.onDomLoadFunc();
		Prototype.onDomLoadFunc = null;

		if (Prototype.Browser.Gecko || Prototype.Browser.Opera)	{
			Event.stopObserving(document, "DOMContentLoaded", $ONDOMLOAD_FUNCTION);
		}
	}
}
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > Core > Ajax
 *
 * base : prototype.js v1.5.1.1
 */

if(typeof Prototype == "undefined")
	throw("empas.prototype.ajax.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};

/*============================================================================*
 * Ajax
 *============================================================================*/
Empas.Ajax = {
	getTransport: function() {
		try { return new XMLHttpRequest() } catch (e) {}
		try { return new ActiveXObject('Msxml2.XMLHTTP') } catch (e) {}
		try { return new ActiveXObject('Microsoft.XMLHTTP') } catch (e) {}
		return false;
	},
	activeRequestCount: 0
};

var Ajax = Empas.Ajax;

Ajax.Responders = {
	responders: [],

	_each: function(iterator) {
		this.responders._each(iterator);
	},

	register: function(responder) {
		if (!this.include(responder))
			this.responders.push(responder);
	},

	unregister: function(responder) {
		this.responders = this.responders.without(responder);
	},

	dispatch: function(callback, request, transport, json) {
		this.each(function(responder) {
			if (typeof responder[callback] == 'function') {
				try {
					responder[callback].apply(responder, [request, transport, json]);
				} catch (e) {}
			}
		});
	}
};

Object.extend(Ajax.Responders, Enumerable);

Ajax.Responders.register({
	onCreate: function() {
		Ajax.activeRequestCount++;
	},
	onComplete: function() {
		Ajax.activeRequestCount--;
	}
});

Ajax.Base = function() {};
Ajax.Base.prototype = {
	setOptions: function(options) {
		this.options = {
			method:       'post',
			asynchronous: true,
			contentType:  'application/x-www-form-urlencoded',
			encoding:     'UTF-8',
			parameters:   ''
		};
		
		Object.extend(this.options, options || {});

		options = this.options;
		options.method = options.method.toLowerCase();
		if ($T(options.parameters) == 'string')
			options.parameters = options.parameters.toQueryParams();
	}
};

Ajax.Request = Class.create();
Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
	_complete: false,

	initialize: function(url, options) {
		this.transport = Ajax.getTransport();
		this.setOptions(options);
		this.request(url);
	},

	request: function(url) {
		this.url = url;
		this.method = this.options.method;
		var params = Object.clone(this.options.parameters);

		if (!['get', 'post'].include(this.method)) {
			// simulate other verbs over post
			params['_method'] = this.method;
			this.method = 'post';
		}

		this.parameters = params;

		if ((params = Hash.toQueryString(params))) {
			// when GET, append parameters to URL
			if (this.method == 'get')
				this.url += (this.url.include('?') ? '&' : '?') + params;
			else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
				params += '&_=';
		}

		try {
			if (this.options.onCreate) this.options.onCreate(this.transport);
			Ajax.Responders.dispatch('onCreate', this, this.transport);

			this.transport.open(this.method.toUpperCase(), this.url,
				this.options.asynchronous);

			if (this.options.asynchronous)
			setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);

			this.transport.onreadystatechange = this.onStateChange.bind(this);
			this.setRequestHeaders();

			this.body = this.method == 'post' ? (this.options.postBody || params) : null;
			this.transport.send(this.body);

			/* Force Firefox to handle ready state 4 for synchronous requests */
			if (!this.options.asynchronous && this.transport.overrideMimeType)
				this.onStateChange();
		}
		catch (e) {
			this.dispatchException(e);
		}
	},

	onStateChange: function() {
		var readyState = this.transport.readyState;
		if (readyState > 1 && !((readyState == 4) && this._complete))
			this.respondToReadyState(this.transport.readyState);
	},

	setRequestHeaders: function() {
		var headers = {
			'X-Requested-With': 'XMLHttpRequest',
			'X-Prototype-Version': Prototype.Version,
			'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
		};

		if (this.method == 'post') {
			headers['Content-type'] = this.options.contentType +
				(this.options.encoding ? '; charset=' + this.options.encoding : '');

			// Force "Connection: close" for older Mozilla browsers to work
			// around a bug where XMLHttpRequest sends an incorrect
			// Content-length header. See Mozilla Bugzilla #246651.
			if (this.transport.overrideMimeType &&
				(navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
				headers['Connection'] = 'close';
		}

		// user-defined headers
		if (typeof this.options.requestHeaders == 'object') {
			var extras = this.options.requestHeaders;

			if (typeof extras.push == 'function')
				for (var i = 0, length = extras.length; i < length; i += 2)
					headers[extras[i]] = extras[i+1];
			else
				$H(extras).each(function(pair) { headers[pair.key] = pair.value });
		}

		for (var name in headers)
			this.transport.setRequestHeader(name, headers[name]);
	},

	success: function() {
		return !this.transport.status
			|| (this.transport.status >= 200 && this.transport.status < 300);
	},

	respondToReadyState: function(readyState) {
		var state = Ajax.Request.Events[readyState];
		var transport = this.transport, json = this.evalJSON();

		if (state == 'Complete') {
			try {
				this._complete = true;
				(this.options['on' + this.transport.status]
					|| this.options['on' + (this.success() ? 'Success' : 'Failure')]
					|| Prototype.emptyFunction)(transport, json);
			} catch (e) {
				this.dispatchException(e);
			}

			var contentType = this.getHeader('Content-type');
			if (contentType && contentType.strip().
				match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
				this.evalResponse();
		}

		try {
			(this.options['on' + state] || Prototype.emptyFunction)(transport, json);
			Ajax.Responders.dispatch('on' + state, this, transport, json);
		} catch (e) {
			this.dispatchException(e);
		}

		if (state == 'Complete') {
			// avoid memory leak in MSIE: clean up
			this.transport.onreadystatechange = Prototype.emptyFunction;
		}
	},

	getHeader: function(name) {
		try {
			return this.transport.getResponseHeader(name);
		} catch (e) { return null }
	},

	evalJSON: function() {
		try {
			var json = this.getHeader('X-JSON');
			return json ? json.evalJSON() : null;
		} catch (e) { return null }
	},

	evalResponse: function() {
		try {
			return eval((this.transport.responseText || '').unfilterJSON());
		} catch (e) {
			this.dispatchException(e);
		}
	},

	dispatchException: function(exception) {
		(this.options.onException || Prototype.emptyFunction)(this, exception);
		Ajax.Responders.dispatch('onException', this, exception);
	}
});

Ajax.Updater = Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
	initialize: function(container, url, options) {
		this.container = {
			success: (container.success || container),
			failure: (container.failure || (container.success ? null : container))
		};

		this.transport = Ajax.getTransport();
		this.setOptions(options);

		var onComplete = this.options.onComplete || Prototype.emptyFunction;
		this.options.onComplete = (function(transport, param) {
			this.updateContent();
			onComplete(transport, param);
		}).bind(this);

		this.request(url);
	},

	updateContent: function() {
		var receiver = this.container[this.success() ? 'success' : 'failure'];
		var response = this.transport.responseText;

		if (!this.options.evalScripts) response = response.stripScripts();

		if (receiver = $(receiver)) {
			if (this.options.insertion) 
				new this.options.insertion(receiver, response);
			else
				receiver.update(response);
		}

		if (this.success()) {
			if (this.onComplete) setTimeout(this.onComplete.bind(this), 10);
		}
	}
});
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > Core > Selector
 *
 * base : prototype.js v1.5.1.1
 */

Object.extend(Element.Methods, {
	recursivelyCollect: function(element, property) {
		element = $(element);
		var elements = [];
		while (element = element[property])
			if (element.nodeType == 1) elements.push(Element.extend(element));
		return elements;
	},

	ancestors: function(element) {
		return $(element).recursivelyCollect('parentNode');
	},

	descendants: function(element) {
		return $A($(element).getElementsByTagName('*')).each(Element.extend);
	},

	firstDescendant: function(element) {
		element = $(element).firstChild;
		while (element && element.nodeType != 1) element = element.nextSibling;
		return $(element);
	},

	immediateDescendants: function(element) {
		if (!(element = $(element).firstChild)) return [];
		while (element && element.nodeType != 1) element = element.nextSibling;
		if (element) return [element].concat($(element).nextSiblings());
		return [];
	},

	previousSiblings: function(element) {
		return $(element).recursivelyCollect('previousSibling');
	},

	nextSiblings: function(element) {
		return $(element).recursivelyCollect('nextSibling');
	},

	siblings: function(element) {
		element = $(element);
		return element.previousSiblings().reverse().concat(element.nextSiblings());
	},

	match: function(element, selector) {
		if (typeof selector == 'string') selector = new Selector(selector);
		return selector.match($(element));
	},

	up: function(element, expression, index) {
		element = $(element);
		if (arguments.length == 1) return $(element.parentNode);
		var ancestors = element.ancestors();
		return expression ? Selector.findElement(ancestors, expression, index) :
      		ancestors[index || 0];
	},

	down: function(element, expression, index) {
		element = $(element);
		if (arguments.length == 1) return element.firstDescendant();
		var descendants = element.descendants();
		return expression ? Selector.findElement(descendants, expression, index) :
			descendants[index || 0];
	},

	previous: function(element, expression, index) {
		element = $(element);
		if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
		var previousSiblings = element.previousSiblings();
		return expression ? Selector.findElement(previousSiblings, expression, index) :
			previousSiblings[index || 0];
	},

	next: function(element, expression, index) {
		element = $(element);
		if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
		var nextSiblings = element.nextSiblings();
		return expression ? Selector.findElement(nextSiblings, expression, index) :
			nextSiblings[index || 0];
	},

	getElementsBySelector: function() {
		var args = $A(arguments), element = $(args.shift());
		return Selector.findChildElements(element, args);
	},
	
	// removes whitespace-only text node children
	descendantOf: function(element, ancestor) {
		element = $(element), ancestor = $(ancestor);
		while (element = element.parentNode)
			if (element == ancestor) return true;
		return false;
	}
});

Object.extend(Element.Methods, {
	childOf: Element.Methods.descendantOf,
	childElements: Element.Methods.immediateDescendants
});

//--------------------------------------------------------------------------
// Selector
//--------------------------------------------------------------------------

// Portions of the Selector class are derived from Jack Slocum¡¯s DomQuery,
// part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
// license.  Please see http://www.yui-ext.com/ for more information.

var Selector = Class.create();

Selector.prototype = {
	initialize: function(expression) {
		this.expression = expression.strip();
		this.compileMatcher();
	},

	compileMatcher: function() {
		// Selectors with namespaced attributes can't use the XPath version
		if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
			return this.compileXPathMatcher();

		var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
			c = Selector.criteria, le, p, m;

		if (Selector._cache[e]) {
			this.matcher = Selector._cache[e]; return;
		}
		this.matcher = ["this.matcher = function(root) {",
			            "var r = root, h = Selector.handlers, c = false, n;"];

		while (e && le != e && (/\S/).test(e)) {
			le = e;
			for (var i in ps) {
				p = ps[i];
				if (m = e.match(p)) {
					this.matcher.push(typeof c[i] == 'function' ? c[i](m) :
    				new Template(c[i]).evaluate(m));
					e = e.replace(m[0], '');
					break;
				}
			}
		}

		this.matcher.push("return h.unique(n);\n}");
		eval(this.matcher.join('\n'));
		Selector._cache[this.expression] = this.matcher;
	},

	compileXPathMatcher: function() {
		var e = this.expression, ps = Selector.patterns,
			x = Selector.xpath, le,  m;

		if (Selector._cache[e]) {
			this.xpath = Selector._cache[e]; return;
		}

		this.matcher = ['.//*'];
		while (e && le != e && (/\S/).test(e)) {
			le = e;
			for (var i in ps) {
				if (m = e.match(ps[i])) {
					this.matcher.push(typeof x[i] == 'function' ? x[i](m) :
					new Template(x[i]).evaluate(m));
					e = e.replace(m[0], '');
					break;
				}
			}
		}

		this.xpath = this.matcher.join('');
		Selector._cache[this.expression] = this.xpath;
	},

	findElements: function(root) {
		root = root || document;
		if (this.xpath) return document._getElementsByXPath(this.xpath, root);
		return this.matcher(root);
	},

	match: function(element) {
		return this.findElements(document).include(element);
	},

	toString: function() {
		return this.expression;
	},

	inspect: function() {
		return "#<Selector:" + this.expression.inspect() + ">";
	}
};

Object.extend(Selector, {
	_cache: {},

	xpath: {
		descendant:   "//*",
		child:        "/*",
		adjacent:     "/following-sibling::*[1]",
		laterSibling: '/following-sibling::*',
		tagName: function(m) {
			if (m[1] == '*') return '';
			return "[local-name()='" + m[1].toLowerCase() +
				"' or local-name()='" + m[1].toUpperCase() + "']";
		},
		className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
		id:           "[@id='#{1}']",
		attrPresence: "[@#{1}]",
		attr: function(m) {
			m[3] = m[5] || m[6];
			return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
		},
		pseudo: function(m) {
			var h = Selector.xpath.pseudos[m[1]];
			if (!h) return '';
			if (typeof h === 'function') return h(m);
			return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
		},
		operators: {
			'=':  "[@#{1}='#{3}']",
			'!=': "[@#{1}!='#{3}']",
			'^=': "[starts-with(@#{1}, '#{3}')]",
			'$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
			'*=': "[contains(@#{1}, '#{3}')]",
			'~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
			'|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
		},
		pseudos: {
			'first-child': '[not(preceding-sibling::*)]',
			'last-child':  '[not(following-sibling::*)]',
			'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
			'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
			'checked':     "[@checked]",
			'disabled':    "[@disabled]",
			'enabled':     "[not(@disabled)]",
			'not': function(m) {
				var e = m[6], p = Selector.patterns,
				x = Selector.xpath, le, m, v;

				var exclusion = [];
				while (e && le != e && (/\S/).test(e)) {
					le = e;
					for (var i in p) {
						if (m = e.match(p[i])) {
							v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m);
							exclusion.push("(" + v.substring(1, v.length - 1) + ")");
							e = e.replace(m[0], '');
							break;
						}
					}
				}
				
				return "[not(" + exclusion.join(" and ") + ")]";
			},
			'nth-child': function(m) {
				return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
			},
			'nth-last-child': function(m) {
				return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
			},
			'nth-of-type':    function(m) {
				return Selector.xpath.pseudos.nth("position() ", m);
			},
			'nth-last-of-type': function(m) {
				return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
			},
			'first-of-type':  function(m) {
				m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
			},
			'last-of-type':   function(m) {
				m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
			},
			'only-of-type':   function(m) {
				var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
			},
			nth: function(fragment, m) {
				var mm, formula = m[6], predicate;
				if (formula == 'even') formula = '2n+0';
				if (formula == 'odd')  formula = '2n+1';
				if (mm = formula.match(/^(\d+)$/)) // digit only
					return '[' + fragment + "= " + mm[1] + ']';
				if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
					if (mm[1] == "-") mm[1] = -1;
					var a = mm[1] ? Number(mm[1]) : 1;
					var b = mm[2] ? Number(mm[2]) : 0;
					predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
						"((#{fragment} - #{b}) div #{a} >= 0)]";
					return new Template(predicate).evaluate({
						fragment: fragment, a: a, b: b });
				}
			}
		}
	},

	criteria: {
		tagName: 'n = h.tagName(n, r, "#{1}", c);   c = false;',
		className: 'n = h.className(n, r, "#{1}", c); c = false;',
		id: 'n = h.id(n, r, "#{1}", c);        c = false;',
		attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
		attr: function(m) {
			m[3] = (m[5] || m[6]);
			return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
		},
		pseudo: function(m) {
			if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
			return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
		},
		descendant: 'c = "descendant";',
		child: 'c = "child";',
		adjacent: 'c = "adjacent";',
		laterSibling: 'c = "laterSibling";'
	},

	patterns: {
		// combinators must be listed first
		// (and descendant needs to be last combinator)
		laterSibling: /^\s*~\s*/,
		child: /^\s*>\s*/,
		adjacent: /^\s*\+\s*/,
		descendant: /^\s/,

		// selectors follow
		tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
		id: /^#([\w\-\*]+)(\b|$)/,
		className: /^\.([\w\-\*]+)(\b|$)/,
		pseudo: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/,
		attrPresence: /^\[([\w]+)\]/,
		attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/
	},

	handlers: {
		// UTILITY FUNCTIONS
		// joins two collections
		concat: function(a, b) {
			for (var i = 0, node; node = b[i]; i++) a.push(node);
			return a;
		},

		// marks an array of nodes for counting
		mark: function(nodes) {
			for (var i = 0, node; node = nodes[i]; i++) node._counted = true;
			return nodes;
		},

		unmark: function(nodes) {
			for (var i = 0, node; node = nodes[i]; i++) node._counted = undefined;
			return nodes;
		},

		// mark each child node with its position (for nth calls)
		// "ofType" flag indicates whether we're indexing for nth-of-type
		// rather than nth-child
		index: function(parentNode, reverse, ofType) {
			parentNode._counted = true;
			if (reverse) {
				for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
					node = nodes[i];
					if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
        		}
			} else {
				for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
					if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
			}
		},

		// filters out duplicates and extends all nodes
		unique: function(nodes) {
			if (nodes.length == 0) return nodes;
			var results = [], n;
			for (var i = 0, l = nodes.length; i < l; i++)
				if (!(n = nodes[i])._counted) {
					n._counted = true;
					results.push(Element.extend(n));
				}
			return Selector.handlers.unmark(results);
		},

		// COMBINATOR FUNCTIONS
		descendant: function(nodes) {
			var h = Selector.handlers;
			for (var i = 0, results = [], node; node = nodes[i]; i++)
				h.concat(results, node.getElementsByTagName('*'));
			return results;
		},

		child: function(nodes) {
			var h = Selector.handlers;
			for (var i = 0, results = [], node; node = nodes[i]; i++) {
				for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
					if (child.nodeType == 1 && child.tagName != '!') results.push(child);
			}
			return results;
		},

		adjacent: function(nodes) {
			for (var i = 0, results = [], node; node = nodes[i]; i++) {
				var next = this.nextElementSibling(node);
				if (next) results.push(next);
			}
			return results;
		},

		laterSibling: function(nodes) {
			var h = Selector.handlers;
			for (var i = 0, results = [], node; node = nodes[i]; i++)
				h.concat(results, Element.nextSiblings(node));
			return results;
		},

		nextElementSibling: function(node) {
			while (node = node.nextSibling)
				if (node.nodeType == 1) return node;
			return null;
		},

		previousElementSibling: function(node) {
			while (node = node.previousSibling)
				if (node.nodeType == 1) return node;
			return null;
		},

		// TOKEN FUNCTIONS
		tagName: function(nodes, root, tagName, combinator) {
			tagName = tagName.toUpperCase();
			var results = [], h = Selector.handlers;
			if (nodes) {
				if (combinator) {
				// fastlane for ordinary descendant combinators
					if (combinator == "descendant") {
						for (var i = 0, node; node = nodes[i]; i++)
							h.concat(results, node.getElementsByTagName(tagName));
						return results;
					} else nodes = this[combinator](nodes);
					
					if (tagName == "*") return nodes;
				}
        
				for (var i = 0, node; node = nodes[i]; i++)
					if (node.tagName.toUpperCase() == tagName) results.push(node);
				return results;
			} else
				return root.getElementsByTagName(tagName);
		},

		id: function(nodes, root, id, combinator) {
			var targetNode = $(id), h = Selector.handlers;
			if (!nodes && root == document) return targetNode ? [targetNode] : [];
			
			if (nodes) {
				if (combinator) {
					if (combinator == 'child') {
						for (var i = 0, node; node = nodes[i]; i++)
							if (targetNode.parentNode == node) return [targetNode];
					} else if (combinator == 'descendant') {
						for (var i = 0, node; node = nodes[i]; i++)
							if (Element.descendantOf(targetNode, node)) return [targetNode];
					} else if (combinator == 'adjacent') {
						for (var i = 0, node; node = nodes[i]; i++)
							if (Selector.handlers.previousElementSibling(targetNode) == node)
						return [targetNode];
					} else nodes = h[combinator](nodes);
				}
				
				for (var i = 0, node; node = nodes[i]; i++)
					if (node == targetNode) return [targetNode];
					
				return [];
			}
			
			return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
		},

		className: function(nodes, root, className, combinator) {
			if (nodes && combinator) nodes = this[combinator](nodes);
				return Selector.handlers.byClassName(nodes, root, className);
		},

		byClassName: function(nodes, root, className) {
			if (!nodes) nodes = Selector.handlers.descendant([root]);
			var needle = ' ' + className + ' ';
			for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
				nodeClassName = node.className;
				if (nodeClassName.length == 0) continue;
				if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
					results.push(node);
			}
			
			return results;
		},

		attrPresence: function(nodes, root, attr) {
			var results = [];
			for (var i = 0, node; node = nodes[i]; i++)
				if (Element.hasAttribute(node, attr)) results.push(node);
			return results;
		},

		attr: function(nodes, root, attr, value, operator) {
			if (!nodes) nodes = root.getElementsByTagName("*");
			var handler = Selector.operators[operator], results = [];
			for (var i = 0, node; node = nodes[i]; i++) {
				var nodeValue = Element.readAttribute(node, attr);
				if (nodeValue === null) continue;
				if (handler(nodeValue, value)) results.push(node);
			}
			
			return results;
		},

		pseudo: function(nodes, name, value, root, combinator) {
			if (nodes && combinator) nodes = this[combinator](nodes);
			if (!nodes) nodes = root.getElementsByTagName("*");
			return Selector.pseudos[name](nodes, value, root);
		}
	},

	pseudos: {
		'first-child': function(nodes, value, root) {
			for (var i = 0, results = [], node; node = nodes[i]; i++) {
				if (Selector.handlers.previousElementSibling(node)) continue;
				results.push(node);
			}
			return results;
		},
		'last-child': function(nodes, value, root) {
			for (var i = 0, results = [], node; node = nodes[i]; i++) {
				if (Selector.handlers.nextElementSibling(node)) continue;
				results.push(node);
			}
			return results;
		},
		'only-child': function(nodes, value, root) {
			var h = Selector.handlers;
			for (var i = 0, results = [], node; node = nodes[i]; i++)
				if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
					results.push(node);
			return results;
		},
		'nth-child': function(nodes, formula, root) {
			return Selector.pseudos.nth(nodes, formula, root);
		},
		'nth-last-child':   function(nodes, formula, root) {
			return Selector.pseudos.nth(nodes, formula, root, true);
		},
		'nth-of-type':      function(nodes, formula, root) {
			return Selector.pseudos.nth(nodes, formula, root, false, true);
		},
		'nth-last-of-type': function(nodes, formula, root) {
			return Selector.pseudos.nth(nodes, formula, root, true, true);
		},
		'first-of-type':    function(nodes, formula, root) {
			return Selector.pseudos.nth(nodes, "1", root, false, true);
		},
		'last-of-type':     function(nodes, formula, root) {
			return Selector.pseudos.nth(nodes, "1", root, true, true);
		},
		'only-of-type':     function(nodes, formula, root) {
			var p = Selector.pseudos;
			return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
		},

		// handles the an+b logic
		getIndices: function(a, b, total) {
			if (a == 0) return b > 0 ? [b] : [];
			return $R(1, total).inject([], function(memo, i) {
				if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
				return memo;
			});
		},

		// handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
		nth: function(nodes, formula, root, reverse, ofType) {
			if (nodes.length == 0) return [];
			if (formula == 'even') formula = '2n+0';
			if (formula == 'odd')  formula = '2n+1';
			var h = Selector.handlers, results = [], indexed = [], m;
			h.mark(nodes);
			for (var i = 0, node; node = nodes[i]; i++) {
				if (!node.parentNode._counted) {
					h.index(node.parentNode, reverse, ofType);
					indexed.push(node.parentNode);
				}
			}
			
			if (formula.match(/^\d+$/)) { // just a number
				formula = Number(formula);
				for (var i = 0, node; node = nodes[i]; i++)
					if (node.nodeIndex == formula) results.push(node);
			} else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
				if (m[1] == "-") m[1] = -1;
				var a = m[1] ? Number(m[1]) : 1;
				var b = m[2] ? Number(m[2]) : 0;
				var indices = Selector.pseudos.getIndices(a, b, nodes.length);
				for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
					for (var j = 0; j < l; j++)
						if (node.nodeIndex == indices[j]) results.push(node);
				}
			}
			
			h.unmark(nodes);
			h.unmark(indexed);
			return results;
		},

		'empty': function(nodes, value, root) {
			for (var i = 0, results = [], node; node = nodes[i]; i++) {
				// IE treats comments as element nodes
				if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
					results.push(node);
			}
			return results;
		},

		'not': function(nodes, selector, root) {
			var h = Selector.handlers, selectorType, m;
			var exclusions = new Selector(selector).findElements(root);
			h.mark(exclusions);
			for (var i = 0, results = [], node; node = nodes[i]; i++)
				if (!node._counted) results.push(node);
					h.unmark(exclusions);
			return results;
		},

		'enabled': function(nodes, value, root) {
			for (var i = 0, results = [], node; node = nodes[i]; i++)
				if (!node.disabled) results.push(node);
			return results;
		},

		'disabled': function(nodes, value, root) {
			for (var i = 0, results = [], node; node = nodes[i]; i++)
				if (node.disabled) results.push(node);
			return results;
		},

		'checked': function(nodes, value, root) {
			for (var i = 0, results = [], node; node = nodes[i]; i++)
				if (node.checked) results.push(node);
			return results;
		}
	},

	operators: {
		'=': function(nv, v) { return nv == v; },
		'!=': function(nv, v) { return nv != v; },
		'^=': function(nv, v) { return nv.startsWith(v); },
		'$=': function(nv, v) { return nv.endsWith(v); },
		'*=': function(nv, v) { return nv.include(v); },
		'~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
		'|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
	},

	matchElements: function(elements, expression) {
		var matches = new Selector(expression).findElements(), h = Selector.handlers;
		h.mark(matches);
		for (var i = 0, results = [], element; element = elements[i]; i++)
			if (element._counted) results.push(element);
		h.unmark(matches);
		return results;
	},

	findElement: function(elements, expression, index) {
		if (typeof expression == 'number') {
			index = expression; expression = false;
		}
		return Selector.matchElements(elements, expression || '*')[index || 0];
	},

	findChildElements: function(element, expressions) {
		var exprs = expressions.join(','), expressions = [];
		exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
			expressions.push(m[1].strip());
		});
		var results = [], h = Selector.handlers;
		for (var i = 0, l = expressions.length, selector; i < l; i++) {
			selector = new Selector(expressions[i].strip());
			h.concat(results, selector.findElements(element));
		}
		return (l > 1) ? h.unique(results) : results;
	}
});

function $$() {
	return Selector.findChildElements(document, $A(arguments));
};
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > UI > Form > CheckBox, Radio
 */

if(typeof Prototype == "undefined")
	throw("empas.ui.form.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.UI)) Empas.UI = {};

/*============================================================================*
 * CheckBox
 *============================================================================*/
Empas.UI.Checkbox = Class.create();

Object.extend(Empas.UI.Checkbox,{
	_groups: {},		// ±×·ì
	
	/**
	 * ±×·ì µ¥ÀÌÅÍ »ý¼º
	 * @param {String} group ±×·ì¸í
	 */
	create: function(group) {
		if (!$D(this._groups[group])) 
			this._groups[group] = { els : [], checked : false};
	},

	/**
	 * ±×·ìº° Ã¼Å©¹Ú½º ¿¤¸®¸ÕÆ® Ãß°¡
	 * 
	 * @param {Object} instance Empas.UI.Checkbox Å¬·¡½º
	 * @param {Object} el Ã¼Å©¹Ú½º ¿¤¸®¸ÕÆ®
	 */	
	add: function(instance, el) {
		this._groups[instance.options.group].els.push(el);
	},
	
	/**
	 * ±×·ì¸íÀ¸·Î µ¥ÀÌÅÍ ±¸ÇÏ±â
	 * 
	 * @param {String} group ±×·ì¸í
	 * @return {Object} ±×·ì µ¥ÀÌÅÍ
	 */	
	_getGroup: function(group) {
		group = group || "default";		
		if (!$D(this._groups[group])) return null;
		
		return this._groups[group];
	},
	
	/**
	 * µî·ÏµÈ Ã¼Å©¹Ú½ºÁß ¼±ÅÃµÈ °ª ±¸ÇÏ±â
	 * 
	 * @param {String} group ±×·ì¸í
	 * @return {Object} ¼±ÅÃµÈ °ªÀ» ¹è¿­ ÇüÅÂ·Î ¹ÝÈ¯
	 */	
	values: function(group) {
		var groups = this._getGroup(group);
		if (!groups) return [];

		var result = [];
		groups.els.each(function (el) { 
			if (el.checked)
			{
				result.push(el.value);
			}
		});

		return result;
	},

	/**
	 * ±×·ìº° Åä±Û ÇÔ¼ö
	 * 
	 * @param {String} group ±×·ì¸í
	 * @param {Boolean} val »ç¿ëÀÚ ÁöÁ¤°ª.
	 */		
	toggle: function(group, val) {
		 var groups = this._getGroup(group);
		if (!groups) return;

		groups.checked = val || !groups.checked;

		groups.els.each(function (el) { el.checkAll(groups.checked) }); 
	},
	
	/**
	 * °ªÀ¸·Î Ã¼Å©
	 * 
	 * @param {String} val °ª
	 * @param {String} group ±×·ì¸í
	 */		
	checkByValue: function(val, group) {
		group = group || "default";
		
		if (!$D(this._groups[group])) return;
		
		var groups = this._groups[group];		
				
		groups.els.each(function (el) {
			if (el.value==val) el.checkAll(true);
		}); 
	}
});

Empas.UI.Checkbox.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(options) {
		this.savedImg = {};	// »ý¼ºµÈ ÀÌ¹ÌÁö °´Ã¼ ÀúÀå (Å° : Ã¼Å©¹Ú½º ¾ÆÀÌµð)
	
		this.options = Object.extend({
			group: "default",								// ±×·ì¸í
			checkbox: null,									// °³º° Ã¼Å©¹Ú½º ¾ÆÀÌµð·Î Àû¿ë½Ã (,·Î º¹¼ö ±¸ºÐ)			
			imgOn: 'http://img.empas.com/img/eprototypeui/form/check_on.png',				// Ã¼Å©»óÅÂ ÀÌ¹ÌÁö
			imgOff: 'http://img.empas.com/img/eprototypeui/form/check_off.png',				// ÀÏ¹Ý»óÅÂ ÀÌ¹ÌÁö
			imgOnOver: 'http://img.empas.com/img/eprototypeui/form/check_on_over.png',		// Ã¼Å©»óÅÂ ¸¶¿ì½º¿À¹ö ÀÌ¹ÌÁö
			imgOffOver: 'http://img.empas.com/img/eprototypeui/form/check_off_over.png',	// ÀÏ¹Ý»óÅÂ ¸¶¿ì½º¿À¹ö ÀÌ¹ÌÁö			
			overMode: true,									// ¸¶¿ì½º¿À¹ö ¸ðµå
			useHand: true,									// ¸¶¿ì½º ¿À¹ö½Ã ¼Õ¸ð¾ç Ä¿¼­ À¯¹«
			classApply: true								// Å¬·¡½º(EUICheckbox) ÀÏ°ý Àû¿ë À¯¹«
		}, options || {});
		
		options = this.options;
		
		// ±×·ì µ¥ÀÌÅÍ »ý¼º
		Empas.UI.Checkbox.create(options.group);
		
		// Å¬·¡½º ÀÏ°ý Àû¿ë
		if (options.checkbox==null && options.classApply) {
			document.getElementsByClassName("EUICheckbox").each(this._bindCheckbox.bind(this));
		} else {
			options.checkbox.split(",").each(function (elm) {
				this._bindCheckbox($(elm));
			}.bind(this));
		}

		// ¶óº§ ¹ÙÀÎµù 
		document.getElementsByClassName("EUICheckLabel").each(this._bindLabel.bind(this));

		// clear memory leak
		Event.observe(window, 'unload', this._cleanup.bind(this));
	},

	/**
	 * Ã¼Å©¹Ú½º °´Ã¼ ¹ÙÀÎµù
	 * 
	 * @param {Object} element ¹ÙÀÎµùÇÒ °´Ã¼
	 */	
	_bindCheckbox: function(element) {
		// Áßº¹ ¹ÙÀÎµù Ã¼Å©
		if ($D(element._created)) return;
		element._created = true;
		
		// ÀÌ¹ÌÁö »ý¼º
		var img = $C("img").setStyle( { "vertical-align":"top" });
		if (this.options.useHand) {
			img.setStyle({ "cursor": "pointer" });
		}

		// Ã¼Å©ÇÔ¼ö ¿¬°á
		element.parent = this;
		Object.extend(element, {
			check: function(val) {
				this.checked = val;
				this.parent._clickImg(img, true);
			},
			checkAll: function(val) {
				this.checked = val;
				this.parent._clickImg(img, true, false);
			},
			setDisable: function(val) {
				this.parent._setDisable(img, val);
			}
		});
		
		// ÀÌ¹ÌÁö onclick ÀÌº¥Æ® ¼³Á¤
		img.observe('click', this._clickImg.bind(this, img));

		// ÀÌ¹ÌÁö mouseover, mouseout ÀÌº¥Æ® ¼³Á¤
		if (this.options.overMode) {
			img.observe('mouseover', this._mouseImg.bind(this, img, 'over'));
			img.observe('mouseout', this._mouseImg.bind(this, img, 'out'));
		}
		
		// Ã¼Å©¹Ú½º °´Ã¼ ¿¬°á
		img.checkbox = element;
		
		// on,off »óÅÂ¿¡ µû¶ó ±×¸®±â 
		this._draw(img);

		if ($ATTR(element, "disabled")) {
			this._setDisable(img, true);
		}
			
		// ¶óº§°ú ¿¬°áÀ» À§ÇØ ÀúÀå 					
		if (element.id)
			this.savedImg[element.id] = img;

		// ÀÌ¹ÌÁö »ðÀÔÇÏ°í ±âÁ¸ Ã¼Å©¹Ú½º ¼û±â±â
		element.parentNode.insertBefore(img, element);
		element.hide();
		
		// ±×·ìº° Ã¼Å©¹Ú½º ¿¤¸®¸ÕÆ® Ãß°¡
		Empas.UI.Checkbox.add(this, element);
	},

	/**
	 * ºñÈ°¼³È­ ¿©ºÎ ¼³Á¤
	 * 
	 * @param {Object} img ÀÌ¹ÌÁö °´Ã¼
	 * @param {Boolean} disable ¼³Á¤°ª
	 */
	_setDisable: function(img, disable) {
		img.setOpacity(disable ? 0.5:1.0);
		img.checkbox.disabled = disable;
	},
	
	/**
	 * ¶óº§ ¹ÙÀÎµù
	 * 
	 * @param {Object} element ¹ÙÀÎµùÇÒ ¶óº§ °´Ã¼
	 */
	_bindLabel: function(element)
	{
		element = $(element);
		
		// Ã¼Å©¹Ú½º ¹ÙÀÎµùÀÌ µÈ ¶óº§¸¸ ¹ÙÀÎµù
		var img = this.savedImg[element.readAttribute("for")];
		if (!img) return;
		
		// Áßº¹ ¹ÙÀÎµù Ã¼Å©
		if ($D(element._created)) return;
		element._created = true;
		
		if (this.options.useHand) 
			element.setStyle({ "cursor": "pointer" });
		
		element.observe('click', this._clickLabel.bindAsEventListener(this));
		
		// ¶óº§ mouseover, mouseout ÀÌº¥Æ® ¼³Á¤
		if (this.options.overMode) {
			element.observe('mouseover', this._mouseImg.bind(this, img, 'over'));
			element.observe('mouseout', this._mouseImg.bind(this, img, 'out'));
		}
		
	},

	/**
	 * ÀÌ¹ÌÁö click ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} img ÀÌº¥Æ® ¹ß»ýÇÑ ÀÌ¹ÌÁö °´Ã¼ 
	 * @param {Object} notupdate Ã¼Å©°ª º¯°æÇÏÁö ¾ÊÀ»Áö À¯¹«. ±âº»°ª false
	 */
	_clickImg: function(img, notupdate) {
		if (img.checkbox.disabled) return;
		
		notupdate = $T(notupdate)=='boolean' ? notupdate:false;
		
		if (!$ATTR(img.checkbox, "disabled")) {
			if (!notupdate) img.checkbox.checked = !img.checkbox.checked;
			this._draw(img);

			// toggleÀÏ °æ¿ì onclick ÀÌº¥Æ® »ç¿ë ¾ÈÇÔ
			if (!$D(arguments[2]) && img.checkbox.onclick) img.checkbox.onclick();
		}
	},
	
	/**
	 * ÀÌ¹ÌÁö mouseover, mouseout ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} img ÀÌº¥Æ® ¹ß»ýÇÑ ÀÌ¹ÌÁö °´Ã¼ 
	 * @param {String} kind ÀÌº¥Æ® Á¾·ù. (over|out)
	 */
	_mouseImg: function(img, kind) {
		if (img.checkbox.disabled) return;
		
		if (kind=="over")
			img.src = img.checkbox.checked ? this.options.imgOnOver:this.options.imgOffOver;
		else
			this._draw(img);
	},
	
	/**
	 * ¶óº§ click ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} e ÀÌº¥Æ® ¹ß»ý °´Ã¼
	 */
	_clickLabel: function(e) {
		Event.stop(e);
		this._clickImg(this.savedImg[Event.element(e).readAttribute("for")]);
	},	
	
	_draw: function(img) {
		img.src = img.checkbox.checked ? this.options.imgOn:this.options.imgOff;
	},

	/**
	 * ¸Þ¸ð¸®¸¯ Á¦°Å¸¦ À§ÇÑ Ã³¸® 
	 */
	_cleanup: function() {
		for (var elm_id in this.savedImg) {
			this.savedImg[elm_id].checkbox = null;
			this.savedImg[elm_id].options = null;
			this.savedImg[elm_id] = null;
		}
		this.savedImg = null;		
	}
};

/*============================================================================*
 * Radio
 *============================================================================*/
Empas.UI.Radio = Class.create();

Empas.UI.Radio.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} group Àû¿ëÇÒ radio °´Ã¼ÀÇ name°ª
	 * @param {Object} options ¼³Á¤°ª
	 * @constructor
	 */
	initialize: function(group, options) {
		// ³»ºÎº¯¼ö ÃÊ±âÈ­
		this._init();
		
		// ¿É¼Ç
		this._options = Object.extend({
			imgOn: 'http://img.empas.com/img/eprototypeui/form/radio_on.png',
			imgOff: 'http://img.empas.com/img/eprototypeui/form/radio_off.png',
			imgOnOver: 'http://img.empas.com/img/eprototypeui/form/radio_on_over.png',
			imgOffOver: 'http://img.empas.com/img/eprototypeui/form/radio_off_over.png',
			overMode: true,
			useHand: true
		}, options || {});
		
		// ÁöÁ¤µÈ ±×·ì ÀÌ¸§À¸·Î ¹ÙÀÎµù
		$A(document.getElementsByName(group)).each(this._bindRadio.bind(this));
		
		// ¶óº§ ¹ÙÀÎµù
		document.getElementsByClassName("EUIRadioLabel").each(this._bindLabel.bind(this));

		// for memory leak
		Event.observe(window, 'unload', this._cleanup.bind(this), false);
	},

	/**
	 * ºñÈ°¼³È­ ¿©ºÎ ¼³Á¤
	 * 
	 * @param {Boolean} disable ¼³Á¤°ª
	 */
	setDisable: function(disable) {
		$H(this.savedImg).each(function (pair) {
			pair.value.setOpacity(disable ? 0.5:1.0);
		});
		
		this._disabled = disable;
	},
	
	/**
	 * ³»ºÎ º¯¼ö ÃÊ±âÈ­
	 */
	_init: function() {
		this.savedImg =  {};
		this.savedElement = [];
		this.selectedImg = null;
		this._disabled = false;
	},
	
	/**
	 * ¶óµð¿À °´Ã¼ ¹ÙÀÎµù
	 * 
	 * @param {Object} element ¹ÙÀÎµùÇÒ °´Ã¼
	 */
	_bindRadio: function(element) {
		// Áßº¹ Ã¼Å©
		if ($D(element._created)) {
			return;
		} else {
			element._created = true;
		}
		
		// ¶óµð¿À °´Ã¼ ÀúÀå
		this.savedElement.push(element);

		// ÀÌ¹ÌÁö »ý¼º	
		var img = $C("img").setStyle({ "vertical-align":"top" });
		if (this._options.useHand) {
			img.setStyle({ "cursor": "pointer" });
		}
		
		// Ã¼Å© ÇÔ¼ö ¿¬°á		
		element.parent = this;
		Object.extend(element, {
			check: function() {
				this.parent._clickImg(img);
			}
		});
		
		// ¼±ÅÃµÈ ÀÌ¹ÌÁö °´Ã¼
		if (element.checked) {
			this.selectedImg = img;
		}
		
		// ÀÌ¹ÌÁö onclick ÀÌº¥Æ® 
		Event.observe(element, 'click', this._clickImg.bind(this, img));
		
		// ÀÌ¹ÌÁö onclick ÀÌº¥Æ® 
		img.observe('click', this._clickImg.bind(this, img));

		// ÀÌ¹ÌÁö mouseover, mouseout ÀÌº¥Æ® ¼³Á¤
		if (this._options.overMode) {
			img.observe('mouseover', this._mouseImg.bind(this, img, 'over'));
			img.observe('mouseout', this._mouseImg.bind(this, img, 'out'));
		}

		// ÀÌ¹ÌÁö¿¡ ¶óµð¿À °´Ã¼ ¿¬°á 
		img.radio = element;
		this._draw(img);

		// ¶óº§°ú ¿¬°áÀ» À§ÇØ ÀÌ¹ÌÁö ÀúÀå 					
		if (element.id) {
			this.savedImg[element.id] = img;			
		}

		// ÀÌ¹ÌÁö »ðÀÔ
		element.parentNode.insertBefore(img, element);
		element.hide();
	},

	/**
	 * ¶óº§ ¹ÙÀÎµù
	 * 
	 * @param {Object} element ¹ÙÀÎµùÇÒ °´Ã¼
	 */
	_bindLabel: function(element)
	{
		// Áßº¹ Ã¼Å©
		if ($D(element._created)) {
			return;
		} 
				
		var img = this.savedImg[element.readAttribute("for")];		
		if ($D(img)) {
			if (this._options.useHand) 
				$(element).setStyle({ "cursor": "pointer"});	
			
			// ¶óµð¿À¿¡ ÀÌ¹ÌÁö ÀúÀåÇÏ°í click ÀÌº¥Æ® ¿¬°á
			element._created = true;
			element.img = img;
			
			Event.observe(element, 'click', this._clickLabel.bindAsEventListener(this));
			
			if (this._options.overMode) {
				Event.observe(element, 'mouseover', this._mouseImg.bind(this, img, 'over'));
				Event.observe(element, 'mouseout', this._mouseImg.bind(this, img, 'out'));
			}
		}
	},
	
	/**
	 * ÀÌ¹ÌÁö click ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} img ¹ß»ýÇÑ ÀÌ¹ÌÁö
	 */
	_clickImg: function(img) {
		if (!this._disabled) {
			img.radio.checked = true;
			this._draw(img);

			// ÀÌÀü ¼±ÅÃµÈ ¶óµð¿À ÇØÁ¦
			if (this.selectedImg!=null && this.selectedImg!=img) {
				this._draw(this.selectedImg);
			}
		
			this.selectedImg = img;
			if (img.radio.onclick) img.radio.onclick();
		}
	},
	
	/**
	 * ÀÌ¹ÌÁö mouseover, mouseout ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} img ÀÌº¥Æ® ¹ß»ýÇÑ ÀÌ¹ÌÁö °´Ã¼ 
	 * @param {String} kind ÀÌº¥Æ® Á¾·ù. (over|out)
	 */
	_mouseImg: function(img, kind) {
		if (this._disabled) return;
		
		if (kind=="over")
			img.src = img.radio.checked ? this._options.imgOnOver:this._options.imgOffOver;
		else
			this._draw(img);
	},	
	
	/**
	 * ¶óº§ click ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} e ÀÌº¥Æ® ¹ß»ý °´Ã¼
	 */
	_clickLabel: function(e) {
		Event.stop(e);
		this._clickImg(Event.element(e).img);
	},	
	
	_draw: function(img) {		
		img.src = img.radio.checked ? this._options.imgOn:this._options.imgOff;		
	},
	
	/**
	 * °ªÀ¸·Î Ã¼Å©
	 * 
	 * @param {String} val °ª
	 * @param {String} group ±×·ì¸í
	 */		
	checkByValue: function(val) {
		this.savedElement.each(function(el) {
			if (el.value==val) el.check();
		}); 
	},
	
	/**
	 * ¸Þ¸ð¸®¸¯ Á¦°Å¸¦ À§ÇÑ Ã³¸®
	 */
	_cleanup: function() {
		this.selectedImg = null;
		
		for (var elm_id in this.savedImg) {
			this.savedImg[elm_id].radio = null;
			this.savedImg[elm_id].options = null;
			this.savedImg[elm_id] = null;
		}
		this.savedImg = null;
				
		this.savedElement.each(function(obj) {
			obj.parent = null;			
			obj.img = null;			
			obj.check = null;
		});
		
		this.savedElement = null;
	}
};
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > UI > SelectBox
 */

if(typeof Prototype == "undefined")
	throw("empas.ui.selectbox.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.UI)) Empas.UI = {};

/*============================================================================*
 * Select
 *============================================================================*/
Empas.UI.SelectBox = Class.create();

Object.extend(Empas.UI.SelectBox,{
	_instances: [],
	
	/**
	 * ÀÎ½ºÅÏ½º Ãß°¡
	 * 
	 * @param {Object} obj Ãß°¡ÇÒ Empas.UI.SelectBox °´Ã¼
	 */
	add: function(obj) {
		this._instances.push(obj);
	},

	/**
	 * µ¿Àû º¯°æ¿¡ µû¸¥ ÀüÃ¼ ¼¿·ºÆ®¹Ú½º À§Ä¡ ÀÌµ¿
	 * 
	 * @param {Object} noobj Á¦¿ÜÇÒ Empas.UI.SelectBox °´Ã¼
	 */	
	redraw: function(noobj) {
		this._instances.each(function (obj, idx) { 
			if (idx>0 && noobj._options.id != obj._options.id) obj._movePosition();
		}); 
	}
});

Empas.UI.SelectBox.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} element ¼¿·ºÆ® ¿¤¸®¸ÕÆ® ID
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(el, options) {
		// ¿É¼Ç 
		this._options = Object.extend({
			id : el,
			width: null,
			fontSize: 12,									// ÆùÆ® Å©±â			
			borderColor: "#A0A0A0",							// Å×µÎ¸®»ö
			titleTextColor: "#ff6600",						// Å¸ÀÌÆ² ±ÛÀÚ»ö. Å¸ÀÌÆ² : <select>
			titleBgColor: "#fff",							// Å¸ÀÌÆ² ¹è°æ»ö
			optionTextColor: "#000",						// ¿É¼Ç ±ÛÀÚ»ö. ¿É¼Ç : <option>
			optionBgColor: "#fff",							// ¿É¼Ç ¹è°æ»ö
			overOptionTextColor: "#fff",					// ¿É¼Ç ¸¶¿ì½º ¿À¹ö½Ã ±ÛÀÚ»ö
			overOptionBgColor: "#3B99FE",					// ¿É¼Ç ¸¶¿ì½º ¿À¹ö½Ã ¹è°æ»ö
			BtnOff: "http://img.empas.com/img/eprototypeui/selectbox_off.gif",	// ¹öÆ° ÀÌ¹ÌÁö
			BtnOn: "http://img.empas.com/img/eprototypeui/selectbox_on.gif", 	// ¸¶¿ì½º ¿À¹ö½Ã ¹öÆ° ÀÌ¹ÌÁö
			cursor: "default",								// Ä¿¼­
			zIndex: 1000,									// z-index
			afterChange: null,								// º¯°æÈÄ È£ÃâÇÒ ÇÔ¼ö
			strictDTD: false								// Strict DTD ¿©ºÎ. ±âº»°ª false(ÄõÅ© ¸ðµå)
		}, options || {});
		
		var options = this._options;

		if (!Prototype.Browser.IE) options.strictDTD = false;

		// Select °´Ã¼
		this.Select = el = $(el);
		
		// ÀÌÀü ¸¶¿ì½º over »óÅÂÀÇ LI °´Ã¼
		this.OverLI = null;
		
		// ¼±ÅÃµÈ LI °´Ã¼ 
		this.SelectedLI = null;
		
		// Select À§Ä¡ ±¸ÇÏ±â
		var Pos = Position.positionedOffset(el);
		
		// SelectÀÇ °¡·Î, ¼¼·Î ±¸ÇÏ±â 
		options.width = options.width || el.getWidth();
		
		// ¾Æ·¡ ÇüÅÂÀÇ DIV ¸¸µé±â
		//	<div class="EmpasUISelect">
		//		<div class="EmpasUISelectTitle">Å×½ºÆ®</div>
		//		<ul class="EmpasUISelectUL">
		//			<li class="EmpasUISelectLI">Å×½ºÆ® 1</li>
		//			<li class="EmpasUISelectLI">Å×½ºÆ® 2</li>
		//		</ul>
		//	</div>
		
		this._divs = {};
		var divs = this._divs;
		
		// ****************************************************************
		// 1. EmpasUISelect
		// ****************************************************************		
		divs.EmpasUISelect = $C("div").setStyle({
			position : "absolute",
			width: options.width + "px",
			left: Pos[0] + "px",
			top: Pos[1] + "px",
			cursor: options.cursor,
			zIndex: options.zIndex
		});

		// ¼¿·ºÆ®¿¡ ÇÔ¼ö ¿¬°á
		this.Select.parent = this;
		Object.extend(this.Select, {
			clear: function() {
				this.parent._actionSelect('clear');
			},

			add: function(text,value) {
				this.parent._actionSelect('add', text, value);
			},

			redraw: function() {
				this.parent._actionSelect('redraw');
			},
			
			setDisabled: function(disable) {
				this.parent._actionSelect('setDisabled', disable);
			}
		});

		// ****************************************************************
		// 2. EmpasUISelectTitle
		// ****************************************************************	
		options.padding = (!options.strictDTD && Prototype.Browser.IE) ? 4:3;
		options.posBtn = (!options.strictDTD && Prototype.Browser.IE) ? 19:11;
			
		divs.EmpasUISelectTitle = $C("div").setStyle({
			color: options.titleTextColor,
			background: options.titleBgColor + " url('" + options.BtnOff + "') no-repeat " + (options.width-options.posBtn) + "px center",
			padding: options.padding+"px 2px 2px 4px",
			border: "1px solid " + options.borderColor,
			width: options.width + "px",
			fontSize: options.fontSize + "px"
		});
		divs.EmpasUISelectTitle._EUISelect = true;
		
		// ÀÌº¥Æ® ¿¬°á
		Event.observe(divs.EmpasUISelectTitle, "mouseover", this._overTitle.bind(this));
		Event.observe(divs.EmpasUISelectTitle, "mouseout", this._outTitle.bind(this));		
		Event.observe(divs.EmpasUISelectTitle, "click", this._clickTitle.bindAsEventListener(this));
		
		divs.EmpasUISelect.appendChild(divs.EmpasUISelectTitle);
		
		// ****************************************************************
		// 3. EmpasUISelectUL
		// ****************************************************************		
		options.AddWidth = !options.strictDTD && !Prototype.Browser.IE ? 6:0;
		options.IE7Width = options.strictDTD && Prototype.Browser.IE7 ? 6:0;

		divs.EmpasUISelectUL = $C("ul").setStyle({
			clear: "both",
			display: "none",
			"list-style": "none",
			margin: "0",
			padding: "0",
			width: (options.width + options.AddWidth + options.IE7Width) + 'px',
			"border-left": "1px solid " + options.borderColor,
			"border-right": "1px solid " + options.borderColor,
			"border-bottom": "1px solid " + options.borderColor
		});
		
		// ****************************************************************
		// 4. EmpasUISelectLI
		// ****************************************************************
		this.LiStyle = {
			margin: "0",
			background: options.optionBgColor,
			color: options.optionTextColor,
			"list-style": "none",
			padding: "5px 0 2px 4px",
			fontSize: options.fontSize + "px"
		};
		
		if (Prototype.Browser.IE)
			this.LiStyle.width = options.strictDTD ? (options.width + options.AddWidth + 2)+"px" : "100%";
		
		// option °ªÀ¸·Î LI »ý¼º 
		this._changeOptionToLI();
		
		if ($ATTR(this.Select, "disabled"))
			this._setDisable(true);

		// ****************************************************************
		// Select¿Í ¹Ù²ãÄ¡±â
		// ****************************************************************
		options.BlankAdd = options.strictDTD ? 6:0;
		
		divs.Blank = $C('input').setStyle({
			width: (options.width + options.AddWidth + options.BlankAdd) + "px",
			height: 0,
			border: 0
		});
		el.parentNode.insertBefore(divs.Blank, el);

		el.parentNode.insertBefore(divs.EmpasUISelect, el);
		el.hide();

		// Document Å¬¸¯ ÀÌº¥Æ® 
		Event.observe(document, "mousedown", this._mdownDocument.bind(this));
		
		// for memory leak
		Event.observe(window, "unload", this._cleanup.bind(this));
		
		Empas.UI.SelectBox.add(this);
	},
	
	/**
	 * ºñÈ°¼³È­ ¿©ºÎ ¼³Á¤
	 * 
	 * @param {Boolean} disable ¼³Á¤°ª
	 */
	_setDisable: function(disable) {
		this._divs.EmpasUISelectTitle.setOpacity(disable ? 0.5:1.0);
		this._disabled = disable;
	},
		
	/**
	 * <option> => LI »ý¼º
	 */
	_changeOptionToLI: function() {
		var divs = this._divs;

		divs.EmpasUISelectLI = [];

		$A(this.Select.getElementsByTagName("option")).each(function (el, idx) {
			divs.EmpasUISelectLI[idx] = $C("li").setStyle(this.LiStyle);			
			divs.EmpasUISelectLI[idx]._EUISelect = true;
			divs.EmpasUISelectLI[idx].val = el.value;
			divs.EmpasUISelectLI[idx].innerHTML = el.text;
			
			// ¸¶¿ì½º ÀÌº¥Æ® ¼³Á¤
			Event.observe(divs.EmpasUISelectLI[idx], "mouseover", 
							this._overLI.bind(this, divs.EmpasUISelectLI[idx]));
							
			Event.observe(divs.EmpasUISelectLI[idx], "click", this._clickLI.bind(this, idx));
			
			divs.EmpasUISelectUL.appendChild(divs.EmpasUISelectLI[idx]);
			
			// ¼±ÅÃµÈ °æ¿ì
			if ($ATTR(el,"selected")) {
				this._selectLI(idx);
			}
		}.bind(this));
		
		// ±âº» ¼±ÅÃµÈ °ªÀÌ ¾øÀ» °æ¿ì
		if (!this.SelectedLI)
			this._selectLI(0);
		
		divs.EmpasUISelect.appendChild(divs.EmpasUISelectUL);	
	},

	/**
	 * ÀÎµ¦½º·Î ¼±ÅÃµÈ LI ¼³Á¤
	 * 
	 * @param {Number} idx EmpasUISelectLI ¹è¿­ ÀÎµ¦½º
	 */	
	_selectLI: function(idx) {
		if (!$D(this._divs.EmpasUISelectLI[idx])) {
			this._divs.EmpasUISelectTitle.innerHTML = "&nbsp;";
			return;
		}

		this._divs.EmpasUISelectTitle.innerHTML = this._divs.EmpasUISelectLI[idx].innerHTML;
		this.SelectedLI = this._divs.EmpasUISelectLI[idx];
	},
	
	/**
	 * UL ¿µ¿ª ¼û±â±â
	 */
	_hideUL: function() {
		this._divs.EmpasUISelectUL.hide();
		this._outTitle();
	},
	
	/**
	 * º»¹® ¿µ¿ª ¸¶¿ì½º Ã¼Å©
	 * 
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 */		
	_mdownDocument: function(e)
	{
		// ÀÌº¥Æ® ¹ß»ýÇÑ °÷ÀÌ »ý¼ºÇÑ LI°¡ ¾Æ´Ò °æ¿ì
		if (!this._disabled && !$D(Event.element(e)._EUISelect) && $D(this._divs.EmpasUISelectUL))
			this._hideUL();
	},
	
	/**
	 * Å¸ÀÌÆ² ¿µ¿ª ¸¶¿ì½º ¿À¹ö Ã³¸®
	 * 
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 */		
	_overTitle: function(e) {
		if (this._disabled) return;

		this._divs.EmpasUISelectTitle.setStyle({
			backgroundImage: "url('" + this._options.BtnOn + "')"
		});
	},
	
	/**
	 * Å¸ÀÌÆ² ¿µ¿ª ¸¶¿ì½º ¾Æ¿ô Ã³¸®
	 * 
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 */
	_outTitle: function(e) {
		if (!this._disabled && !this._divs.EmpasUISelectUL.visible()) {
			this._divs.EmpasUISelectTitle.setStyle({
				backgroundImage: "url('" + this._options.BtnOff + "')"			
			});
		}
	},
	
	/**
	 * Å¸ÀÌÆ² ¿µ¿ª click ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 */
	_clickTitle: function(e)
	{
		if (!this._disabled && $D(this._divs.EmpasUISelectUL)) {
			Event.stop(e);
			this._divs.EmpasUISelectUL.toggle();
			this._overLI(this.SelectedLI);
		}
	},
	
	/**
	 * LI(¾ÆÀÌÅÛ) mouseover ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} LI ¹ß»ý LI °´Ã¼
	 */ 
	_overLI: function(LI)
	{
		if (this.OverLI==LI) return;
		
		// ÀÌÀü °­Á¶µÈ LI ÃÊ±âÈ­
		if (this.OverLI!=null) {
			$(this.OverLI).setStyle({
				background: this._options.optionBgColor,
				color: this._options.optionTextColor
			});	
		}
		
		// ÇöÀç LI °­Á¶
		$(LI).setStyle({
			background: this._options.overOptionBgColor,
			color: this._options.overOptionTextColor
		});
		
		this.OverLI = LI;
	},
	
	/**
	 * LI(¾ÆÀÌÅÛ) ¸¶¿ì½º Å¬¸¯ ÀÌº¥Æ®
	 * 
	 * @param {Number} idx EmpasUISelectLI ¹è¿­ ÀÎµ¦½º
	 */
	_clickLI: function(idx)
	{
		this._selectLI(idx);
		this._hideUL();
		
		// ½ÇÁ¦ SELECT °ª º¯°æ
		this.Select.selectedIndex = idx;
		
		if (this._options.afterChange) 
			this._options.afterChange(this.Select.value);
	},
	
	/**
	 * ¼¿·ºÆ®¿¡ ¿¬°áµÈ ÇÔ¼ö Ã³¸®
	 * 
	 * @param {String} cmd ¸í·É Á¾·ù
	 */		
	_actionSelect: function(cmd) {
		var divs = this._divs;
		
		switch(cmd) {
			case "add": // Ãß°¡
				this.Select.options[this.Select.options.length] = new Option(arguments[1], arguments[2]);
			break;
			
			case "clear": // ÃÊ±âÈ­
				if (divs.EmpasUISelectLI.size()>0) {
					// ¿¬°áµÈ ÀÌ¸àÆ® Á¦°Å
					divs.EmpasUISelectLI.each(function(obj, idx) {
						Event.stopObserving(obj, 'mouseover', this._overLI.bind(this, obj));
						Event.stopObserving(obj, 'click', this._clickLI.bind(idx));
						obj.remove();
					}.bind(this));
					divs.EmpasUISelectLI.clear();
				
					divs.EmpasUISelectUL.setStyle({
						border:'none'
					});
						
					divs.EmpasUISelectTitle.innerHTML = '';
					
					this.OverLI = this.SelectedLI = null;
					
					// ¼¿¸¯Æ®ÀÇ ¿É¼Ç°ª ÃÊ±âÈ­
					while(this.Select.options.length>0) {
						this.Select.remove(0);
					}
				}
			break;

			case "redraw":
				// UL ½ºÅ¸ÀÏ º¹±¸
				divs.EmpasUISelectUL.setStyle({
					"border-left": "1px solid " + this._options.borderColor,
					"border-right": "1px solid " + this._options.borderColor,
					"border-bottom": "1px solid " + this._options.borderColor
				});
				
				this._resize();
				this._changeOptionToLI();				
			break;

			case "setDisabled":
				this._setDisable(arguments[1]);
			break;
		}
	},
	
	/**
	 * ¹®ÀÚ¿­¿¡¼­ ÇÑ±Û(2bytes) ±æÀÌ¿Í ±×ÀÌ¿Ü ±æÀÌ ¹ÝÈ¯
	 *
	 * @param {String} str ¹®ÀÚ¿­
	 * @return {Object} han_len : ÇÑ±Û ±æÀÌ, etc_len : ³ª¸ÓÁö ±æÀÌ
	 */
	_getLenInfo: function(str) {
		var len = str.length; 
    	var han = 0; 
     
	    for(var i=0;i<len;i++) { 
    	    if(str.charCodeAt(i)>128) han++; 
	    } 

    	return {han_len:han, etc_len:len-han}; 
	},
	
	/**
	 * ³»¿ë º¯°æ¿¡ µû¸¥ ¸®»çÀÌÂ¡
	 */	
	_resize: function() {
		var divs = this._divs;
		var options = this._options;

		// IEÀÎ °æ¿ì ¼¿·ºÆ®ÀÇ Å©±â°¡ º¯°æµÇÁö ¾ÊÀ½ => ¹®ÀÚ¿­·Î °è»ê
		if (Prototype.Browser.IE) {
			var Width = 0;
			$A(this.Select.getElementsByTagName("option")).each(function (el, idx) {
				var info = this._getLenInfo(el.text);
				Width = Math.max(Width, 35 + (info.han_len*12 + info.etc_len*5));
			}.bind(this));
		} else {
			var Width = this.Select.getWidth();			
		}
		
		divs.Blank.setStyle({ width : (Width + options.AddWidth + options.BlankAdd) + "px" });		
		divs.EmpasUISelect.setStyle({ width : Width + "px" });
		divs.EmpasUISelectTitle.setStyle({
			width : Width + "px",
			background: options.titleBgColor + " url('" + options.BtnOff + "') no-repeat " + (Width-options.posBtn) + "px center"
		});
		
		divs.EmpasUISelectUL.setStyle({ width : (Width + options.AddWidth + options.IE7Width) + "px" });
		
		if (Prototype.Browser.IE)
			this.LiStyle.width = options.strictDTD ? (Width + options.AddWidth + 2)+"px" : "100%";
			
		// ÀüÃ¼ ´Ù½Ã ±×¸®±â
		Empas.UI.SelectBox.redraw(this);
	},
	
	/**
	 * ºí·©Å© ¿µ¿ªÀ¸·Î À§Ä¡ ÀÌµ¿½ÃÅ°±â
	 */
	_movePosition: function() {
		var divs = this._divs;
		var Pos = Position.positionedOffset(divs.Blank);		

		divs.EmpasUISelect.setStyle({ left : Pos[0] + "px" });
	},
	
	/**
	 * ¸Þ¸ð¸® ÇØÁ¦
	 */
	_cleanup: function() {
		// ¼¿¸¯Æ® ÃÊ±âÈ­
		this.Select.parent = null;
		this.Select.clear = null;
		this.Select.add = null;
		this.Select.redraw = null;
		this.Select = null;
		
		// »óÅÂÀúÀå º¯¼ö ÃÊ±âÈ­
		this.OverLI = null;
		this.SelectedLI = null;	
	}
};
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > UI > View > Tab, Rotate, Toggle, Scroller, Floating
 */

if(typeof Prototype == "undefined")
	throw("empas.ui.view.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.UI)) Empas.UI = {};

/*============================================================================*
 * ViewItem
 *============================================================================*/
Empas.UI.ViewItem = Class.create();

Empas.UI.ViewItem.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} tab_id ÅÇ°ú ¿¬°áÇÒ ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {Object} request Ajax ¿äÃ» ¿É¼Ç
	 * @constructor
	 */
	initialize: function(id, request) {
		this._el = $(id);
		this.setRequest(request);
	},
	
	/**
	 * Ajax ¿äÃ» ¿É¼Ç ¼³Á¤
	 * 
	 * @param {Object} request ¿É¼Ç
	 */
	setRequest: function(request) {
		this._request = Object.extend({
			url: '',			// Ajax È£Ãâ URL
			lazyLoading: false,	// Áö¿¬ ·Îµù À¯¹«
			isLoad: false		// ·Îµù ¿Ï·á À¯¹«
		}, request || {});
		
		if (this._request.lazyLoading) 
			Event.observe(window, "load", this._load.bind(this));
	},
	
	/**
	 * ¼û±â±â
	 */
	hide: function() {
		this._el.hide();
	},

	/**
	 * º¸ÀÌ±â
	 */	
	show: function() {
		this._el.show();
		this._load();
	},
	
	/**
	 * Ajax ¼³Á¤ÀÌ µÈ °æ¿ì ¿äÃ»ÇØ ¿¤¸®¸ÕÆ® °»½ÅÇÏ±â
	 */
	_load: function() {
		if (this._request.url!='' && !this._request.isLoad) {
			if(!$D(Ajax))
				throw("Empas.UI.View.js requires including Prototype.Ajax library");
			
			this._request.isLoad = true;
			new Empas.Ajax.Updater(this._el, this._request.url);
		}
	}
};

/*============================================================================*
 * Tab
 *============================================================================*/
Empas.UI.Tab = Class.create();

Empas.UI.Tab.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(options) {
		this._options = Object.extend({
			changeAction: true,		// ÅÇ º¯°æ½Ã ¾×¼Ç ¿©ºÎ
			clickMode: false,		// Å¬¸¯ ¸ðµå(Å¬¸¯ÇØ¾ß ÅÇ º¯°æ). ±âº»°ªÀº ¸¶¿ì½º ¿À¹ö½Ã º¯°æ
			afterChange: null,		// º¯°æÈÄ ½ÇÇàµÉ ÇÔ¼ö
			noActive: false			// ÃÊ±â ÅÇ ºñÈ°¼ºÈ­ ¿©ºÎ
		}, options || {});
		
		this._TabItems = {};
		this._selectedTab = null;
	},
	
	/**
	 * ·çÆ®ÅÇ °´Ã¼ ¹ÙÀÎµù
	 * 
	 * @param {Empas.UI.View.TabItem} ÅÇ ¾ÆÀÌÅÛ °´Ã¼
	 */	
	add: function(TabItem) {
		if ($D(TabItem.el)) {
			this._TabItems[TabItem.id] = TabItem;
		}
	},	
	
	/**
	 * ÅÇ¿¡ ¸¶¿ì½º ¿À¹ö ÀÌº¥Æ® ¿¬°á
	 * 
	 * @param {String} focusTabId ÃÊ±â º¸¿©Áú ÅÇ ¾ÆÀÌµð (±âº»°ª : Ã¹¹øÂ° ÅÇ)
	 */
	start: function(focusTabId) {
		var initTabId = focusTabId || null;
		var options = this._options;
		var eventKey = options.clickMode ? 'click':'mouseover';
		
		// ÅÇ ¾ÆÀÌÅÛº° ÀÌº¥Æ® ¿¬°á
		$H(this._TabItems).each(function(tab) {
			Event.observe(tab.key, eventKey, this._onChangeTab.bindAsEventListener(this, tab.value));
			if (initTabId==null) initTabId = tab.key;
		}.bind(this));
		
		// ÃÊ±âÅÇ È°¼ºÈ­
		if (!options.noActive && (this._selectedTab = this._TabItems[initTabId])) {
			this._selectedTab._setVisible(true, options.changeAction);
		}
	},
	
	/**
	 * ÅÇ º¯°æ½Ã ½ÇÇà
	 * 
	 * @param {Empas.UI.View.TabItem} TabItem ÀÌº¥Æ®°¡ ¹ß»ýÇÑ ÅÇ ¾ÆÀÌÅÛ °´Ã¼
	 */
	_onChangeTab: function(e, TabItem) {
		var options = this._options;

		// Å¬¸¯ ¸ðµåÀÏ °æ¿ì ÀÌº¥Æ® Àü´Þ ¸·±â
		if (options.clickMode) {
			Event.stop(e);
		}
		
		// ÀÌÀüÅÇ ºñÈ°¼ºÈ­
		if (this._selectedTab != null) {
			if (this._selectedTab == TabItem) return; // ÇöÀç È°¼ºÈ­ ÅÇ°ú °°À» °æ¿ì
			this._selectedTab._setVisible(false, options.changeAction);
		}

		// ¼±ÅÃÅÇ È°¼ºÈ­
		TabItem._setVisible(true, options.changeAction);		
		this._selectedTab = TabItem;
		
		if (options.afterChange != null) 
			options.afterChange(TabItem);
	}
};

/*============================================================================*
 * TabItem
 *============================================================================*/
Empas.UI.TabItem = Class.create();

Empas.UI.TabItem.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} tab_id ÅÇ°ú ¿¬°áÇÒ ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @constructor
	 */
	initialize: function(tab_id) {
		this.view = null; // ÅÇ°ú ¿¬°áÇÒ ºä ¾ÆÀÌÅÛ
		
		if ((this.el = $(tab_id)) != null) {			
			this.id = tab_id;
			
			// ¸¶¿ì½º ¿À¹ö½Ã ½ÇÇàÇÒ ¸í·É¿¡ ´ëÇÑ ¼³Á¤°ª ÀúÀå
			if (this.el.tagName=="IMG") { // ÀÌ¹ÌÁöÀÏ °æ¿ì
				this._over = {
					mode: 'img',
					off: this.el.readAttribute('offsrc')!=null ? 
							this.el.readAttribute('offsrc'):this.el.src,
					on: this.el.readAttribute('onsrc')
				};
			} else {
				this._over = {
					mode: 'class',
					off: this.el.readAttribute('offclass')!=null ? 
							this.el.readAttribute('offclass'):$(this.el).className,
					on: this.el.readAttribute('onclass')
				};
			}
		}
	},
	
	/**
	 * ÅÇ°ú ºä ¿¬°á
	 * 
	 * @param {String} view_id ºä ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {Object} request Ajax ¿äÃ» ¿É¼Ç 
	 */
	setView: function(view_id, request) {	
		if ((this.view = new Empas.UI.ViewItem(view_id, request)) != null) {
			this.view.hide();
		}
	},
	
	/**
	 * ºä º¸ÀÓ/¾Èº¸ÀÓ Ã³¸®
	 * 
	 * @param {Boolen} visible º¸ÀÓ/¾Èº¸ÀÓ
	 * @param {Boolen} changeAction »óÅÂ º¯°æ½Ã ¾×¼Ç ¿©ºÎ
	 */	
	_setVisible: function(visible, changeAction) {
		if (!this.view) return;
		
		var tab = this.el;
		if (visible) {
			if (changeAction && this._over.on!=null) {
				if (this._over.mode=='img') {
					tab.src = this._over.on;
				} else if (!tab.hasClassName(this._over.on)){
					tab.removeClassName(this._over.off);
					tab.addClassName(this._over.on);
				}
			}
			this.view.show();
		}
		else {
			if (changeAction && this._over.off!=null) {
				if (this._over.mode=='img') {
					tab.src = this._over.off;
				} else if (!tab.hasClassName(this._over.off)){
					tab.removeClassName(this._over.on);
					tab.addClassName(this._over.off);
				}
			}
			this.view.hide();
		}
	}
};

/*============================================================================*
 * Rotate
 *============================================================================*/
Empas.UI.Rotate = Class.create();

Empas.UI.Rotate.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(options) {
		this._options = Object.extend({			
			autoTime: 0,		// Å¸ÀÌ¸Ó (ÀÚµ¿ ·Ñ¸µ). ÃÊ´ÜÀ§
			useHand: true,		// ¸¶¿ì½º ¿À¹ö½Ã ¼Õ¸ð¾ç ¸¶¿ì½º ¿©ºÎ
			afterChange: null	// º¯°æ½Ã ½ÇÇàÇÒ ÇÔ¼ö
		}, options || {});
		
		this._ViewItems = [null];
	},
	
	/**
	 * ºä Ãß°¡
	 * 
	 * @param {String} view_id ºä ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {Object} request Ajax ¿äÃ» ¿É¼Ç
	 */	
	add: function(view_id, request) {
		this._ViewItems.push(new Empas.UI.ViewItem(view_id, request));
	},	
	
	/**
	 * ½ÇÇà
	 * 
	 * @param {Number} initIdx ÃÊ±â ºä ÀÎµ¦½º
	 */
	start: function(initIdx) {
		var options = this._options;

		// ÀÌº¥Æ® ¿¬°á
		Event.observe(options.prev, "click", this._onClick.bindAsEventListener(this, 'prev'));
		Event.observe(options.next, "click", this._onClick.bindAsEventListener(this, 'next'));
		
		// ¸¶¿ì½º Ä¿¼­
		if (options.useHand) {
			$(options.prev).setStyle({ cursor: "pointer" });
			$(options.next).setStyle({ cursor: "pointer" });			
		}

		// ÃÊ±â ºä
		this._endIdx = this._ViewItems.length-1;
		this._savedIdx = this._curIdx = $D(initIdx) ? initIdx:1;
		
		this._show();
	},

	/**
	 * ÀÌÀü ¹öÆ° ¿ÜºÎ ÇÔ¼ö
	 */	
	priv: function() {
		this._onClick(null, "priv");
	},
	
	/**
	 * ´ÙÀ½ ¹öÆ° ¿ÜºÎ ÇÔ¼ö
	 */		
	next: function() {
		this._onClick(null, "next");
	},
	
	/**
	 * ºä ³ëÃâ ¿©ºÎ
	 */
	_show: function() {
		var options = this._options;

		// ÇöÀç ¾ÆÀÌÅÛ
		this._ViewItems[this._curIdx].show();

		// ÀÚµ¿ ·Ñ¸µ Å¸ÀÌ¸Ó ¼³Á¤
		if (options.autoTime != 0) {
			if ($D(this._timer)) this._timer.stop();
						
			this._timer = new PeriodicalExecuter(function () {
				this._onClick('next'); 
			}.bind(this), options.autoTime);
		}

		if (options.afterChange!=null)
			options.afterChange(this._curIdx);		
	},
	
	/**
	 * ÀÌÀü, ´ÙÀ½ Å¬¸¯ ÀÌº¥Æ® ¹ß»ý½Ã ½ÇÇà
	 */	
	_onClick: function(e, mode) {
		Event.stop(e);
		
		this._curIdx += mode=="next" ? 1:-1;
		
		if (this._curIdx <= 0) 
			this._curIdx = this._endIdx;
		else if (this._curIdx > this._endIdx)
			this._curIdx = 1;

		this._ViewItems[this._savedIdx].hide();
		this._savedIdx = this._curIdx;
		
		this._show();
	}
};

/*============================================================================*
 * Toggle
 *============================================================================*/
Empas.UI.Toggle = Class.create();

Empas.UI.Toggle.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} id Åä±ÛÀ» ¿¬°áÇÒ ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {String} view_id ºä ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {String} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(id, view_id, options) {
		this._options = Object.extend({
			visible: false,		// ÃÊ±â Ãâ·Â ¿©ºÎ
			afterChange: null,	// ½ÇÇàÈÄ È£ÃâÇÒ ÇÔ¼ö
			useHand:false		// ¸¶¿ì½º ¼Õ¸ð¾ç Ä¿¼­ À¯¹«
		}, options || {});
		
		this._el = $(id);
		if (!this._el) return;
		
		if (this._options.useHand) 
			this._el.setStyle({ cursor: "pointer" });
			
		this._view = new Empas.UI.ViewItem(view_id);
		
		this.toggle(false);
		
		this._el.observe("click", this.toggle.bind(this));
	},
	
	/**
	 * Åä±Û ÇÔ¼ö
	 * 
	 * @param {Boolean} change »óÅÂ°ª º¯°æ ¿©ºÎ (±âº»°ª true)
	 */
	toggle: function(change) {
		var options = this._options;

		if ((change = change || false))
			options.visible = !options.visible;
			
		this._view[options.visible ? 'show':'hide']();
		
		if (options.afterChange!=null)
			options.afterChange(this._el, options.visible);
	}
};

/*============================================================================*
 * Scroller
 *============================================================================*/
Empas.UI.Scroller = Class.create();

Empas.UI.Scroller.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} id ·çÆ® ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {Object} options ¿É¼Ç 
	 * @constructor
	 */
	initialize: function(id, options) {
		id = $(id);
		if (!id) return;

		this._options = Object.extend({	
			height: 18,			// ³ôÀÌ
			width: "100%",		// ³Êºñ
			width_unit: "px",	// ³Êºñ ´ÜÀ§
			pauseTime: 3,		// ¸ØÃã½Ã°£(ÃÊ)
			speed: 0.02,		// ½ºÅ©·Ñ ÀÌµ¿ È£Ãâ½Ã°£ (³·À»¼ö·Ï ºü¸§)
			step: 1,			// ÀÌµ¿ ÇÈ¼¿ ´ÜÀ§
			overStop: true,		// ¸¶¿ì½º ¿À¹ö½Ã ¸ØÃã ¿©ºÎ
			autoStart: true		// ½ÃÀÛ½Ã ·Ñ¸µ ½ÃÀÛ
		}, options || {});

		options = this._options;

		if (options.width.indexOf("%")!=-1)
		{
			options.width = options.width.replace("%","");
			options.width_unit = "%";
		}

		// ·çÆ® ¿¤¸®¸ÕÆ® ½ºÅ¸ÀÏ ¼³Á¤
		this._el = $C("div");
		$(this._el).setStyle({
			position : "relative",
			overflow : "hidden",
			height : options.height + "px",
			width : options.width + options.width_unit
		});	
		id.appendChild(this._el);

		// ¾ÆÀÌÅÛ ½ÃÀÛ À§Ä¡(y)
		options.readyPos = options.height;
		
		// ¾ÆÀÌÅÛ ÀúÀå ¹è¿­
		this._items = [];
		this._itemCnt = 0;
	},
	
	/**
	 * µ¥ÀÌÅÍ Ãß°¡
	 * 
	 * @param {String} html Ãß°¡ÇÒ div¿¡ ³ÖÀ» ³»¿ë
	 */	
	add: function(html) {
		if (!$D(this._options)) return;
		
		var options = this._options;

		// div °´Ã¼ ¸¸µé±â
		var item = $C("div");
		item.top = (this._itemCnt==0) ? 0:options.readyPos;
		$(item).setStyle( {
			position : "absolute",
			top : item.top + "px",
			height : options.height + "px",
			width : options.width + options.width_unit
		});
		item.innerHTML = html;
		
		// Ãß°¡
		this._el.appendChild(item);
		this._items[this._itemCnt++] = item;
	},
	
	/**
	 * ½ÇÇà
	 */	
	start: function() {	
		if (this._itemCnt>1) {
			// ÃÊ±âÈ­
			this._pause = false;
			this._curIdx = 0;
			this._nextIdx = 1;

			// mouse over ÀÌº¥Æ® µî·Ï
			if (this._options.overStop) {
				this._el.observe("mouseover", this._setPause.bind(this, true));
				this._el.observe("mouseout", this._setPause.bind(this, false));
			}
			
			this._start();
		}
	},
	
	/**
	 * ½ºÅ©·Ñ Á¤Áö º¯¼ö ¼³Á¤
	 * 
	 * @param {Boolean} val Á¤Áö ¿©ºÎ
	 */
	_setPause: function(val) {
		this._pause = val;		
	},
	
	/**
	 * ½ºÅ©·Ñ ÇÔ¼ö ½ÇÇà
	 */	
	_start: function() {
		new PeriodicalExecuter(function (pe) {
			pe.stop();
		
			// ¾ÆÀÌÅÛ ÀÌµ¿ ÇÔ¼ö ½ÇÇà
			if (this._Executer) this._Executer.stop();			
			this._Executer = new PeriodicalExecuter(function () {
				this._moveItem(); 
			}.bind(this), this._options.speed);
						
		}.bind(this), this._options.pauseTime);
	},
	
	/**
	 * ½ºÅ©·Ñ Á¤Áö º¯¼ö ¼³Á¤
	 * 
	 * @param {Boolean} val Á¤Áö ¿©ºÎ
	 */
	_moveItem: function() {
		if (this._pause) return;
		var oerflow = false;
		var items = this._items;
		var options = this._options;
		
		[this._curIdx, this._nextIdx].each(function(idx) {
			// ÇöÀç ¾ÆÀÌÅÛÀ» À§·Î ÀÌµ¿
			items[idx].top -= options.step;
			if (idx==this._nextIdx && items[idx].top <= 0) {
				items[idx].top = 0;
				oerflow = true;
			}
			items[idx].style.top = items[idx].top + "px";
			
			// ´ÙÀ½ ¾ÆÀÌÅÛÀÌ Á¤Áö À§Ä¡¿¡ ¿Ã °æ¿ì
			if (oerflow) {
				if (this._Executer) this._Executer.stop();

				// ÇöÀç ¾ÆÀÌÅÛ(À§·Î »ç¶óÁø)À» ´ë±â À§Ä¡·Î ÀÌµ¿
				items[this._curIdx].top = options.readyPos;
				items[this._curIdx].style.top = items[this._curIdx].top + "px";

				// ÇöÀç, ´ÙÀ½ ¾ÆÀÌÅÛ ÀÎµ¦½º Áõ°¡
				if (++this._curIdx>=this._itemCnt) this._curIdx = 0;
				if (++this._nextIdx >= this._itemCnt) this._nextIdx = 0;
			
				// ½ºÅ©·Ñ ´Ù½Ã ½ÃÀÛ			
				this._start();
			}
		}.bind(this));
	}
};

/*============================================================================*
 * Floating
 *============================================================================*/
Empas.UI.Floating = Class.create();

Empas.UI.Floating.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} id Àû¿ëÇÒ ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(id, options) {
		this._el = $(id);
		if (!this._el) return;
		
		this._options = Object.extend({
			xMargin: 10,		// X ¸¶Áø 
			yMargin: 10,		// Y ¸¶Áø
			xMode: "left",		// X ¸ðµå : left, right, center, center_add
			yMode: "top",		// Y ¸ðµå : top, middle, bottom
			duration: 0.04,	// ÀÌµ¿ Ã¼Å© ½Ã°£(ÃÊ)
			width: this._el.getWidth(),
			height: this._el.getHeight()
		}, options || {});

		options = this._options;

		// yMode¿¡¼­ »ç¿ëÇÏ±â À§ÇÑ ÃÊ±â yMargin °ª
		options.yOrgMargin = options.yMargin;

		// yMode¿¡ µû¸¥ yMargin°ª º¯°æ
		this._arragePositionY();
		
		// ·çÆ® ¿¤¸®¸ÕÆ® ½ºÅ¸ÀÏ ¼³Á¤
		this._el.setStyle( {
			position : "absolute",
			top : options.yMargin + "px"
		});
		
		// xMode¿¡ µû¸¥ x À§Ä¡ º¯°æ
		this._arragePositionX();
		
		// À©µµ¿ì Å©±â º¯°æ½Ã À§Ä¡ º¸Á¤
		Event.observe(window, "resize", function () {
			this._arragePositionX();
			this._arragePositionY();
		}.bind(this));

		this.start();
	},
	
	/**
	 * xMode¿¡ µû¸¥ x À§Ä¡ º¯°æ
	 */
	_arragePositionX: function() {
		var docWidth = document.body.clientWidth;
		var options = this._options;
		var xPos = options.xMargin;

		// X ÁÂÇ¥ ±¸ÇÏ±â
		switch(this._options.xMode) {
			case "center_add":
				xPos = parseInt(docWidth/2,10) + options.xMargin;
			break;

			case "right":
				xPos = docWidth - options.width - options.xMargin;
			break;

			case "center":
				xPos = parseInt((docWidth - options.width)/2, 10);
			break;
		}

		this._el.style.left = xPos + "px";
	},
	
	/**
	 * yMode¿¡ µû¸¥ yMargin°ª º¯°æ
	 */	
	_arragePositionY: function() {
		var options = this._options;
		if (options.yMode=="middle") {
			options.yMargin = parseInt((document.body.clientHeight - options.height)/2, 10);
		} else if (options.yMode=="bottom") {
			options.yMargin = document.body.clientHeight - options.height - options.yOrgMargin;
		}
	},
	
	/**
	 * ÁÖ±âÀûÀÎ ÀÌµ¿ÇÔ¼ö ½ÇÇà
	 */	
	start: function() {
		this.stop();		
		this._Executer = new PeriodicalExecuter(function () {
			this._move();
		}.bind(this), this._options.duration);
	},
	
	/**
	 * ÀÌµ¿ÇÔ¼ö ½ÇÇà ¸ØÃã
	 */	
	stop: function() {
		if (this._Executer) this._Executer.stop();
	},
	
	/**
	 * ¿¤¸®¸ÕÆ® ÀÌµ¿
	 */	
	_move: function() {
		// ½ÃÀÛ(ÇöÀç) À§Ä¡
		var startPos = parseFloat(this._el.style.top);
		if (!startPos) startPos = 0;
		
		// ¸ñÇ¥ À§Ä¡
		var endPos = document.body.scrollTop + document.documentElement.scrollTop + this._options.yMargin;
		
		// ÀÌµ¿ ¹æÇâ (+, -)
		var dir = (endPos < startPos) ? -1:1;

		// ÀÌµ¿
		if (startPos != endPos) {
			var amount = Math.ceil(Math.abs(endPos-startPos)/5);
			this._el.style.top = (startPos + (dir * amount)) + "px";
		} else {
			this.start();
		}
	}
};
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > UI > RollOver
 */

if(typeof Prototype == "undefined")
	throw("empas.ui.rollover.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.UI)) Empas.UI = {};

/*============================================================================*
 * RollOver
 *============================================================================*/
Empas.UI.RollOver = Class.create();

Empas.UI.RollOver.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(options) {
		this._options = Object.extend({
			preload: true				// ÀÌ¹ÌÁö ¹Ì¸® ÀÐ±â
		}, options || {});
		
		this._cache = {};
		
		document.getElementsByClassName("EUIRollOver").each(this._bindElement.bind(this));
	},
	
	/**
	 * EUIRollOver¸¦ Å¬·¡½º·Î °¡Áö´Â ¿¤¸®¸ÕÆ® ¹ÙÀÎµù
	 * 
	 * @param {Object} options ¿É¼Ç
	 */
	_bindElement: function(el) {
		// Áßº¹ ¹ÙÀÎµù Ã¼Å©
		if ($D(el._created)) return;
		el._created = true;
		
		el = $(el);
		
		var attr = {
			src: $ATTR(el, "src"),				// ±âº» ÀÌ¹ÌÁö
			over: $ATTR(el, "over"),			// ¿À¹ö ÀÌ¹ÌÁö
			click: $ATTR(el, "click"),			// Å¬¸¯ ÀÌ¹ÌÁö
			select: $ATTR(el, "select"),		// ¼±ÅÃ ÀÌ¹ÌÁö
			clickmode: $ATTR(el, "clickmode")	// Å¬¸¯ Áö¿ø ¿©ºÎ
		};

		if (!attr.src) return;
				
		// ÀÌ¹ÌÁö¸í°ú È®ÀåÀÚ ±¸ÇÏ±â
		attr.src.scan(/(.+).(gif|png|jpg|bmp)$/, function(match) {
			attr.img_name = match[1];
			attr.img_ext = match[2];
		});
		
		// over, select, click »óÅÂ ÀÌ¹ÌÁö ÀúÀå & ·Îµå
		['over', 'select', 'click'].each(function (action) {
			if (!attr[action])
				attr[action] = attr.img_name + "_" + action + "." + attr.img_ext;
				
			// ÀÌ¹ÌÁö ·Îµå
			var img = attr[action];
			if (this._options.preload) {				
				if (!$D(this._cache[img])) {					
					if (action=="click" && !attr.clickmode) return;
					new Image().src = img;
					this._cache[img] = true;
				}
			}
		}.bind(this));	

		// ¼±ÅÃ ¼Ó¼ºÀÌ ÀÖÀ» °æ¿ì
		if ($ATTR(el, "selected"))
			el.src = attr.src = attr.select;
		
		el.observe("mouseover", this._mouseEvent.bindAsEventListener(this, "over", attr));
		el.observe("mouseout", this._mouseEvent.bindAsEventListener(this, "src", attr));

		// Å¬¸¯¸ðµå »ç¿ëÇÒ °æ¿ì
		if (attr.clickmode) {
			el.observe("mousedown", this._mouseEvent.bindAsEventListener(this, "click", attr));
			el.observe("mouseup", this._mouseEvent.bindAsEventListener(this, "src", attr));
		}
	},
	
	/**
	 * ¸¶¿ì½º ÀÌº¥Æ® Ã³¸®
	 * 
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 * @param {String} action Á¾·ù (over|src|click)
	 * @param {Object} attr ¼Ó¼º
	 */
	_mouseEvent: function(e, action, attr) {
		Event.element(e).src = attr[action];
	}
};
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > UI > Drag
 *
 * reference : script.aculo.us, mootools
 */

if(typeof Prototype == "undefined")
	throw("empas.ui.drag.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.UI)) Empas.UI = {};

/*============================================================================*
 * Drag
 *============================================================================*/
Empas.UI.Drag = Class.create();

Empas.UI.Drag.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} id Àû¿ëÇÒ ¿¤¸®¸ÕÆ® ID
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(id, options) {
		if (!(this._el = $(id))) return;

		// ¿É¼Ç
		this._options = Object.extend({	
			handle: null,			// µå·¡±× ÀÛµ¿ ¿¤¸®¸ÕÆ® ¾ÆÀÌµð
			zIndex: 1000,			// z-index
			ghosting: false,		// °í½ºÆÃ ¸ðµå(¿øº»Àº ³²ÀÌÀÖ°í º¹»çº»À¸·Î ÀÌµ¿) ¿©ºÎ
			changeCursor: true,		// Ä¿¼­ º¯°æ ¿©ºÎ
			changeOpacity: true,	// Åõ¸íµµ º¯°æ ¿©ºÎ
			dragOpacity: 0.5,		// µå·¡±× ½ÃÀÛ½Ã Åõ¸íµµ			
			onStart: null,			// µå·¡±× ½ÃÀÛ½Ã È£ÃâÇÒ ÇÔ¼ö
			onDrag: null,			// µå·¡±× µ¿¾È È£ÃâÇÒ ÇÔ¼ö
			onStop: null			// µå·¡±× Á¾·á½Ã È£ÃâÇÒ ÇÔ¼ö
		}, options || {});
		
		this._events = {
			start: this._onStart.bindAsEventListener(this),
			drag: this._onDrag.bindAsEventListener(this),
			stop: this._onStop.bindAsEventListener(this)
		};

		this._handle = this._options.handle ? $(this._options.handle):this._el;
		
		this._el.makePositioned();
		
		this.start();
	},
	
	/**
	 * µå·¡±× È°¼ºÈ­
	 */	
	start: function() {
		this._handle.observe("mousedown", this._events.start);
	},
	
	/**
	 * µå·¡±× ºñÈ°¼ºÈ­
	 */
	stop: function() {
		this._handle.stopObserving("mousedown", this._events.start);
	},
	
	/**
	 * »ç¿ëÀÚ ÁöÁ¤ ÀÌº¥Æ® ½ÇÇà
	 * 
	 * @param {String} name ÀÌº¥Æ® ÀÌ¸§. onStart, onDrag, onStop
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 */	
	_notify: function(name, e) {
		if (this._options[name]) 
			this._options[name](e);
	},
	
	/**
	 * ¸¶¿ì½º ¹öÆ°À» ´­·¯ µå·¡±×°¡ ½ÃÀÛµÉ ¶§ È£Ãâ
	 * 
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 */		
	_onStart: function(e) 
	{
		var options = this._options;
		var el = this._el;
	
		// ÀÌµ¿ Ã¼Å©ÇÒ À§Ä¡ ÀúÀå
		this._pos = Position.cumulativeOffset(el);
		this._pos[0] = Event.pointerX(e) - this._pos[0];
		this._pos[1] = Event.pointerY(e) - this._pos[1];	

		// z-Index
		if(options.zIndex) {
			options.orgZIndex = parseInt(el.getStyle('z-index') || 0);
			el.setStyle( { zIndex : options.zIndex } );
		}

		// °í½ºÆÃ ¸ðµå
		if (options.ghosting) {
			this._clone = el.cloneNode(true);
			Position.absolutize(el);
			el.parentNode.insertBefore(this._clone, el);
		}
		
		// Åõ¸íµµ
		if (options.changeOpacity) {
			options.orgOpacity = el.getOpacity() || 1.0;
			el.setOpacity(options.dragOpacity);
		}
		
		// Ä¿¼­
		if (this._options.changeCursor) {
			options.orgCursor = el.getStyle("cursor") || "";	
			el.setStyle({ cursor: "move" });
		}			
		
		// ÀÌº¥Æ® ¿¬°á
		Event.observe(document, "mousemove", this._events.drag);
		Event.observe(document, "mouseup", this._events.stop);		

		this._notify('onStart', e);	
		Event.stop(e);
	},
	
	/**
	 * ¸¶¿ì½º ÀÌµ¿À¸·Î µå·¡±×°¡ ÁøÇàµÉ ¶§ È£Ãâ
	 * 
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 */	
	_onDrag: function(e) {
		// ÀÌµ¿ÇÒ À§Ä¡ ±¸ÇÏ±â
		var pos = Position.cumulativeOffset(this._el);

		if(this._options.ghosting) {
			Position.prepare();
			var r = Position.realOffset(this._el);
			pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
		}

		pos[0] -= parseInt(this._el.getStyle('left') || '0');
		pos[1] -= parseInt(this._el.getStyle('top') || '0');

		// ÀÌµ¿
		this._el.setStyle({
			left: (Event.pointerX(e)-pos[0]-this._pos[0])+ "px",
			top: (Event.pointerY(e)-pos[1]-this._pos[1]) + "px"
		});
		
		this._notify('onDrag', e);
		Event.stop(e);
	},
	
	/**
	 * ¸¶¿ì½º ¹öÆ°À» ¶§¼­ µå·¡±×°¡ Á¾·áµÉ ¶§ È£Ãâ
	 * 
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 */		
	_onStop: function(e) {
		var options = this._options;
		var el = this._el;

		// z-index
		if(options.zIndex)
			el.style.zIndex = options.orgZIndex;

		// °í½ºÆÃ ¸ðµå
		if (options.ghosting) {
			Position.relativize(el);
			Element.remove(this._clone);
			this._clone = null;	
		}

		// Åõ¸íµµ
		if (options.changeOpacity)
			el.setOpacity(options.orgOpacity);
		
		// Ä¿¼­
		if (options.changeCursor) 
			el.setStyle({ cursor: options.orgCursor });
		
		Event.stopObserving(document, "mousemove", this._events.drag);
		Event.stopObserving(document, "mouseup", this._events.stop);
		
		this._notify('onStop', e);
	}
};
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > UI > Tooltip
 */

if(typeof Prototype == "undefined")
	throw("empas.ui.tooltip.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.UI)) Empas.UI = {};

/*============================================================================*
 * Tooltip
 *============================================================================*/
Empas.UI.Tooltip = Class.create();

Empas.UI.Tooltip.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(options) {
		// ¿É¼Ç
		this._options = Object.extend({
			className: "EUITooltip",		// Àû¿ëÇÒ Å¬·¡½º¸í
			zindex: 1000,					// z-index
			background: "#FEFCF0",			// ¹è°æ ¼Ó¼º
			border: "1px solid #A2A383",	// Å×µÎ¸® ¼Ó¼º
			fontFamily: "±¼¸²",				// ÆùÆ® ¼Ó¼º
			fontSize: "12px",				// ÆùÆ® Å©±â
			fontColor: "#555555",			// ÆùÆ® »ö
			padding: 5,						// ¿©¹é
			width: 0,						// ÅøÆÁ °¡·Î Å©±â. 0Àº ÁöÁ¤ ¾ÈÇÔ
			x: 16,							// ÅøÆÁ X À§Ä¡. ¸¶¿ì½º Æ÷ÀÎÅÍ ±âÁØ
			y: 16,							// ÅøÆÁ Y À§Ä¡
			fixed: false					// °íÁ¤ À¯¹«
		}, options || {});
		
		document.getElementsByClassName(this._options.className).each(this._bindElement.bind(this));
	},
	
	/**
	 * ¿¤¸®¸ÕÆ® ÀÌº¥Æ® ¿¬°á
	 * 
	 * @param {Object} el EUITooltipÀ» Å¬·¡½º·Î °¡Áö´Â ¿¤¸®¸ÕÆ®
	 */	
	_bindElement: function(el) {
		// Áßº¹ ¹ÙÀÎµù Ã¼Å©
		if ($D(el._created)) return;
		el._created = true;

		el = $(el);
		
		// Å¸ÀÌÆ² ¼Ó¼º ±¸ÇÏ±â
		if (!el.title) return;
		var title = el.title;
		el.removeAttribute('title');

		// ÀÌº¥Æ® ¿¬°á
		el.observe("mouseover", this._showTip.bindAsEventListener(this, title));
		el.observe("mouseout", this._hideTip.bindAsEventListener(this));
		
		if (!this._options.fixed)
			el.observe("mousemove", this._moveTip.bindAsEventListener(this));		
	},
	
	/**
	 * ÅøÆÁ È°¼ºÈ­
	 * 
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 * @param {String} title ÅøÆÁ¿¡ º¸¿©ÁÙ ³»¿ë
	 */	
	_showTip: function(e, title) {
		Event.stop(e);
		
		// ÇÑ¹ø ÅøÆÁ ¿µ¿ªÀ» »ý¼º
		if (!$D(this._tooltip)) {
			var options = this._options;

			this._tooltip = $C("div").setStyle({
				position: "absolute",
				background: options.background,
				border: options.border,
				padding: options.padding + "px",
				fontFamily: options.fontFamily,
				fontSize: options.fontSize,
				color: options.fontColor,
				zIndex: options.zindex,
				display: "none"
			});

			if (options.width!=0)
				this._tooltip.setStyle({ width: options.width + "px" });

			document.body.appendChild(this._tooltip);
		}

		// ³»¿ë º¯°æÇÏ°í º¸¿©ÁÖ±â
		this._tooltip.innerHTML = title;
		this._tooltip.show();
		
		// ÅøÆÁ ÀÌµ¿
		this._moveTip(e);
	},
	
	/**
	 * ÅøÆÁ ºñÈ°¼ºÈ­
	 * 
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 */		
	_hideTip: function(e) {
		Event.stop(e);
		this._tooltip.hide();
	},
	
	/**
	 * ÅøÆÁ ÀÌµ¿
	 * 
	 * @param {Object} e ÀÌº¥Æ® °´Ã¼
	 */		
	_moveTip: function(e) {
		Event.stop(e);
		
		if (!$D(this._tooltip)) return;

		// °íÁ¤ À§Ä¡ÀÏ °æ¿ì
		if (this._options.fixed) {
			var el = Event.element(e);
			var pos = Position.cumulativeOffset(el);
			
			this._tooltip.setStyle({
				left: pos[0] + this._options.x + "px",
				top: (pos[1] + Event.element(e).getHeight() + this._options.y) + "px"
			});
		
			return;	
		}
		
		// ¸¶¿ì½º À§Ä¡
		var mouse = { x : Event.pointerX(e), y : Event.pointerY(e) };
		
		// ÅøÆÁ Å©±â
		var tooltip = Element.getDimensions(this._tooltip);
		
		// À©µµ¿ì Å©±â
		var win = Position.getWindowSize();
		win.height += document.body.scrollTop + document.documentElement.scrollTop;

		var options = this._options;
		
		// °¡·Î ¹üÀ§ ÃÊ°ú Ã¼Å©
		if (tooltip.width + mouse.x >= win.width - options.x - 20)
			mouse.x -= tooltip.width;
		else
			mouse.x += options.x;

		// ¼¼·Î ¹üÀ§ ÃÊ°ú Ã¼Å©
		if (tooltip.height + mouse.y >= win.height - options.y)
			mouse.y -= tooltip.height;
		else
			mouse.y += options.y;
		
		// ÅøÆÁ ÀÌµ¿
		this._tooltip.setStyle({
			left: mouse.x + "px",
			top: mouse.y + "px"
		});
	}
};
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > UI > Modal
 */

if(typeof Prototype == "undefined")
	throw("empas.util.modal.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.UI)) Empas.UI = {};

/*============================================================================*
 * Modal
 *============================================================================*/
Empas.UI.Modal = Class.create();

Object.extend(Empas.UI.Modal,{
	_instances: {},
	
	/**
	 * Modal ÀÎ½ºÅÏ½º »ý¼º
	 * 
	 * @param {String} section ±¸ºÐÀÚ
	 * @param {Object} options ¿É¼Ç
	 */	
	create: function(section, options) {
		if ($T(section)!="string") {
			options = section;
			section = "default";
		} else {
			section = section || "default";
		}
		
		if (!this._instances[section])
			this._instances[section] = new Empas.UI.Modal(options);
	},
	
	/**
	 * Modal ÀÎ½ºÅÏ½º ±¸ÇÏ±â
	 * 
	 * @param {String} section ±¸ºÐÀÚ
	 * @return {Object} ±¸ºÐÀÚ¿¡ ÇØ´çÇÏ´Â Empas.UI.Modal ÀÎ½ºÅÏ½º
	 */
	getModal: function(section) {
		section = section || "default";	
		
		if (!this._instances[section])
			this.create(section, arguments[1] || {});
		
		return this._instances[section];
	}
});

Empas.UI.Modal.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(options) {
		// ¿É¼Ç
		this._options = Object.extend({
			modaless: false,			// Modaless À¯¹«
			drag: false,				// µå·¡±× À¯¹«
			loading: true,				// ·Îµù Ç¥½Ã À¯¹«
			loadingImg: "http://img.empas.com/img/eprototypeui/loading.gif", // ·Îµù ÀÌ¹ÌÁö
			escClose:true,				// ESC Å°·Î ´Ý±â À¯¹«
			imageClose: true,			// ÀÌ¹ÌÁö Å¬¸¯½Ã ´Ý±â À¯¹«
			overlap: true,				// ¿À¹ö·¦ »ç¿ë À¯¹«
			overlapColor: "#282828",	// ¿À¹ö·¦ »ö
			overlapOpacity: 0.4,		// ¿À¹ö·¦ Åõ¸íµµ
			overlapZIndex: 2000,		// ¿À¹ö·¦ z-index
			overlapClose: true,			// ¿À¹ö·¦ ¸¶¿ì½º Å¬¸¯½Ã ´Ý±â À¯¹«
			centerUpdate: true,			// °¡¿îµ¥ Á¤·Ä À¯Áö À¯¹« (½ºÅ©·Ñ, À©µµ¿ì Å©±â º¯°æ)
			containerBG: "#efefef",		// ÃÖ»óÀ§ ÄÁÅ×ÀÌ¾î ¹è°æ
			containerBorder: "1px solid #898989", // ÄÁÅ×ÀÌ³Ê Å×µÎ¸®
			contentsBG: "#fff",			// ÄÁÅÙÃ÷ ¿µ¿ª ¹è°æ
			contentsBorder: "1px solid #B8B8B8", // ÄÁÅÙÃ÷ ¿µ¿ª Å×µÎ¸®
			titleColor: "#F36324",		// Å¸ÀÌÆ² ÆùÆ®»ö
			closeImg: "http://img.empas.com/img/eprototypeui/close_btn.gif" // Á¾·á ¹öÆ° ÀÌ¹ÌÁö
		}, options || {});
				
		this._reviseOption();
		
		// ¿µ¿ª ÀúÀå
		this._divs = {};
		
		// ÀÌº¥Æ®
		this._events = {
			contents: this._onLoadContents.bind(this),
			resize: this._resize.bind(this),
			close: this.close.bind(this),
			keypress: this._onKeyPress.bindAsEventListener(this)
		};
		
		this._contents = {
			active: null,
			iframe: null,
			image: null
		};
	},

	/**
	 * ¸ð´Þ¸®½º ±âº» ¼³Á¤
	 */
	setModaless: function() {
		this._options = Object.extend(this._options, {
			drag: true,
			overlap: false,
			centerUpdate: false					
		});
	},

	/**
	 * ¸ð´Þ ±âº» ¼³Á¤
	 */	
	setModal: function() {
		this._options = Object.extend(this._options, {
			overlap: true,
			overlapClose: true
		});
	},
	
	/**
	 * ¿É¼Ç Á¶Á¤
	 */
	_reviseOption: function() {
		var options = this._options;

		if (options.modaless) this.setModaless();

		options.containerZIndex = options.overlapZIndex + 1;
		
		if (options.drag) options.centerUpdate = false;
		
		if (!options.overlap) options.overlapClose = false;
		
		if (options.drag && (!$D(Empas.UI) || !$D(Empas.UI.Drag))) options.drag = false;
	},
	
	/**
	 * HTML ³»¿ëÀ¸·Î ¿­±â
	 * 
	 * @param {String} html HTML
	 */	
	openHtml: function(html) {
		var options = Object.extend({
			mode : "html"
		}, arguments[1] || {});
		
		this._open(html, options);
	},

	/**
	 * iframe ¿­±â
	 * 
	 * @param {String} url À¥ÆäÀÌÁö °æ·Î
	 */	
	openFrame: function(url) {
		var options = Object.extend({
			mode : "iframe",
			scrolling : "no",
			width: 500,
			height: 400
		}, arguments[1] || {});
		
		this._open(url, options);
	},
	
	/**
	 * ÀÌ¹ÌÁö·Î ¿­±â
	 * 
	 * @param {String} img ÀÌ¹ÌÁö °æ·Î
	 */		
	openImage: function(img) {
		var options = Object.extend({
			mode : "image"
		}, arguments[1] || {});
		
		this._open(img, options);
	},
	
	/**
	 * ½ÇÁúÀûÀÎ ¿­±â ÇÔ¼ö
	 * 
	 * @param {String} request ¿äÃ»°ª
	 * @param {Object} options ¿É¼Ç
	 */	
	_open: function(request, options) {
		this.close();
		
		// overlap º¸ÀÌ±â
		this._showOverlap();

		var g_options = this._options;
		var divs = this._divs;

		// x,y ÁÂÇ¥°¡ ÀÖÀ» °æ¿ì ±Û·Î¹ú ¿É¼Ç¿¡ Ãß°¡
		if ($D(options.x) && $D(options.y)) {
			g_options.x = options.x;
			g_options.y = options.y;
			g_options.position = options.position || "absolute";
		}
		
		// ÄÁÅ×ÀÌ³Ê ¿µ¿ª »ý¼º
		if (!$D(this._divs.container)) {
			var tid = (new Date).getMilliseconds();
			
			divs.container = $C("div").setStyle({
				position: "absolute",
				background: g_options.containerBG,
				border: g_options.containerBorder,
				zIndex: g_options.containerZIndex,
				display: "none"
			});
			divs.container.id = "modal_container_" + tid;

			// ÄËÅÏÃ÷ ¿µ¿ª
			divs.contents = $C("div").setStyle({
				position: "relative",
				background: g_options.contentsBG,
				border: g_options.contentsBorder,
				margin: "23px 4px 4px 4px"
			});			
			divs.container.appendChild(divs.contents);

			// Å¸ÀÌÆ² ¿µ¿ª
			divs.title = $C("div").setStyle({
				position: "absolute",
				top: "5px",
				left: "5px",
				fontSize: "12px",
				color: g_options.titleColor
			});
			divs.title.id = "modal_title_" + tid;
			divs.container.appendChild(divs.title);
			
			// Á¾·á¹öÆ° ¿µ¿ª
			divs.closeBtn = $C("div").setStyle({
				cursor: "pointer",
				position: "absolute",				
				top: "3px",
				left: "0px",
				width: "16px",
				height: "16px",
				background: "url('" + g_options.closeImg + "') no-repeat center center"
			});
			divs.container.appendChild(divs.closeBtn);
			divs.closeBtn.observe("click", this._events.close);
						
			// º»¹® Ãß°¡
			document.body.appendChild(divs.container);			
		}
		
		if (g_options.drag && !g_options.initDrag) {
			new Empas.UI.Drag(divs.container.id, {
				handle: divs.title.id,
				zIndex: 100000
			});
			
			g_options.initDrag = true;
		}
		
		// ·Îµù º¸ÀÌ±â
		this._showLoading();

		// Á¾·ù¿¡ µû¶ó Ã³¸®
		switch(options.mode) {
			case "html":
				if (!this._contents.html) {
					this._contents.html = $C("div");
					this._divs.contents.appendChild(this._contents.html);					
				}
				
				this._contents.active = this._contents.html;
				
			break;
			
			case "iframe":
				if (!this._contents.iframe) {
					this._contents.iframe = $C("iframe");
					this._contents.iframe.frameBorder = 0;
					this._contents.iframe.scrolling = options.scrolling;

					this._divs.contents.appendChild(this._contents.iframe);
				}

				this._contents.iframe.width = options.width + "px";
				this._contents.iframe.height = options.height + "px";				
				
				this._contents.active = this._contents.iframe;
			break;
			
			case "image":
				if (!this._contents.image) {
					this._contents.image = $C("img");
					
					if (this._options.imageClose) {
						this._contents.image.setStyle({ cursor: "pointer" });
						this._contents.image.observe("click", this._events.close);
					}
					
					this._divs.contents.appendChild(this._contents.image);
				}

				this._contents.active = this._contents.image;
			break;
		}

		this._contents.active.show();
		
		// Å¸ÀÌÆ² ¼³Á¤
		this._title = options.title || " ";

		if (options.mode=="html") {
			this._contents.active.innerHTML = request;
			this._onLoadContents();
		} else {
			Event.observe(this._contents.active, "load", this._events.contents);
			this._contents.active.src = request;
		}
				
		// ESC Å° ÀÌº¥Æ® µî·Ï
		if (this._options.escClose)
			Event.observe(document, "keypress", this._events.keypress);

		// À©µµ¿ì ¸®»çÀÌÁî ÀÌº¥Æ® µî·Ï
		Event.observe(window, "resize", this._events.resize);
	},
	
	/**
	 * iframe, imgÀÏ °æ¿ì onload ÀÌº¥Æ®°¡ ¹ß»ýÇÒ ¶§ ½ÇÇà
	 */		
	_onLoadContents: function() {
		// ·Îµù ¼û±â±â
		this._hideLoading();

		var divs = this._divs;
		var options = this._options;
		
		if ($D(options.x) && $D(options.y)) {

			if (options.position=="relative")
			{
				options.y += document.body.scrollTop + document.documentElement.scrollTop	
			}

			divs.container.setStyle({
				left: options.x + "px",
				top: options.y + "px"
			});
			
			options.x = options.y = options.position = undefined;
		} else {
			// ÄÁÅ×ÀÌ³Ê Áß¾Ó Á¤·Ä
			Position.center(divs.container);
		}
		
		divs.container.show();
		
		// Å¸ÀÌÆ² ³Ö±â
		if (this._title)
			divs.title.innerHTML = this._title;

		// Å¸ÀÌÆ² Å©±â º¯°æ
		if (options.drag) {
			divs.title.setStyle({
				width: (divs.container.getWidth() - 40) + "px"
			});
		}
		
		// ´Ý±â ¿µ¿ª ÀÌµ¿
		divs.closeBtn.style.left = (divs.container.getWidth()-21) + "px";
		
		// load ÀÌº¥Æ® Á¦°Å
		Event.stopObserving(this._contents.active, "load", this._events.contents);
	},
	
	/**
	 * ´Ý±â
	 */	
	close: function() {
		if (!this._contents.active) return;

		// ÄÁÅÙÃ÷ ¿µ¿ª ¼û±â±â
		if (this._contents.active.tagName=="IFRAME")
			this._contents.active.src = "about:blank";
			
		this._contents.active.hide();
		this._contents.active = null;
		
		// ÄÁÅ×ÀÌ³Ê ¿µ¿ª ¼û±â±â
		this._divs.container.hide();
		
		// ·Îµù ¼û±â±â
		this._hideLoading();
		
		// ¿À¹ö·¦ ¼û±â±â
		this._hideOverlap();
		
		// ÀÌº¥Æ® Á¦°Å
		if (this._options.escClose)
			Event.stopObserving(document, "keypress", this._events.keypress);

		Event.stopObserving(window, "resize", this._events.resize);
	},
	
	/**
	 * ·Îµù º¸ÀÌ±â
	 */		
	_showLoading: function() {
		if (!this._options.loading)	 return;
		
		// ·Îµù ¿µ¿ª »ý¼º
		if (!$D(this._divs.loading)) {
			this._divs.loading = $C("div").setStyle({
				position: "absolute",
				background: "#fff",
				border: "1px solid #787878",
				zIndex: 9100,
				padding: "10px",
				width: "145px",
				display: "none"
			});
			
			this._divs.loading.update("<img src='" + this._options.loadingImg + "'>");
			document.body.appendChild(this._divs.loading);
		}

		Position.center(this._divs.loading, { update: true } );
		this._divs.loading.show();
	},
	
	/**
	 * ·Îµù °¨Ãß±â
	 */	
	_hideLoading: function() {
		if (!this._options.loading)	 return;
		if (this._divs.loading) this._divs.loading.hide();
	},
	
	/**
	 * ¿À¹ö·¦ º¸ÀÌ±â
	 */	
	_showOverlap: function() {
		// IEÀÏ °æ¿ì SELECT ¼û±â±â
		if (Prototype.Browser.IE)
			$A(document.getElementsByTagName('select')).each(function(select){
				select.style.visibility = 'hidden';
			});		

		if (!this._options.overlap) return;
		
		// ¿À¹ö·¦ ¿µ¿ª »ý¼º
		if (!$D(this._divs.overlap)) {
			this._divs.overlap = $C("div");
			
			this._divs.overlap.setStyle({
				top: "0px",
				left: "0px",
				zIndex: this._options.overlapZIndex,
				background: this._options.overlapColor,
				display: "none"
			});
				
			if (Prototype.Browser.IE) {
				this._divs.overlap.setStyle({ position: "absolute" });
				
				this._resize();
			} else {
				this._divs.overlap.setStyle({
					position: "fixed",
					width: "100%", 
					height: "100%"
				});
			}
						
			this._divs.overlap.setOpacity(this._options.overlapOpacity);
			
			document.body.appendChild(this._divs.overlap);
		}
		
		this._divs.overlap.show();
		
		if (this._options.overlapClose)
			this._divs.overlap.observe("click", this._events.close);
	},
	
	/**
	 * ¿À¹ö·¦ ¼û±â±â
	 */	
	_hideOverlap: function() {
		if (Prototype.Browser.IE)
			$A(document.getElementsByTagName('select')).each(function(select){
				select.style.visibility = 'visible';
			});
		
		if (!this._options.overlap || !this._divs.overlap || !this._divs.overlap.visible()) return;
				
		this._divs.overlap.hide();
		
		if (this._options.overlapClose)	
			this._divs.overlap.stopObserving("click", this._events.close);
	},
	
	/**
	 * È­¸é ¸®»çÀÌÂ¡ Ã³¸®
	 */	
	_resize: function() {
		// ¿À¹ö·¦
		if (this._options.overlap && Prototype.Browser.IE) {
			this._divs.overlap.setStyle({
				width: Math.min(document.body.scrollWidth, Position.getWindowSize().width) + "px",
				height: Math.max(document.body.scrollHeight, $(document.body).getHeight()) + "px"
			});
		}
		
		// ÄÁÅÙÃ÷
		if (this._options.centerUpdate && $D(this._divs.container) && this._divs.container.visible())
			Position.center(this._divs.container);
	},

	/**
	 * Å°º¸µå ´­¸² ÀÌº¥Æ®
	 */		
	_onKeyPress: function(e) {
		if (e.keyCode == Event.KEY_ESC)
			this.close();
	}
};

/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > Effect
 * 
 * base : script.aculo.us effects.js v1.7.0
 * reference : Transitions (Based on Easing Equations v2.0)
 */

if(typeof Prototype == "undefined")
	throw("empas.effect.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};

/*============================================================================*
 * Element ÇÔ¼ö Ãß°¡
 *============================================================================*/

Element.forceRerendering = function(element) {
	try {
		element = $(element);
		var n = document.createTextNode(' ');
		element.appendChild(n);
		element.removeChild(n);
	} catch(e) {}
};

['forceRerendering'].each(function(f) { Element.Methods[f] = Element[f]; });

Element.addMethods();

/*============================================================================*
 * Effect
 *============================================================================*/

Empas.Effect = {
	_elementDoesNotExistError: {
		name: 'ElementDoesNotExistError',
		message: 'The specified DOM element does not exist, but is required for this effect to operate'
	}
};

var Effect = Empas.Effect;

/*============================================================================*
 * Transitions. (Âü°í : mootools)
 *============================================================================*/
Effect.Transition= function (transition) {
	return Object.extend(transition, {
		easeIn: function(pos) {
			return transition(pos);
		},
	
		easeOut: function(pos) {
			return 1-transition(1-pos);
		},
	
		easeInOut: function(pos) {
			return (pos <= 0.5) ? transition(2 * pos) / 2 : (2 - transition(2 * (1 - pos))) / 2;
		}
	});
};
		
Effect.TransCore = {
	linear : Prototype.K,
	
	Quad : function(p) {
		return Math.pow(p, 2);
	},
	
	Cubic : function(p) {
		return Math.pow(p, 3);
	},

	Quart : function(p) {
		return Math.pow(p, 4);
	},
	
	Quint : function(p) {
		return Math.pow(p, 5);
	},
	
	Expo: function(p){
		return Math.pow(2, 8 * (p - 1));
	},
	
	Circ: function(p){
		return 1 - Math.sin(Math.acos(p));
	},
	
	Sine: function(p){
		return 1 - Math.sin((1 - p) * Math.PI / 2);
	},
	
	Back: function(p){
		x = 1.618;
		return Math.pow(p, 2) * ((x + 1) * p - x);
	},
	
	Bounce: function(p){
		var value;
		for (var a = 0, b = 1; 1; a += b, b /= 2){
			if (p >= (7 - 4 * a) / 11){
				value = - Math.pow((11 - 6 * a - 11 * p) / 4, 2) + b * b;
				break;
			}
		}
		return value;
	},
	
	Elastic: function(p, x){
		x = 1;
		return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * x / 3);
	}
};

Effect.Transitions = {};

$H(Effect.TransCore).each(function(core) {
	Effect.Transitions[core.key] = new Effect.Transition(core.value);
});

/*============================================================================*
 * Core Effect
 *============================================================================*/
Effect.ScopedQueue = Class.create();
Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
	initialize: function() {
		this.effects  = [];
		this.interval = null;
	},
	_each: function(iterator) {
		this.effects._each(iterator);
	},
	add: function(effect) {
		var timestamp = new Date().getTime();
    
		var position = (typeof effect.options.queue == 'string') ? 
		effect.options.queue : effect.options.queue.position;
    
		switch(position) {
			case 'front':
				// move unstarted effects after this effect  
				this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
					e.startOn  += effect.finishOn;
					e.finishOn += effect.finishOn;
				});
			break;
			case 'with-last':
				timestamp = this.effects.pluck('startOn').max() || timestamp;
			break;
			case 'end':
				// start effect after last queued effect has finished
				timestamp = this.effects.pluck('finishOn').max() || timestamp;
			break;
		}
    
		effect.startOn  += timestamp;
		effect.finishOn += timestamp;

		if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
			this.effects.push(effect);
    
		if(!this.interval) 
			this.interval = setInterval(this.loop.bind(this), 15);
	},
	remove: function(effect) {
		this.effects = this.effects.reject(function(e) { return e==effect });
		if(this.effects.length == 0) {
			clearInterval(this.interval);
			this.interval = null;
		}
	},
	loop: function() {
		var timePos = new Date().getTime();
		for(var i=0, len=this.effects.length;i<len;i++) 
			if(this.effects[i]) this.effects[i].loop(timePos);
	}
});

Effect.Queues = {
	instances: $H(),
	get: function(queueName) {
		if(typeof queueName != 'string') return queueName;
    
		if(!this.instances[queueName])
			this.instances[queueName] = new Effect.ScopedQueue();
      
		return this.instances[queueName];
	}
};

Effect.Queue = Effect.Queues.get('global');

Effect.DefaultOptions = {
	transition: Effect.Transitions.Sine.easeIn,
	duration:   1.0,   // seconds
	fps:        60.0,  // max. 60fps due to Effect.Queue implementation
	sync:       false, // true for combining
	from:       0.0,
	to:         1.0,
	delay:      0.0,
	queue:      'parallel'
};

Effect.Base = function() {};
Effect.Base.prototype = {
	position: null,
	start: function(options) {
		this.options      = Object.extend(Object.extend({},Effect.DefaultOptions), options || {});
		this.currentFrame = 0;
		this.state        = 'idle';
		this.startOn      = this.options.delay*1000;
		this.finishOn     = this.startOn + (this.options.duration*1000);
		this.event('beforeStart');
		if(!this.options.sync)
			Effect.Queues.get(typeof this.options.queue == 'string' ? 
				'global' : this.options.queue.scope).add(this);
	},
	loop: function(timePos) {
		if(timePos >= this.startOn) {
			if(timePos >= this.finishOn) {
				this.render(1.0);
				this.cancel();
				this.event('beforeFinish');
				if(this.finish) this.finish(); 
				this.event('afterFinish');
				return;  
			}
			var pos   = (timePos - this.startOn) / (this.finishOn - this.startOn);
			var frame = Math.round(pos * this.options.fps * this.options.duration);
			if(frame > this.currentFrame) {
				this.render(pos);
				this.currentFrame = frame;
			}
		}
	},
	render: function(pos) {
		if(this.state == 'idle') {
			this.state = 'running';
			this.event('beforeSetup');
			if(this.setup) this.setup();
			this.event('afterSetup');
		}
		if(this.state == 'running') {
			if(this.options.transition) pos = this.options.transition(pos);
			pos *= (this.options.to-this.options.from);
			pos += this.options.from;
			this.position = pos;
			this.event('beforeUpdate');
			if(this.update) this.update(pos);
			this.event('afterUpdate');
		}
	},
	cancel: function() {
		if(!this.options.sync)
			Effect.Queues.get(typeof this.options.queue == 'string' ? 
				'global' : this.options.queue.scope).remove(this);
		this.state = 'finished';
	},
	event: function(eventName) {
		if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
		if(this.options[eventName]) this.options[eventName](this);
	},
	inspect: function() {
		var data = $H();
		for(property in this)
			if(typeof this[property] != 'function') data[property] = this[property];
		return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
	}
};

Effect.Parallel = Class.create();
Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
	initialize: function(effects) {
		this.effects = effects || [];
		this.start(arguments[1]);
	},
	update: function(position) {
		this.effects.invoke('render', position);
	},
	finish: function(position) {
		this.effects.each( function(effect) {
			effect.render(1.0);
			effect.cancel();
			effect.event('beforeFinish');
			if(effect.finish) effect.finish(position);
			effect.event('afterFinish');
		});
	}
});

Effect.Event = Class.create();
Object.extend(Object.extend(Effect.Event.prototype, Effect.Base.prototype), {
	initialize: function() {
		var options = Object.extend({
			duration: 0
		}, arguments[0] || {});
		this.start(options);
	},
	update: Prototype.emptyFunction
});

Effect.Opacity = Class.create();
Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
	initialize: function(element) {
		this.element = $(element);
		if(!this.element) throw(Effect._elementDoesNotExistError);
		// make this work on IE on elements without 'layout'
		if(Prototype.Browser.IE && !window.opera && (!this.element.currentStyle.hasLayout))
			this.element.setStyle({zoom: 1});
		var options = Object.extend({
			from: this.element.getOpacity() || 0.0,
			to:   1.0
		}, arguments[1] || {});
		this.start(options);
	},
	update: function(position) {
		this.element.setOpacity(position);
	}
});

/*============================================================================*
 * Move
 *============================================================================*/
Effect.Move = Class.create();
Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
	initialize: function(element) {
		this.element = $(element);
		if(!this.element) throw(Effect._elementDoesNotExistError);
		var options = Object.extend({
			x: 0,
			y: 0,
			mode: 'relative'
		}, arguments[1] || {});
		this.start(options);
	},
	setup: function() {
		// Bug in Opera: Opera returns the "real" position of a static element or
		// relative element that does not have top/left explicitly set.
		// ==> Always set top and left for position relative elements in your stylesheets 
		// (to 0 if you do not need them) 
		this.element.makePositioned();
		this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
		this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
		
		if(this.options.mode == 'absolute') {
			// absolute movement, so we need to calc deltaX and deltaY
			this.options.x = this.options.x - this.originalLeft;
			this.options.y = this.options.y - this.originalTop;
		}
	},
	update: function(position) {
		this.element.setStyle({
			left: Math.round(this.options.x  * position + this.originalLeft) + 'px',
			top: Math.round(this.options.y  * position + this.originalTop)  + 'px'
		});
	}
});

// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
	return new Effect.Move(element, 
		Object.extend({ x: toLeft, y: toTop }, arguments[3] || {}));
};

Effect.MoveTo = function(element, x, y) {
	var Pos = Position.cumulativeOffset($(element));
	if (x==0) Pos[0] = x;
	if (y==0) Pos[1] = y;
	return new Effect.Move(element, 
		Object.extend({ x: x - Pos[0], y: y - Pos[1] }, arguments[3] || {}));
};

/*============================================================================*
 * Scale
 *============================================================================*/
Effect.Scale = Class.create();
Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
	initialize: function(element, percent) {
		this.element = $(element);
		if(!this.element) throw(Effect._elementDoesNotExistError);
		var options = Object.extend({
			scaleX: true,
			scaleY: true,
			scaleContent: true,
			scaleFromCenter: false,
			scaleMode: 'box',        // 'box' or 'contents' or {} with provided values
			scaleFrom: 100.0,
			scaleTo: percent
		}, arguments[2] || {});
		this.start(options);
	},
	setup: function() {
		this.restoreAfterFinish = this.options.restoreAfterFinish || false;
		this.elementPositioning = this.element.getStyle('position');

		this.originalStyle = {};
		['top','left','width','height','fontSize'].each( function(k) {
			this.originalStyle[k] = this.element.style[k];
		}.bind(this));
      
		this.originalTop  = this.element.offsetTop;
		this.originalLeft = this.element.offsetLeft;
    
		var fontSize = this.element.getStyle('font-size') || '100%';
		['em','px','%','pt'].each( function(fontSizeType) {
			if(fontSize.indexOf(fontSizeType)>0) {
				this.fontSize = parseFloat(fontSize);
				this.fontSizeType = fontSizeType;
			}
		}.bind(this));
    
		this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;

		this.dims = null;
		if(this.options.scaleMode=='box')
			this.dims = [this.element.offsetHeight, this.element.offsetWidth];
		else if(/^content/.test(this.options.scaleMode))
			this.dims = [this.element.scrollHeight, this.element.scrollWidth];
		if(!this.dims)
			this.dims = [this.options.scaleMode.originalHeight, this.options.scaleMode.originalWidth];
	},
	update: function(position) {
		var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
		if(this.options.scaleContent && this.fontSize)
			this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
		this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
	},
	finish: function(position) {
		if(this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
	},
	setDimensions: function(height, width) {
		var d = {};
		if(this.options.scaleX) d.width = Math.round(width) + 'px';
		if(this.options.scaleY) d.height = Math.round(height) + 'px';
		if(this.options.scaleFromCenter) {
			var topd  = (height - this.dims[0])/2;
			var leftd = (width  - this.dims[1])/2;
			if(this.elementPositioning == 'absolute') {
				if(this.options.scaleY) d.top = this.originalTop-topd + 'px';
				if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
			} else {
				if(this.options.scaleY) d.top = -topd + 'px';
				if(this.options.scaleX) d.left = -leftd + 'px';
			}
		}
		this.element.setStyle(d);
	}
});

Effect.ScaleTo = function(element, width, height) {	
	var dim = $(element).getDimensions();
	var size = { width: width, height: height };
	var options = arguments[3];

	// afterFish°¡ ÀÖ´Â °æ¿ì ±âº» ¿É¼Ç¿¡¼­ Á¦°Å
	var afterFinish = options.afterFinish;
	if (afterFinish) options.afterFinish = null;

	var kindCnt = 0, kindIdx = 0;
	if (width!=-1) kindCnt++;
	if (height!=-1) kindCnt++;
	
	['width','height'].each(function(kind) {
		if (size[kind]!=-1)
		{
			var per = (size[kind] / dim[kind]) * 100.0;	
			var opt = Object.clone(options);
			opt[kind=="width" ? "scaleY":"scaleX"] = false;

			if (++kindIdx>=kindCnt && afterFinish)
			{
				opt.afterFinish = afterFinish;
			}

			new Effect.Scale(element, per, opt);
		}
	});
};

/*============================================================================*
 * Fade In & Out
 *============================================================================*/
Effect.Appear = function(element) {
	element = $(element);
	var options = Object.extend({
		from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
		to:   1.0,
		// force Safari to render floated elements properly
		afterFinishInternal: function(effect) {
			effect.element.forceRerendering();
		},
		beforeSetup: function(effect) {
			effect.element.setOpacity(effect.options.from).show(); 
		}
	}, arguments[1] || {});

	return new Effect.Opacity(element,options);
};

Effect.FadeIn = Effect.Appear;

Effect.Fade = function(element) {
	element = $(element);
	var oldOpacity = element.getOpacity();
	var options = Object.extend({
		from: element.getOpacity() || 1.0,
		to:   0.0,
		afterFinishInternal: function(effect) { 
			if(effect.options.to!=0) return;
			effect.element.hide().setStyle({opacity: oldOpacity}); 
		}
	}, arguments[1] || {});
	
	return new Effect.Opacity(element,options);
};

Effect.FadeOut = Effect.Fade;
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > Util > Cookie
 */

if(typeof Prototype == "undefined")
	throw("empas.util.cookie.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.Util)) Empas.Util = {};

/*============================================================================*
 * Cookie (Âü°í : Cookie.js of mootools)
 *============================================================================*/
Empas.Util.Cookie = {
	/**
	 * ÄíÅ° ¼³Á¤
	 * 
	 * @param {String} key ÀÌ¸§
	 * @param {String} value °ª
	 * @param {Object} options ¿É¼Ç
	 */	
	set: function(key, value, options) {
		options = Object.extend({
			domain: false,		// µµ¸ÞÀÎ
			path: false,		// Àû¿ë °æ·Î
			duration: false,	// ¸¸·á±â°£. ÀÏ´ÜÀ§
			secure: false		// º¸¾È ¿©ºÎ
		}, options || {});
		
		value = encodeURIComponent(value);
		
		if (options.domain) value += '; domain=' + options.domain;
		if (options.path) value += '; path=' + options.path;
		if (options.duration){
			var date = new Date();
			date.setTime(date.getTime() + options.duration * 24 * 60 * 60 * 1000);
			value += '; expires=' + date.toGMTString();
		}		
		if (options.secure) value += '; secure';
		
		document.cookie = key + '=' + value;	
	},
	
	/**
	 * ÄíÅ° ±¸ÇÏ±â
	 * 
	 * @param {String} key ÀÌ¸§
	 * @return {String} Å°¿¡ ÇØ´çÇÏ´Â °ª. ¾øÀ» °æ¿ì null ¹ÝÈ¯.
	 */		
	get: function(key) {
		key = key.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
		var value = document.cookie.match('(?:^|;)\\s*' + key + '=([^;]*)');
		
		return value ? decodeURIComponent(value[1]) : null;
	},

	/**
	 * ÄíÅ° »èÁ¦
	 * 
	 * @param {String} key ÀÌ¸§
	 * @param {Object} options ¿É¼Ç
	 */	
	remove: function(key, options) {
		this.set(key, '', $H(options).merge({ duration: -1 }));	
	}
};
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > Util > IFResize : ¾ÆÀÌÇÁ·¹ÀÓ ÀÚµ¿ ¸®»çÀÌÂ¡
 */

if(typeof Prototype == "undefined")
	throw("empas.util.ifresize.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.Util)) Empas.Util = {};

/*============================================================================*
 * IFResize
 *============================================================================*/

Empas.Util.IFResize = Class.create();

Empas.Util.IFResize.prototype = {
	/**
	 * »ý¼ºÀÚ
	 *
	 * @param {String} id Àû¿ëÇÒ ¾ÆÀÌÇÁ·¹ÀÓ ID
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */	
	initialize: function(id, options) {
		this._iframe = $(id);
		if (!this._iframe) return;
		
		this._options = Object.extend({
			watch: true,		// Å©±â º¯°æ °¨½Ã ¿©ºÎ
			watchInterval: 0.1	// °¨½Ã °£°Ý
		}, options || {});
		
		Event.observe(window, "load", this._resize.bind(this));		
		this.start();
	},
	
	/**
	 * ½ÃÀÛ
	 */	
	start: function() {
		this._resize();
		
		// °¨½Ã ¸ðµåÀÏ °æ¿ì
		if (this._options.watch)
			new PeriodicalExecuter(function () { this._resize(); }.bind(this), 
				this._options.watchInterval);
	},
	
	/**
	 * ½ÇÁúÀûÀÎ ¸®»çÀÌÂ¡ ÇÔ¼ö
	 */	
	_resize: function() {
		var iframe = this._iframe;

		// ºê¶ó¿ìÀú Á¾·ù¿¡ µû¶ó ³ôÀÌ ±¸ÇÏ±â
		if (Prototype.Browser.WebKit) {
			var doc = iframe.contentWindow.document;
			var s = doc.body.appendChild(document.createElement('DIV'));
			s.style.clear = 'both';
			var h = s.offsetTop + 5;
			s.parentNode.removeChild(s);
		} else if (Prototype.Browser.IE) {
			var h = iframe.contentWindow.document.body.scrollHeight + 5;
		} else {
			var h = iframe.contentDocument.body.offsetHeight + 20;
		}

		iframe.style.height = h + "px";
	}
};
/**
 * @projectDescription Empas Prototye & UI
 * @copyright Empas Corp. <http://www.empas.com>
 * @author ifsnow ifsnow-at-empascorp.com
 * @version 1.0
 * 
 * Empas > Util> Logger
 */

if(typeof Prototype == "undefined")
	throw("empas.util.logger.js requires including Prototype library");

if (!$D(Empas)) var Empas = {};
if (!$D(Empas.Util)) Empas.Util = {};

/*============================================================================*
 * Logger
 *============================================================================*/
Empas.Util.Logger = Class.create();

Object.extend(Empas.Util.Logger,{
	_instances: {},
	_zIndex: 100000,
	_idx: 0,
	
	/**
	 * Logger ÀÎ½ºÅÏ½º ±¸ÇÏ±â
	 * 
	 * @param {String} section ±¸ºÐÀÚ
	 * @param {Object} options ¿É¼Ç
	 * @return {Object} ±¸ºÐÀÚ¿¡ ÇØ´çÇÏ´Â Empas.Util.Logger ÀÎ½ºÅÏ½º
	 */
	getLogger: function(section, options) {
		if ($T(section)!="string") {
			options = section;
			section = "default";
		} else {
			section = section || "default";
		}
		
		if (!this._instances[section]) {
			// ¿É¼Ç Ãß°¡
			options = Object.extend({
				zIndex: this._zIndex++,
				idx: this._idx++
			}, options || {});

			this._instances[section] = new Empas.Util.Logger(section, options);
		}
		
		return this._instances[section];
	}
});
	
Empas.Util.Logger.prototype = {
	/**
	 * »ý¼ºÀÚ
	 * 
	 * @param {String} section ±¸ºÐÀÚ
	 * @param {Object} options ¿É¼Ç
	 * @constructor
	 */
	initialize: function(section, options) {
		this._options = Object.extend({
			drag: true,				// µå·¡±× À¯¹«
			showTime: true,			// ½Ã°£ Ãâ·Â À¯¹«
			title: "Logger",		// Å¸ÀÌÆ²
			width: 350,				// Å©±â
			height: 200,
			infoColor: "#383838",	// ÆùÆ®»ö
			debugColor: "#297C1D",
			errorColor: "#ff4400",
			sorting: 'desc',		// ¼ÒÆÃ ¼ø¼­. asc, desc
			idx: 0					// ÀÎ½ºÅÏ½º ÀÎµ¦½º. º¹¼ö Ã³¸®¸¦ À§ÇØ
		}, options || {});
		
		options = this._options;
		
		if (options.drag && (!$D(Empas.UI) || !$D(Empas.UI.Drag))) options.drag = false;

		// À©µµ¿ì Å©±â ±¸ÇÏ±â
		var Win = Position.getWindowSize();
		
		// ÄÁÅ×ÀÌ³Ê À§Ä¡
		var posLeft = $(document.body).getWidth() - options.width - 30;
		posLeft -= options.idx*15;
		var posTop = document.body.scrollTop + document.documentElement.scrollTop + 10;
		posTop += options.idx*15;

		// ÄÁÅ×ÀÌ³Ê ¿µ¿ª
		this._divs = {};
		this._divs.container = $C("div").setStyle({
			position: "absolute",
			background: "#efefef",
			border: "1px solid #A7A7A7",
			left: posLeft + "px",
			top: posTop + "px",
			zIndex: options.zIndex
		});
		this._divs.container.id = "logger_container_" + section;

		// Å¸ÀÌÆ² ¿µ¿ª
		this._divs.title = $C("div").setStyle({
			fontSize: "12px",
			color: "#3073DD",
			width: options.width + "px",
			padding: "4px"
		});
		this._divs.title.id = "logger_handle_" + section;
		this._divs.title.innerHTML = "Logger";
		this._divs.container.appendChild(this._divs.title);
			
		// ÄËÅÏÃ÷ ¿µ¿ª
		this._divs.contents = $C("div").setStyle({
			background: "#fff",
			border: "1px solid #B8B8B8",
			margin: "0px 4px 4px 4px",
			width: options.width + "px",
			height: options.height + "px",
			fontSize: "12px",
			padding: "4px",
			overflow: "auto"
		});
		this._divs.container.appendChild(this._divs.contents);
		
		document.body.appendChild(this._divs.container);
		
		// µå·¡±× ¼³Á¤
		if (options.drag) {
			new Empas.UI.Drag(this._divs.container.id, {
				handle: this._divs.title.id,
				zIndex: options.zIndex
			});
		}
	},
	
	/**
	 * info ¸Þ½ÃÁö Ãß°¡
	 * 
	 * @param {String} msg ¸Þ½ÃÁö
	 */	
	info: function(msg) {
		this._addMsg("info", msg);
	},
	
	/**
	 * debug ¸Þ½ÃÁö Ãß°¡
	 * 
	 * @param {String} msg ¸Þ½ÃÁö
	 */	
	debug: function(msg) {
		this._addMsg("debug", msg);
	},
	
	/**
	 * debug ¸Þ½ÃÁö Ãß°¡
	 * 
	 * @param {String} msg ¸Þ½ÃÁö
	 */	
	error: function(msg) {
		this._addMsg("error", msg);
	},
	
	/**
	 * ½ÇÁúÀûÀÎ ¸Þ½ÃÁö Ãß°¡
	 * 
	 * @param {String} kind ·Î±× Á¾·ù 
	 * @param {String} msg ¸Þ½ÃÁö
	 */	
	_addMsg: function(kind, msg) {
		var options = this._options;
		
		// ½Ã°£ º¸¿©ÁÖ±â ¿É¼ÇÀÌ¸é
		if (options.showTime) {
			var date = new Date();
			var hour = date.getHours();
			var min = date.getMinutes();
			var sec = date.getSeconds();
			
			date = "[" + (hour<10 ? '0':'') + hour + ":";
			date += (min<10 ? '0':'') + min + ":";
			date += (sec<10 ? '0':'') + sec + "] ";
			
			msg = date + msg;
		}

		// ·Î±× Á¾·ù¿¡ µû¸¥ »ö
		var color = options[kind+"Color"];
		
		// ¸Þ½ÃÁö
		msgObj = $C("div").setStyle({ color : color });
		msgObj.innerHTML = msg;
		
		// ¿ª¼ø Ãß°¡ÀÏ °æ¿ì
		if (options.sorting=="desc") {
			var first = this._divs.contents.firstChild;
			if (first) {
				this._divs.contents.insertBefore(msgObj, first);
				return;
			}			
		}
		
		this._divs.contents.appendChild(msgObj);
	},
	
	/**
	 * ÃÊ±âÈ­
	 */
	clear: function() {
		this._divs.contents.innerHTML = "";
	}
};
