
	var msgs = new Array();
msgs["req"] = "Campos requeridos sem preenchimento: \"%s\".";
msgs["conf"] = "Confirma %s sem preenchimento?";
msgs["reqfields"] = "Pelo menos %s campo(s) tem que ser preenchido(s).";
msgs["ireg"] = "Registro inexistente.";
msgs["delete"] = "Apagar registro?";
msgs["discard"] = "Nesse caso, as alterações serão descartadas.";

	/*
** Class Exception
*/
Exception = function (message)
{
	this.message = message;
}
Exception.prototype.toString = function ()
{
	return this.message;
}
/*
**	Object Dispose
*/
Dispose = function ()
{
	var itens = [];
	return {
		itens: itens,
		add: function (o)
		{
			if (typeof(o.dispose) == "function")
				itens.push(o);
		},
		all: function ()
		{
			for (var i = itens.length - 1; i >= 0; i--) {
				try {
					itens[i].dispose();
					itens[i] = undefined;
				} catch (e) {
					//alert(e);
				}
			
			}
			delete itens;
		}
	};
}();
/*
**	Object Debugger
*/
Debugger = function(state)
{
	var elemOut;
	var win;
	var doc;
	var lines = [];
	var counter = 0;
	var maxLines = 0;
	var nDigits = 2;
	var curState = state;
	var states = [];
	return {
		print: function (str)
		{
			var pad = "";
			if (doc && curState) {
				counter++;
				pad = counter.toString();
				lines.push(pad.lpad(" ", nDigits)+")"+str);
				if (maxLines > 0 && lines.length > maxLines)
					lines.shift();
				elemOut.innerHTML = lines.join("<br />");
				win.scrollBy(0, elemOut.offsetHeight);
				//doc.write(str + "<br/>");
				//doc.parentWindow.scrollBy(0, doc.documentElement.offsetHeight);
			}
		},
		on: function ()
		{
			states.push(curState);
			curState = 1;
		},
		off: function ()
		{
			states.push(curState);
			curState = 0;
		},
		ret: function ()
		{
			if (states.length > 0)
				curState = states.pop();
			else
				throw "Debugger.states: ret() overflow";
		},
		onload: function ()
		{
			win = window.open("", "Debugger",
				"resizable=yes, toolbar=no, scrollbars=yes, " +
				"height=600, width=800, titlebar=no, directories=no");
			if (win) {
				doc = win.document;
				doc.open();
				doc.write("<html><head><title>Debugger</title></head><body><pre></pre></body></html>");
				doc.close();
				elemOut = doc.body.getElementsByTagName("pre").item(0);
			}
		}
	};
}(0);
/*
** Object Sequence
*/
Sequence = function ()
{
	var seqs = [];
	return {
		seqs: seqs,
		init: function (id)
		{
			if (typeof(this.seqs[id]) == "undefined")
				this.seqs[id] = 0;
		},
		get: function (id)
		{
			return String(id) + "_" + String(this.seqs[id]);
		},
		nextval: function (id)
		{
			this.init(id);
			++this.seqs[id];
			return this.get(id);
		},
		currval: function (id)
		{
			this.init(id);
			return this.get(id);
		}
	};
}();
/*
** Object Register
*/
Register = function ()
{
	var regs = [];
	return {
		regs: regs,
		set: function (obj, id, overwrite)
		{
			if (typeof(id) == "undefined")
				id = Sequence.nextval("register");
			if (this.regs[id] != null && !overwrite)
				throw new Exception("Register: Overwrite id = '"+id+"'");
			this.regs[id] = obj;
			return id;
		},
		get: function (id)
		{
			return this.regs[id];
		},
		unSet: function (id)	
		{
			this.regs[id] = null;
		}
	};
}();
/*
** Object Timer
*/
Timer = function ()
{
	return {
		getObj: function (pointer)
		{
			var obj;
			if (typeof(pointer) == "function")
				obj = {func: pointer};
			else if (pointer instanceof Array) {
				if (typeof(pointer[0]) == "object" &&
					typeof(pointer[0][pointer[1]]) == "function")
					obj = {obj: pointer[0], method: pointer[1]};
				else
					throw new Exception("Timer: Array pointer invalid");
			}
			else
				throw new Exception("Timer: Function pointer invalid");
			return obj;
		},
		setTimeout: function (pointer, time)
		{
			var obj = this.getObj(pointer);
			var id = Register.set(obj, Sequence.nextval("setTimeout"));
			var handle = "Timer.timeoutHandle('"+id+"')";
			obj.timerId = window.setTimeout(handle, time);
			return id;
		},
		clearTimeout: function (id)
		{
			var obj = Register.get(id);
			if (obj != null) {
				window.clearTimeout(obj.timerId);
				Register.unSet(id);
			}
		},
		setInterval: function (pointer, time)
		{
			var obj = this.getObj(pointer);
			var id = Register.set(obj, Sequence.nextval("setInterval"));
			var handle = "Timer.intervalHandle('"+id+"')";
			obj.timerId = window.setInterval(handle, time);
			return id;
		},
		clearInterval: function (id)
		{
			var obj = Register.get(id);
			if (obj != null) {
				window.clearInterval(obj.timerId);
				Register.unSet(id);
			}
		}
	};
}();
Timer.timeoutHandle = function (id)
{
	var obj = Register.get(id);
	if (obj == null)
		return;
	if (obj.func)
		obj.func();
	else if (obj.method)
		obj.obj[obj.method]();
	Register.unSet(id);
}
Timer.intervalHandle = function (id)
{
	var obj = Register.get(id);
	if (obj == null)
		return;
	if (obj.func)
		obj.func();
	else if (obj.method)
		obj.obj[obj.method]();
}
/*
** Object Listener
*/
Listener = function ()
{
	var register = [];
	var l = {
		register: register,
		add: function (elem, type, pointer, id)
		{
			var obj;
			if (typeof(elem) != "object")
				throw new Exception("Listener: Element is not object");
			if (typeof(id) == "undefined")
				id = Sequence.nextval("listener");
			if (typeof(pointer) == "function") {
				obj = {elem: elem, type: type, func: pointer};
				obj.handle = this.make(id, true);
			}
			else if (pointer instanceof Array) {
				if (typeof(pointer[0]) == "object" &&
					typeof(pointer[0][pointer[1]]) == "function") {
					obj = {elem: elem, type: type, obj: pointer[0], method: pointer[1]};
					obj.handle = this.make(id, false);
				} else {
					throw new Exception("Listener: Array pointer invalid");
				}
			}
			else {
				throw new Exception("Listener: Function pointer invalid");
			}
			id = Register.set(obj, id);
			if (id == null)
				return null;
			this.register.push(id);
			if (Navigator.hasFeature(elem, "addEventListener"))
					elem.addEventListener(type, obj.handle, false);
			else if (Navigator.hasFeature(elem, "attachEvent"))
					elem.attachEvent("on" + type, obj.handle);
			else
				throw new Exception("Listener.add: Navigator has not feature");
			return id;
		},
		remove: function (id)
		{
			var obj = Register.get(id);
			if (obj == null)
				return;
			this.register.remove(id);
			if (Navigator.hasFeature(obj.elem, "removeEventListener"))
				obj.elem.removeEventListener(obj.type, obj.handle, false);
			else if (Navigator.hasFeature(obj.elem, "detachEvent"))
				obj.elem.detachEvent("on" + obj.type, obj.handle);
			else
				throw new Exception("Listener.remove: Navigator has not this feature");
			Register.unSet(id);
		},
		dispatch: function (elem, type)
		{
			if (elem.dispatchEvent)
				elem.dispatchEvent(type);
			else if (elem.fireEvent)
				elem.fireEvent("on" + type);
			else
				throw new Exception("Listener.dispatch: Navigator has not this feature");
		},
		make: function (id, isFunc)
		{
			var expr = "var evt = new CEvent(e);"+
				"var obj = Register.get('"+id+"');";
			if (isFunc)
				expr += "var ret = obj.func(evt);";
			else
				expr += "var ret = obj.obj[obj.method](evt);";
			expr += "return ret;";
			return new Function ("e", expr);
		},
		dispose: function ()
		{
			for (var i = 0; i < this.register.length; i++)
				this.remove(this.register[i]);
		}
	};
	Dispose.add(l);
	return l;
}();
/*
**	Object Navigator
*/
Navigator = function ()
{
	return {
		hasFeature: function (obj, feature) {
			if (feature) {
				if (obj != "object") {
					if (feature == "event")
						return true;
					return (obj[feature] != null);
				}
			} else {
				if (obj != "undefined")
					return true;
			}
			return false;
		}
	};
}();
window.onunload = function ()
{
	Dispose.all();
}

	SimpleXPath = function (document)
{
	this.document = document;
}

SimpleXPath.cache = {};

// type axis
SimpleXPath.CHILD_AXIS = 1;
SimpleXPath.ATTRIBUTE_AXIS = 2;
SimpleXPath.DOCUMENT_AXIS = 3;
SimpleXPath.PARENT_AXIS = 4;
SimpleXPath.ID_AXIS = 5;
SimpleXPath.ANCESTOR_AXIS = 6;
SimpleXPath.DESCENTANT_AXIS = 7;
SimpleXPath.SELF_AXIS = 8;

// type node
SimpleXPath.ELEMENT_NODE = 1;
SimpleXPath.ATTRIBUTE_NODE = 2;
SimpleXPath.TEXT_NODE = 3;
SimpleXPath.PROCESSING_INSTRUCTION_NODE = 7;
SimpleXPath.COMMENT_NODE = 8;
SimpleXPath.DOCUMENT_NODE = 9;

// type operation
SimpleXPath.OPERATION_BINARY = 100;

// type data
SimpleXPath.TYPE_BOOLEAN = 1000;
SimpleXPath.TYPE_LITERAL = 1001;
SimpleXPath.TYPE_DOMNODE = 1002;

SimpleXPath.prototype.select = function (pathExpr, node)
{
	var locationPath;
	if (typeof(pathExpr) == "object")
		locationPath = pathExpr;
	else
		locationPath = this.compile(pathExpr);
	if (!node)
		node = this.document;
	if (node instanceof Array)
		return locationPath.select(node);
	else
		return locationPath.select([node]);
}

SimpleXPath.prototype.evaluate = function (pathExpr, node)
{
	var orExpr;
	if (typeof(pathExpr) == "object")
		orExpr = pathExpr;
	else
		orExpr = this.compileEvaluate(pathExpr);
	if (!node)
		node = this.document;
	var nodeSets = new SimpleXPath.NodeSets();
	if (node instanceof Array)
	{
		for (var i=0; i < node.length; i++)
			nodeSets.push(new SimpleXPath.Node(node[i], SimpleXPath.TYPE_DOMNODE));
	}
	else
	{
		nodeSets.push(new SimpleXPath.Node(node, SimpleXPath.TYPE_DOMNODE));
	}
	return orExpr.select(nodeSets);
}

SimpleXPath.prototype.compile = function (pathExpr)
{
	if (pathExpr in SimpleXPath.cache)
		return SimpleXPath.cache[pathExpr];
	var context = new SimpleXPath.Context(pathExpr);
	var locationPath = new SimpleXPath.LocationPath(context);
	if (context.index != context.expression.length)
		throw new Exception("Unexpected: " + context.input);
	SimpleXPath.cache[pathExpr] = locationPath;
	return locationPath;
}

SimpleXPath.prototype.compileEvaluate = function (pathExpr)
{
	var context = new SimpleXPath.Context(pathExpr);
	var orExpr = new SimpleXPath.OrExpr(context);
	return orExpr;
}

SimpleXPath.prototype.valueOf = function (nodes)
{
	var value = "";
	for (var i=0; i < nodes.length; i++)
	{
		var node = nodes[i];
		if (node.nodeValue)
			value += String(node.nodeValue);
	}
	return value;
}


SimpleXPath.Node = function (value, type)
{
	this.value = value;
	this.type = type;
}

SimpleXPath.Node.prototype.toBoolean = function ()
{
	switch (this.type)
	{
		case SimpleXPath.TYPE_BOOLEAN:
			return this.value == true;
		case SimpleXPath.TYPE_LITERAL:
		case SimpleXPath.TYPE_DOMNODE:
			return this.value != null;
	}
}

SimpleXPath.Node.prototype.literal = function ()
{
	switch (this.type)
	{
		case SimpleXPath.TYPE_BOOLEAN:
			return this.value ? "" : null;
		case SimpleXPath.TYPE_LITERAL:
			return this.value;
		case SimpleXPath.TYPE_DOMNODE:
			return this.value != null ? this.value.nodeValue : null;
	}
}

SimpleXPath.Node.prototype.name = function ()
{
	switch (this.type)
	{
		case SimpleXPath.TYPE_DOMNODE:
			return this.value != null ? this.value.nodeName : null;
	}
	return null;
}

SimpleXPath.Node.prototype.equals = function (node)
{
	if (this.type == SimpleXPath.TYPE_BOOLEAN || node.type == SimpleXPath.TYPE_BOOLEAN)
		return this.toBoolean() == node.toBoolean();
	else if (this.type == SimpleXPath.TYPE_LITERAL || node.type == SimpleXPath.TYPE_LITERAL)
		return this.literal() == node.literal();
	else
		return this.value == node.value;
}

SimpleXPath.Node.prototype.contains = function (node)
{
	var str1 = this.literal();
	if (!str1)
		return false;
	var str2 = node.literal();
	if (!str2)
		return false;
	return (String(str1).indexOf(str2) >= 0);
}

SimpleXPath.Node.prototype.match = function (node)
{
	var str1 = this.literal();
	if (!str1)
		return false;
	var str2 = node.literal();
	if (!str2)
		return false;
	return (String(str1).match(str2) ? true : false);
}

SimpleXPath.NodeSets = function (node)
{
	this.length = 0;
	if (node)
		this.push(node);
}

SimpleXPath.NodeSets.prototype.push = Array.prototype.push;

SimpleXPath.NodeSets.prototype.toBoolean = function ()
{
	for (var i=0; i < this.length; i++)
		if (this[i].toBoolean())
			return true;
	return false;
}

SimpleXPath.NodeSets.prototype.toNodes = function ()
{
	var nodes = [];
	for (var i=0; i < this.length; i++)
		if (this[i].type == SimpleXPath.TYPE_DOMNODE)
			nodes.push(this[i].value);
	return nodes;
}

SimpleXPath.NodeSets.prototype.not = function ()
{
	var nodeSets = new SimpleXPath.NodeSets();
	for (var i=0; i < this.length; i++)
	{
		var b = this[i].toBoolean();
		var node = new SimpleXPath.Node(!b, SimpleXPath.TYPE_BOOLEAN);
		nodeSets.push(node);
	}
	if (!nodeSets.length)
		nodeSets = new SimpleXPath.NodeSets(new SimpleXPath.Node(true, SimpleXPath.TYPE_BOOLEAN));
	return nodeSets;
}

SimpleXPath.NodeSets.prototype.contains = function (nodeSets)
{
	var nodeSets2 = new SimpleXPath.NodeSets(new SimpleXPath.Node(false, SimpleXPath.TYPE_BOOLEAN));
	for (var i=0; i < this.length; i++)
	{
		var right = this[i];
		for (var j=0; j < nodeSets.length; j++)
		{
			var left = nodeSets[j];
			if (right.contains(left))
				return new SimpleXPath.NodeSets(new SimpleXPath.Node(true, SimpleXPath.TYPE_BOOLEAN));
		}
	}
	return nodeSets2;
	
}

SimpleXPath.NodeSets.prototype.match = function (nodeSets)
{
	var nodeSets2 = new SimpleXPath.NodeSets(new SimpleXPath.Node(false, SimpleXPath.TYPE_BOOLEAN));
	for (var i=0; i < this.length; i++)
	{
		var right = this[i];
		for (var j=0; j < nodeSets.length; j++)
		{
			var left = nodeSets[j];
			if (right.match(left))
				return new SimpleXPath.NodeSets(new SimpleXPath.Node(true, SimpleXPath.TYPE_BOOLEAN));
		}
	}
	return nodeSets2;
	
}

SimpleXPath.NodeSets.prototype.name = function ()
{
	var nodeSets2 = new SimpleXPath.NodeSets();
	for (var i=0; i < this.length; i++)
	{
		var node = this[i];
		nodeSets2.push(new SimpleXPath.Node(String(node.name()).toLowerCase(), SimpleXPath.TYPE_LITERAL));
	}
	return nodeSets2;
}

SimpleXPath.NodeSets.prototype.or = function (nodeSets)
{
	var node = new SimpleXPath.Node(this.toBoolean() || nodeSets.toBoolean(), SimpleXPath.TYPE_BOOLEAN);
	return new SimpleXPath.NodeSets(node);
}

SimpleXPath.NodeSets.prototype.and = function (nodeSets)
{
	var node = new SimpleXPath.Node(this.toBoolean() && nodeSets.toBoolean(), SimpleXPath.TYPE_BOOLEAN);
	return new SimpleXPath.NodeSets(node);
}

SimpleXPath.NodeSets.prototype.equals = function (nodeSets)
{
	var nodeSets2 = new SimpleXPath.NodeSets();
	for (var i=0; i < this.length; i++)
	{
		var node = this[i];
		for (var j=0; j < nodeSets.length; j++)
		{
			var node2 = nodeSets[j];
			if (node.equals(node2))
				nodeSets2.push(node);
		}
	}
	return nodeSets2;
}

SimpleXPath.Context = function (expression)
{
	this.expression = String(expression);
	this.index = 0;
	this.offset(0);
}

SimpleXPath.Context.prototype.offset = function (offset)
{
	this.index += offset;
	this.input = this.expression.substr(this.index);
}

SimpleXPath.Context.prototype.saveState = function ()
{
	return {
		expression: new String(this.expression),
		index: this.index,
		input: new String(this.input)
	}
}

SimpleXPath.Context.prototype.loadState = function (state)
{
	this.expression = state.expression;
	this.index = state.index;
	this.input = state.input;
}

SimpleXPath.LocationPath = function (context)
{
	if (context.input.indexOf("/") == 0)
	{
		context.offset(1);
		this.type = SimpleXPath.DOCUMENT_NODE;
		this.axis = SimpleXPath.DOCUMENT_AXIS;
	}
	var matches = context.input.match(/^id\('([^']*)'\)\/?/);
	if (matches)
	{
		context.offset(matches[0].length);
		this.id = matches[1];
	}
	if (context.index < context.expression.length)
		this.relativeLocationPath = new SimpleXPath.RelativeLocationPath(context);
}

SimpleXPath.LocationPath.prototype.select = function (nodes)
{
	var node, selectNodes = [];
	if (this.id)
	{
		for (var i=0; node = nodes[i]; i++)
		{
			var n = null;
			if (node.nodeType == SimpleXPath.DOCUMENT_NODE)
			{
				n = node.getElementById(this.id);
			}
			else if (node.nodeType == SimpleXPath.ELEMENT_NODE)
			{
				n = node.ownerDocument.getElementById(this.id);
			}
			if (n)
				selectNodes.push(n);
		}
	}
	else if (this.axis == SimpleXPath.DOCUMENT_AXIS)
	{
		for (var i=0; node = nodes[i]; i++)
		{
			if (node.nodeType == SimpleXPath.DOCUMENT_NODE)
				selectNodes.push(node);
			else if (node.nodeType == SimpleXPath.ELEMENT_NODE)
				selectNodes.push(node.ownerDocument);
		}
	}
	else
	{
		selectNodes = nodes;
	}
	if (selectNodes.length && this.relativeLocationPath)
		selectNodes = this.relativeLocationPath.select(selectNodes);
	return selectNodes;
}

SimpleXPath.RelativeLocationPath = function (context)
{
	this.step = new SimpleXPath.Step(context);
	if (context.input.indexOf("/") == 0)
	{
		context.offset(1);
		this.relativeLocationPath = new SimpleXPath.RelativeLocationPath(context);	
	}
}

SimpleXPath.RelativeLocationPath.prototype.select = function (nodes)
{
	var selectNodes = this.step.select(nodes);
	if (this.relativeLocationPath)
		selectNodes = this.relativeLocationPath.select(selectNodes);
	return selectNodes;
}

SimpleXPath.Step = function (context)
{
	this.axisSpecifier = new SimpleXPath.AxisSpecifier(context, this);
	if (this.axisSpecifier.axis != SimpleXPath.PARENT_AXIS && this.axisSpecifier.axis != SimpleXPath.SELF_AXIS)
		this.nodeTest = new SimpleXPath.NodeTest(context);
	this.predicate = new SimpleXPath.Predicate(context);
	this.axisSpecifier.checkName();
}

SimpleXPath.Step.prototype.select = function (nodes)
{
	if (this.primaryExpr)
		return this.primaryExpr.select(nodes);
	return this.axisSpecifier.select(nodes);
}

SimpleXPath.AxisSpecifier = function (context, step)
{
	this.step = step;
	this.axis = SimpleXPath.CHILD_AXIS;
	if (context.input.indexOf("@") == 0)
	{
		context.offset(1);
		this.axis = SimpleXPath.ATTRIBUTE_AXIS;
	}
	else if (context.input.indexOf("..") == 0)
	{
		context.offset(2);
		this.axis = SimpleXPath.PARENT_AXIS;
	}
	else if (context.input.indexOf(".") == 0)
	{
		context.offset(1);
		this.axis = SimpleXPath.SELF_AXIS;
	}
	else if (context.input.indexOf("ancestor::") == 0)
	{
		context.offset(10);
		this.axis = SimpleXPath.ANCESTOR_AXIS;
	}
	else if (context.input.indexOf("/") == 0)
	{
		context.offset(1);
		this.axis = SimpleXPath.DESCENTANT_AXIS;
	}
}

SimpleXPath.AxisSpecifier.prototype.checkName = function ()
{
	this.name = null;
	if (this.step.nodeTest && this.step.nodeTest.nameTest && this.step.nodeTest.nameTest.name != "*")
		this.name = this.step.nodeTest.nameTest.name;
}

SimpleXPath.AxisSpecifier.prototype.test = function (result)
{
	var test = false;
	if (!this.step.nodeTest || this.step.nodeTest.test(result))
	{
		++result.position;
		if (this.step.predicate.test(result))
			test = true;
	}
	return test;
}

SimpleXPath.AxisSpecifier.prototype.select = function (nodes)
{
	var aux, node, selectNodes = [];
	var result = {node: null, position: 0};
	for (var i=0; node = nodes[i]; i++)
	{
		var iterator = null;
		switch (this.axis)
		{
			case SimpleXPath.CHILD_AXIS:
				iterator = new Node.ChildIterator(node);
				break;
			case SimpleXPath.ATTRIBUTE_AXIS:
				if (this.name)
				{
					aux = node.getAttributeNode(this.name);
					iterator = new Node.SelfIterator(aux);
				}
				else
				{
					iterator = new Node.AttributeIterator(node);				
				}
				break;		
			case SimpleXPath.PARENT_AXIS:
				iterator = new Node.ParentIterator(node);
				break;
			case SimpleXPath.ANCESTOR_AXIS:
				iterator = new Node.AncestorIterator(node);
				break;
			case SimpleXPath.DESCENTANT_AXIS:
				if (this.name)
				{
					aux = node.getElementsByTagName(this.name);
					iterator = new Node.CollectionIterator(aux);
				}
				else
				{
					iterator = new Node.DescentantIterator(node);
				}
				break;
			case SimpleXPath.SELF_AXIS:
				iterator = new Node.SelfIterator(node);
				break;
		}
		if (iterator)
		{
			while (iterator.hasNext())
			{
				result.node = iterator.next();
				if (this.test(result))
					selectNodes.push(result.node);			
			}					
		}
	}
	return selectNodes;
}

SimpleXPath.NodeTest = function (context)
{
	try
	{
		var state = context.saveState();
		var nodeType = new SimpleXPath.NodeType(context);
		if (context.input.indexOf("()") == 0)
		{
			this.nodeType = nodeType;
			context.offset(2);
		}
		else
		{
			throw "Char("+context.index+"): Expected '()'.";
		}
	}
	catch(exp)
	{
		context.loadState(state);
		var nameTest = new SimpleXPath.NameTest(context);
		this.nameTest = nameTest;		
	}
}

SimpleXPath.NodeTest.prototype.test = function (result)
{
	if (this.nameTest)
		return this.nameTest.test(result);
	else if (this.nodeType)
		return this.nodeType.test(result);
	return true;
}

SimpleXPath.NameTest = function (context)
{
	if (context.input.indexOf("*") == 0)
	{
		this.name = "*";
	}
	else
	{
		var mName = context.input.match(/^[a-zA-Z_][a-zA-Z0-9-_]*/);
		if (mName)
			this.name = mName[0];
		else
			throw "Char("+context.index+"):Error on match NameTest.";
	}
	context.offset(this.name.length);
}

SimpleXPath.NameTest.prototype.compare = function (value)
{
	return this.name.toLowerCase() == String(value).toLowerCase();
}

SimpleXPath.NameTest.prototype.test = function (result)
{
	if (result.node.nodeType == SimpleXPath.ELEMENT_NODE || result.node.nodeType == SimpleXPath.ATTRIBUTE_NODE)
		return this.name == "*" || (this.compare(result.node.nodeName));
	return false;
}

SimpleXPath.NodeType = function (context)
{
	if (context.input.indexOf("comment") == 0)
	{
		this.nodeType = SimpleXPath.COMMENT_NODE;
		context.offset(7);
	}
	else if (context.input.indexOf("text") == 0)
	{
		this.nodeType = SimpleXPath.TEXT_NODE;
		context.offset(4);
	}
	else if (context.input.indexOf("processing-instruction") == 0)
	{
		this.nodeType = SimpleXPath.PROCESSING_INSTRUCTION_NODE;
		context.offset(22);
	}
	else if (context.input.indexOf("node") == 0)
	{
		this.nodeType = null;
		context.offset(4);
	}
	else
	{
		throw new String("Char("+context.index+"): Error on match NodeType.");
	}
}

SimpleXPath.NodeType.prototype.test = function (result)
{
	if (this.nodeType == null)
		return true;
	return result.node.nodeType == this.nodeType;
}

SimpleXPath.Predicate = function (context)
{
	var matches = context.input.match(/^[ ]*\[/);
	if (matches)
	{
		context.offset(matches[0].length);
		matches = context.input.match(/^([0-9]+)[ ]*\]/);
		if (matches)
		{
			this.position = matches[1];
			context.offset(matches[0].length);
		}
		else
		{
			var predicateExpr = new SimpleXPath.PredicateExpr(context);
			matches = context.input.match(/^[ ]*\]/);
			if (matches)
			{
				context.offset(matches[0].length);
				this.predicateExpr = predicateExpr;
			}
			else
			{
				throw new String("Char("+context.index+"): Expected ']'.");
			}
		}
	}
}

SimpleXPath.Predicate.prototype.test = function (result)
{
	if (this.position)
		return this.position == result.position;
	else if (this.predicateExpr)
		return this.predicateExpr.evaluate(result.node);
	return true;			
}

SimpleXPath.PredicateExpr = function (context)
{
	this.orExpr = new SimpleXPath.OrExpr(context);
}

SimpleXPath.PredicateExpr.prototype.evaluate = function (node)
{
	var oNode = new SimpleXPath.Node(node, SimpleXPath.TYPE_DOMNODE);
	var nodeSets = new SimpleXPath.NodeSets(oNode);
	nodeSets = this.orExpr.select(nodeSets);
	return nodeSets.toBoolean();
}

SimpleXPath.OrExpr = function (context)
{
	this.andExpr = new SimpleXPath.AndExpr(context);
	var matches = context.input.match(/^[ ]*(or)[ ]*/);
	if (matches)
	{
		context.offset(matches[0].length);
		this.orExpr = new SimpleXPath.OrExpr(context);
	}
}

SimpleXPath.OrExpr.prototype.select = function (nodeSets)
{
	var nodeSets1 = this.andExpr.select(nodeSets);
	if (this.orExpr)
	{
		var nodeSets2 = this.orExpr.select(nodeSets);
		nodeSets1 = nodeSets1.or(nodeSets2);
	}
	return nodeSets1;
}

SimpleXPath.AndExpr = function (context)
{
	this.equalityExpr = new SimpleXPath.EqualityExpr(context);
	var matches = context.input.match(/^[ ]*(and)[ ]*/);
	if (matches)
	{
		context.offset(matches[0].length);
		this.andExpr = new SimpleXPath.AndExpr(context);
	}
}

SimpleXPath.AndExpr.prototype.select = function (nodeSets)
{
	var nodeSets1 = this.equalityExpr.select(nodeSets);	
	if (this.andExpr)
	{
		var nodeSets2 = this.andExpr.select(nodeSets);
		nodeSets1 = nodeSets1.and(nodeSets2);
	}
	return nodeSets1;
}

SimpleXPath.EqualityExpr = function (context)
{
	this.primaryExpr = new SimpleXPath.PrimaryExpr(context);
	var matches = context.input.match(/^[ ]*(=|!=)[ ]*/);
	if (matches)
	{
		this.oper = matches[1];
		context.offset(matches[0].length);
		this.primaryExpr2 = new SimpleXPath.PrimaryExpr(context);
	}
}

SimpleXPath.EqualityExpr.prototype.select = function (nodeSets)
{
	var nodeSets1 = this.primaryExpr.select(nodeSets);
	if (!this.oper)
		return nodeSets1;
	var nodeSets2 = this.primaryExpr2.select(nodeSets);
	nodeSets1 = nodeSets1.equals(nodeSets2);
	var found = nodeSets1.toBoolean();
	if (this.oper == "=")
		return new SimpleXPath.NodeSets(new SimpleXPath.Node(found, SimpleXPath.TYPE_BOOLEAN));
	return new SimpleXPath.NodeSets(new SimpleXPath.Node(!found, SimpleXPath.TYPE_BOOLEAN));
}

SimpleXPath.PrimaryExpr = function (context)
{
	var matches = context.input.match(/^'([^']*)'/);
	if (matches)
	{
		this.literal = matches[1];
		context.offset(matches[0].length);
	}
	else
	{
		var state = context.saveState();
		try
		{
			var functionCall = new SimpleXPath.FunctionCall(context);
			this.functionCall = functionCall;
		}
		catch (exp)
		{
			context.loadState(state);
			matches = context.input.match(/^[ ]*\([ ]*/);
			if (matches)
			{
				context.offset(matches[0].length);
				this.orExpr = new SimpleXPath.OrExpr(context);
				matches = context.input.match(/^[ ]*\)[ ]*/);
				if (!matches)
					throw "Char("+context.index+"): Error expected ')'.";
				context.offset(matches[0].length);
			}
			else
			{
				this.locationPath = new SimpleXPath.LocationPath(context);
			}
		}
	}
}

SimpleXPath.PrimaryExpr.prototype.select = function (nodeSets)
{
	var nodeSets2 = new SimpleXPath.NodeSets();
	if (this.literal)
	{
		nodeSets2.push(new SimpleXPath.Node(this.literal, SimpleXPath.TYPE_LITERAL));
	}
	else if (this.functionCall)
	{
		nodeSets2 = this.functionCall.select(nodeSets);
	}
	else if (this.orExpr)
	{
		nodeSets2 = this.orExpr.select(nodeSets);
	}
	else if (this.locationPath)
	{
		var nodes = this.locationPath.select(nodeSets.toNodes());
		for (var i=0; i < nodes.length; i++)
		{
			var n = nodes[i];
			nodeSets2.push(new SimpleXPath.Node(n, SimpleXPath.TYPE_DOMNODE));
		}
	}
	return nodeSets2;
}

SimpleXPath.FunctionCall = function (context)
{
	var matches = context.input.match(/^([a-zA-Z_][a-zA-Z0-9-_.]*)/);
	if (matches)
	{
		var name = matches[1];
		context.offset(name.length);
		if (context.input.indexOf("()") == 0)
		{
			this.name = name;
			context.offset(2);
		}
		else
		{
			matches = context.input.match(/^\([ ]*/);
			if (matches)
			{
				this.name = name;
				context.offset(matches[0].length);
				this.argumentList = new SimpleXPath.ArgumentList(context);
				matches = context.input.match(/^[ ]*\)/);
				if (matches)
					context.offset(matches[0].length);
				else
					throw "Char("+context.index+"): Expected ')'.";
			}
		}
	}
	if (!this.name)
		throw "It is not a function().";
}

SimpleXPath.FunctionCall.prototype.select = function (nodeSets)
{
	var nodeSets2;
	if (this.argumentList)
		var args = this.argumentList.get();
	switch (this.name)
	{
		case "not":
			nodeSets2 = args[0].select(nodeSets).not();
			return nodeSets2;
		case "contains":
			nodeSets2 = args[0].select(nodeSets);
			nodeSets3 = args[1].select(nodeSets);
			return nodeSets2.contains(nodeSets3);
		case "match":
			nodeSets2 = args[0].select(nodeSets);
			nodeSets3 = args[1].select(nodeSets);
			return nodeSets2.match(nodeSets3);
		case "name":
			return nodeSets.name();
		default:
			throw "Function "+this.name+" is not exists.";
	}
}

SimpleXPath.ArgumentList = function (context)
{
	this.orExpr = new SimpleXPath.OrExpr(context);
	var matches = context.input.match(/^[ ]*,[ ]*/);
	if (matches)
	{
		context.offset(matches[0].length);
		this.next = new SimpleXPath.ArgumentList(context);
	}	
}

SimpleXPath.ArgumentList.prototype.select = function (nodeSets)
{
	return this.orExpr.select(nodeSets);
}

SimpleXPath.ArgumentList.prototype.get = function ()
{
	var args = [this];
	var list = this;
	while (list.next)
	{
		list = list.next;
		args.push(list);
	}
	return args;
}

	Date.prototype.format = function (format)
{
	Debugger.off();
	var s = "";
	var t;
	Debugger.print("Date.format {format: "+format+"}");
	for (var i = 0; i < format.length; i++)
	{
		var ch = format.charAt(i);
		switch (ch) {
		case 'Y':
			s += this.getFullYear();
			break;
		case 'm':
			s += ((t = this.getMonth() + 1) < 10) ? "0" + t : t;
			break;
		case 'd':
			s += ((t = this.getDate()) < 10) ? "0" + t : t;
			break;
		case 'H':
			s += ((t = this.getHours()) < 10) ? "0" + t : t;
			break;
		case 'i':
			s += ((t = this.getMinutes()) < 10) ? "0" + t : t;
			break;
		case 's':
			s += ((t = this.getSeconds()) < 10) ? "0" + t : t;
			break;
		default:
			s += ch;
		}
		Debugger.print("Date.format {ch: "+ch+", s: "+s+"}");
	}
	Debugger.ret();
	return s;
}
Date.prototype.setFormat = function (date, format)
{
	Debugger.off();
	// verifica ajustes
	var ajusta = format.match(/d/) ? 'mY' : '';
	ajusta = format.match(/m/) ? 'Y' : ajusta;
	ajusta = format.match(/Y/) ? '' : ajusta;
	Debugger.print("Date.setFormat {date: "+date+", format: "+format+"}");
	Debugger.print("Date.setFormat {ajusta: "+ajusta+"}");

	var fmt = format.replace(/[sihHdm]/g, "(\\d{1,2})");
	fmt = fmt.replace(/Y/, "(\\d{1,4})");
	Debugger.print("Date.setFormat {fmt: "+fmt+"}");

	var reg = new RegExp(fmt);
	var afind = reg.exec(date);
	Debugger.print("Date.setFormat {afind: "+afind+"}");

	if (!afind) {
		Debugger.ret();
		return false;
	}

	var nowDate = new Date();
	Debugger.print("Date.setFormat {nowDate: "+nowDate+"}");
	var diffPrev, diffNow, diffNext;
	var r, year;
	var s, i, h, H, d, m, Y;

	format = format.replace(/[^sihHdmY]/g, "");
	Debugger.print("Date.setFormat {format: "+format+"}");
	for (var index = 0; index < format.length; index++) {
		var idx = index + 1;
		Debugger.print("Date.setFormat {index: "+index+", idx: "+idx+"}");
		switch (format.charAt(index)) {
		case 's':
			s = afind[idx];
			break;
		case 'i':
			i = afind[idx];
			break;
		case 'h':
			h = afind[idx];
			break;
		case 'H':
			H = afind[idx];
			break;
		case 'd':
			d = afind[idx];
			break;
		case 'm':
			m = afind[idx] - 1;
			break;
		case 'Y':
			Y = afind[idx];
		}
		Debugger.print("Date.setFormat {s: "+s+", i: "+i+", h: "+h+", H: "+H+", d: "+d+", m: "+m+", Y: "+Y+"}");
	}

	if (Y) {
		if (Y.length == 3)
			Y = Y.substr(1, 2);
		Debugger.print("Date.setFormat {Y: "+Y+"}");
		if (Y < 100) {
			if (Y.length == 1)
				Y = "0" + Y;
			Debugger.print("Date.setFormat {Y: "+Y+"}");
			var year = new String(nowDate.getFullYear());
			var prefixNow = year.substr(0, 2);
			var prefixPrev = prefixNow - 1;
			var nowYear = new Date();
			var prevYear = new Date();

			Debugger.print("Date.setFormat {prefixNow: "+prefixNow+", prefixPrev: "+prefixPrev+"}");
			
			nowYear.setFullYear(prefixNow + Y);
			prevYear.setFullYear(prefixPrev + Y);

			if (nowYear < nowDate)
				diffNow = nowDate - nowYear;
			else
				diffNow = nowYear - nowDate;

			if (prevYear < nowDate)
				diffPrev = nowDate - prevYear;
			else
				diffPrev = prevYear - nowDate;

			Y = (diffNow < diffPrev) ? prefixNow + Y : prefixPrev + Y;
			Debugger.print("Date.setFormat {Y: "+Y+"}");
		}
	}

	if (Y != null)
		this.setFullYear(Y);

	Debugger.print("Date.setFormat {s: "+s+", i: "+i+", h: "+h+", H: "+H+", d: "+d+", m: "+m+", Y: "+Y+"}");
	this.setFullDate(Y, m, d, H, i, s);

	Debugger.print("Date.setFormat {this.autoApproachDate: "+this.autoApproachDate+"}");
	if (!this.autoApproachDate)
	{
		Debugger.ret();
		return true;
	}

	for (var index = 0; index < ajusta.length; index++) {
		var ch = ajusta.charAt(index);
		switch (ch) {
		case 'm':
			Date.prototype.setAjuste = Date.prototype.setMonth;
			Date.prototype.getAjuste = Date.prototype.getMonth;
			break;
		case 'Y':
			Date.prototype.setAjuste = Date.prototype.setFullYear;
			Date.prototype.getAjuste = Date.prototype.getFullYear;
			break;
		}

		var prevDate = new Date(this);
		var nextDate = new Date(this);
		prevDate.setAjuste(prevDate.getAjuste() - 1);
		nextDate.setAjuste(nextDate.getAjuste() + 1);
		diffPrev = nowDate - prevDate;
		diffNext = nextDate - nowDate;
		diffNow;
		if (this < nowDate)
			diffNow = nowDate - this;
		else
			diffNow = this - nowDate;

		Debugger.print("Date.setFormat {ch: "+ch+"}");
		Debugger.print("Date.setFormat {prevDate: "+prevDate+", nowDate: "+nowDate+", nextDate: "+nextDate+"}");
		Debugger.print("Date.setFormat {diffPrev: "+diffPrev+", diffNow: "+diffNow+", diffNext: "+diffNext+"}");
		
		if (diffPrev < diffNext)
			if (diffNow < diffPrev)
				this.setAjuste(nowDate.getAjuste());
			else
				this.setAjuste(prevDate.getAjuste());
		else if (diffNow < diffNext)
			this.setAjuste(nowDate.getAjuste());
		else
			this.setAjuste(nextDate.getAjuste());
	}
	Debugger.print("Date.setFormat {this: "+this+"}");
	Debugger.ret();
	return true;
}

Date.prototype.setApproachDate = function (p)
{
	this.autoApproachDate = p;
}

Date.prototype.setFullDate = function (Y, m, d, H, i, s)
{
	if (s == null)
		s = 0;
	if (i == null)
		i = 0;
	if (H == null)
		H = 0;
	if (d == null)
		d = this.getDate();
	if (m == null)
		m = this.getMonth();
	if (Y == null)
		Y = this.getFullYear();
	this.setFullYear(0);
	this.setMonth(0);
	this.setDate(1);
	this.setHours(0);
	this.setMinutes(0);
	this.setSeconds(0);
	this.setFullYear(Y);
	this.setMonth(m);
	this.setDate(d);
	this.setHours(H);
	this.setMinutes(i);
	this.setSeconds(s);
}

Date.isWeekend = function (v, f)
{
	if (!(v instanceof Date))
	{
		var d = new Date();
		d.setFormat(v, f);
		v = d;
	}
	var day = v.getDay();
	return (day == 0) || (day == 6);
}

Date.prototype.getWeekIterator = function (e, bw, ew)
{
	return new WeekIterator(this, e, bw, ew);
}

WeekInterval = function (i, b, e) {
	this.i = i;
	this.b = b;
	this.e = e;
	this.index = function () {
			return this.i;
	}
	this.begin = function () {
			return this.b;
	}
	this.end = function () {
			return this.e;
	}
}
WeekIterator = function (b, e, bw, ew) {
	this.b = new Date(b);
	this.e = new Date(e);
	this.c = new Date(b);
	this.bw = bw || 0;
	this.ew = typeof(ew) != "undefined" ? ew : 6;
	this.index = 0;
}
WeekIterator.prototype.hasNext = function () {
	return this.c < this.e;
}
WeekIterator.prototype.next = function () {
	var b = new Date(this.c);
	this.c.setDate(this.c.getDate() + 7);
	// primeiro dia da semana
	b.setDate(b.getDate() - b.getDay() + this.bw);
	var e = new Date(b);
	// ultimo dia da semana
	e.setDate(b.getDate() + this.ew);
	if (b < this.b)
		b = this.b;
	if (e < this.b)
		e = this.b;
	if (b > this.e)
		b = this.e;
	if (e > this.e)
		e = this.e;
	this.index++;
	return new WeekInterval(this.index, b, e);
}
/*
** Array Extension
*/
Array.prototype.compare = function (a, b)
{
	if (a > b)
		return 1;
	if (a < b)
		return -1;
	return 0;
}

Array.prototype.setCompare = function (cmp)
{
	var cur = this.compare;
	this.compare = cmp;
	return cur;
}

Array.prototype.remove = function (value, index)
{
	index = index || 0;
	var i = this.indexOf(value, index);
	if (i != -1)
		this.splice(i, 1);
	return this;
}

Array.prototype.removeAll = function (value)
{
	var i = this.indexOf(value);
	while (i != -1)
	{
		this.splice(i, 1);
		i = this.indexOf(value, i + 1);
	}
	return this;
}

Array.prototype.forEach = function (func, obj, pred, predRet)
{
	if (typeof(predRet) == "undefined")
		predRet = true;
	Debugger.off();
	Debugger.print("Array.forEach {func: " + func + ", obj: " + obj + ", pred: " + pred + ", predRet: " + predRet + "}");
	Debugger.print("\tthis.length: {" + this.length + "}");
	for(var i=0; i < this.length; i++)
	{
		var hasBreak = false;
		if (!pred || pred(i, this) == predRet)
		{
			if (typeof(obj) == "undefined" || obj == null)
				hasBreak = func(this[i]);
			else
				hasBreak = func(this[i], obj);
			if (hasBreak)
				break;
		}
	}
	Debugger.ret();
}

Array.prototype.indexOf = function (value, index, compare)
{
	index = index || 0;
	compare = compare || this.compare;
	for(var i = index; i < this.length; i++)
		if (compare(this[i], value) == 0)
			return i;
	return -1;
}

Array.prototype.bSearch = function (value, compare)
{
	var bi = 0;
	var ei = this.length;
	var mi, cmp;
	compare = compare || this.compare;
	while (bi < ei)
	{
		mi = parseInt((bi + ei) / 2);
		cmp = compare(this[mi], value);
		if (cmp == -1)
			bi = mi + 1;
		else if (cmp == 1)
			ei = mi;
		else
			return mi;
	}
	return -1;
}

Array.prototype.lBound = function (value, compare)
{
	compare = compare || this.compare;
	var i = this.bSerach(value, compare);
	while ((i > 0) && (compare(this[i - 1], value) == 0))
		i--;
	return i;
}

Array.prototype.hBound = function (value, compare)
{
	compare = compare || this.compare;
	var i = this.bSerach(value, compare);
	var len = length - 1;
	while ((i < len) && (compare(this[i + 1], value) == 0))
		i++;
	return i;
}

Array.prototype.iterator = function()
{
	return new ArrayIterator(this);
}

/*
** ArrayIterator Extension
*/
ArrayIterator = function (a)
{
	this.a = a;
	this.index = -1;
}

ArrayIterator.prototype.hasNext = function ()
{
	return ((this.index + 1) < this.a.length) ? true : false;
}

ArrayIterator.prototype.next = function ()
{
	return this.a[++this.index];
}

/*
** String Extension
*/
String.prototype.subRange = function (fmt)
{
	var str = "";
	var ranges = String(fmt).split(";");
	for (var i=0; i < ranges.length; i++)
	{
		var limits = ranges[i].split(",");
		if (limits.length == 1)
			limits.push("");
		if (limits[0] == "")
			limits[0] = 0;
		if (limits[1] == "")
			limits[1] = 0;
		var start = parseInt(limits[0]);
		var end = parseInt(limits[1]);
		if (!end)
			end = this.length;
		str += this.substr(start, end);
	}
	return str;
}
String.prototype.lpad = function (ch, maxWidth)
{
	var t = this;
	if (ch && ch.length > 0)
		while (maxWidth >= (t.length + ch.length))
			t = ch + t;
	return t;
}
String.prototype.rpad = function (ch, maxWidth)
{
	var t = this;
	if (ch && ch.length > 0)
		while (maxWidth >= (t.length + ch.length))
			t += ch;
	return t;
}
/*
** Number Extension
*/
Number.prototype.clean = function (str)
{
	var tmp = new String(str);
	var ice = tmp.lastIndexOf(",");
	var icb = tmp.indexOf(",");
	var ipe = tmp.lastIndexOf(".");
	var ipb = tmp.indexOf(".");
	var ilast = Math.max(ice, ipe);

	// Comma is separator decimal
	var bDecimal = (icb != -1) && (icb == ice);
	// or Dot is separator decimal
	bDecimal = bDecimal || (ipb != -1) && (ipb == ipe);

	if (bDecimal) {
		var str1 = tmp.slice(0, ilast);
		str1 = str1.replace(/[.,]/g, "");
		str1 += ".";
		str1 += tmp.slice(ilast+1, tmp.length);
		return str1;
	} else {
		str = str.replace(/[.,]/g, "");
		return str;
	}
}

	/*
**	Class StyleClass
*/
StyleClass = function (elem)
{
	if (elem)
		this.setElem(elem);
}
StyleClass.prototype.setElem = function (elem)
{
	var cl = new String(elem.className);
	this.elem = elem;
	this.aStyleClass = cl.split(" ");
	return this;
}
StyleClass.prototype.set = function (name, bReplace)
{
	if (bReplace) {
		this.elem.className = name;
		return this;
	}
	if (this.isSet(name))
		this.unSet(name);
	this.aStyleClass.push(name);
	this.elem.className = this.aStyleClass.join(" ");
	return this;
}
StyleClass.prototype.unSet = function (name)
{
	this.aStyleClass.remove(name);
	this.elem.className = this.aStyleClass.join(" ");
	return this;
}
StyleClass.prototype.isSet = function (name)
{
	return (this.aStyleClass.indexOf(name) != -1);
}
/*
**	Class MSelect - Manager selects
*/
MSelect = function (elem) {
	this.elem = elem;
}
MSelect.prototype.clear = function (preserve) {
	var i = 0;
	var options = [];
	if (this.elem.length)
		if ((this.elem.options[0].value == "") && preserve)
			i = 1;
	while (this.elem.length > i) {
		options.push(this.elem.options[i]);
		this.elem.remove(i);
	}
	return options;
}
MSelect.prototype.add = function (option, before) {
	if (typeof(before) == "undefined")
		before = null;
	for (var index = 0; index < this.elem.length; index++) {
		var opt = this.elem.options[index];
		if (opt == before)
			break;
	}
	try {
		this.elem.add(option, index);
	} catch (e) {
		this.elem.add(option, before);
	}
}
MSelect.prototype.addAll = function (options, before) {
	for (var i = 0; i < options.length; i++)
		this.add(options[i], before);
}
MSelect.prototype.getElement = function () {
	return this.elem;
}
MSelect.prototype.createOption = function (value, label, selected, def) {
	return new Option(label, value, def, selected);
}
MSelect.prototype.getLength = function () {
	return this.elem.length;
}
MSelect.prototype.getIndex = function () {
	return this.elem.selectedIndex;
}
MSelect.prototype.setIndex = function (index) {
	this.elem.selectedIndex = index;
}
MSelect.prototype.getOption = function (index) {
	if (index >= this.elem.length)
		throw "Out Range";
	return this.elem.options[index];
}
/*
**	Class VSSelect - View State for MSelect
*/
VSSelect = function (mselect) {
	this.mselect = mselect;
	this.state = [];
}
VSSelect.prototype.saveState = function () {
	var options = [];
	var length = this.mselect.getLength();
	for (var i = 0; i < length; i++) {
		options.push(this.mselect.getOption(i));
	}
	var index = this.mselect.getIndex();
	this.state.push({options: options, index: index});
}
VSSelect.prototype.loadState = function () {
	var o = this.state[this.state.length-1];
	this.mselect.clear();
	this.mselect.addAll(o.options);
	this.mselect.setIndex(o.index);
}
VSSelect.prototype.popState = function () {
	return this.state.pop();
}
/*
**	Class TableSort
*/
TableSort = function (elem, fmt, nIgnore)
{
	this.parent = elem.parentNode;
	if (!this.parent.oTableSort) {
		this.classDown = "arrowDOWN";
		this.classUp = "arrowUP";
		this.parent.oTableSort = this;
		this.createRows(nIgnore);
	}
	elem.oTableSort = this.parent.oTableSort;
	elem.oTableSortFormat = this.format(fmt);
	elem.oTableSort.makeKeys(elem);
}
TableSort.prototype.createRows = function (nIgnore)
{
	var row = this.parent;
	this.rows = [];
	while (row = row.nextSibling) {
		if (row.nodeType != 1)
			continue;
		row.oTableSort = this;
		this.rows.push(row);
	}
	// It ignores nIgnore lines of the end
	this.rows.splice(this.rows.length - nIgnore, nIgnore);
	this.rows.groupIndex = [];
}
TableSort.prototype.makeKeys = function (elem)
{
	var format = elem.oTableSortFormat;
	var index = elem.cellIndex;
	for (var i=0; i < this.rows.length; i++) {
		var row = this.rows[i];
		var col = row.cells.item(index);
		var str = this.findText(col);
		var key = "";
		switch (format.type) {
		case "n":
			key = parseFloat(Number().clean(str));
			break;
		case "s":
			key = str.subRange(format.ranges);
			break;
		case "S":
			key = str.subRange(elem.fmtSort.ranges).toUpperCase();
			break;
		}
		col.oTableSortKey = key;
	}
	elem.oTableSortAscending = true;
	Listener.add(elem, "click", [this, "onClick"]);
}
TableSort.prototype.findText = function (node)
{
	var ELEMENT_NODE = 1;
	var TEXT_NODE = 3;
	var no, ret;
	for(var i=0; i < node.childNodes.length; i++) {
		no = node.childNodes.item(i);
		if(no.nodeType == ELEMENT_NODE) {
			return this.findText(no);
		}
		if(no.nodeType == TEXT_NODE) {
			var str = new String(no.nodeValue);
			str = str.replace(/[ \r\t\n]*/g, "");
			if(str.length > 0)
				return str;
		}
	}
	return "";
}
TableSort.prototype.compare = function (a, b)
{
	var groupIndex = a.oTableSort.rows.groupIndex;
	var cells = a.oTableSort.parent.cells;
	for (var i=0; i < groupIndex.length; i++) {
		var index = groupIndex[i];
		var keyA = a.cells.item(index).oTableSortKey;
		var keyB = b.cells.item(index).oTableSortKey;
		var ascending = cells.item(index).oTableSortAscending;
		if (ascending) {
			if (keyA > keyB) return -1;
			if (keyA < keyB) return 1;
		} else {
			if (keyA > keyB) return 1;
			if (keyA < keyB) return -1;
		}
	}
	return 0;
}
TableSort.prototype.sort = function ()
{
	this.rows.sort(this.compare);
	var table = this.parent.parentNode;
	for (var i = 0; i < this.rows.length; i++)
		table.insertBefore(this.rows[i], this.parent.nextSibling);
	var sib = this.parent;
	for (var row = 0; row < this.oTableSortnIgnore ; row++) {
		sib = sib.nextSibling;
		while (sib && sib.nodeType != 1) // Element node
			sib = sib.nextSibling;
		table.appendChild(sib);
	}
}
TableSort.prototype.onClick = function (evt)
{
	var elem = evt.src;
	var c = new StyleClass();
	var bInGroup = this.rows.groupIndex.indexOf(elem.cellIndex) != -1;

	if (bInGroup && (evt.ctrlKey || elem == this.lastElem))
		elem.oTableSortAscending = !elem.oTableSortAscending;
	this.lastElem = elem;

	if (!evt.ctrlKey) {
		for (var i=0; i < this.rows.groupIndex.length; i++) {
			var index = this.rows.groupIndex[i];
			var col = this.parent.cells.item(index);
			c.setElem(col);
			c.unSet(this.classDown);
			c.unSet(this.classUp);
		}
		this.rows.groupIndex = [];
	}
	c.setElem(elem);
	if (elem.oTableSortAscending) {
		c.set(this.classDown);
		c.unSet(this.classUp);
	} else {
		c.set(this.classUp);
		c.unSet(this.classDown);
	}
	if (this.rows.groupIndex.indexOf(elem.cellIndex) == -1)
		this.rows.groupIndex.push(elem.cellIndex);
	this.sort();
}
TableSort.prototype.format = function (fmt)
{
	var format = new Object();
	if (!fmt) {
		format.type = "s";
		return format;
	}
	var sfmt = fmt.split(":");
	format.type = sfmt[0];
	if (!sfmt[1])
		return format;
	format.ranges = sfmt[1];
	return format;
}
/*
**	Class Subject
**
**	It´s a notifier of Observers
*/
Subject = function ()
{
	this.observers = [];
}
Subject.prototype.attach = function (observer)
{
	this.observers.push(observer);
}
Subject.prototype.detach = function (observer)
{
	this.observers.remove(observer)
}
Subject.prototype.notify = function (o)
{
	var i = this.observers.iterator();
	while (i.hasNext()) {
		var ret = i.next().update(o);
		if (!ret)
			return false;
	}
	return true;
}
/*
**	Class Handler
**
**	It´s a Chain of resposability
*/
Handler = function (sucessor)
{
	this.setHandler(sucessor);
}
Handler.prototype.setHandler = function (sucessor)
{
	if (sucessor instanceof Handler)
		this.sucessor = sucessor;
}
Handler.prototype.requestSucessor = function (o)
{
	if (this.sucessor)
		this.sucessor.request(o);
}
Handler.prototype.request = function (o)
{
	this.requestSucessor(o);
}
/*
**	Class CEvent
*/
CEvent = function (oEvent)
{

	var auxEvent;
	this.oEvent = oEvent;

	// Differentiated
	if (Navigator.hasFeature(oEvent, "event"))
		auxEvent = oEvent;
	else if (Navigator.hasFeature(event, "event"))
		auxEvent = event;
	else
		throw Exception("CEvent: not exists event object");
	
	if (Navigator.hasFeature(auxEvent, "srcElement"))
		this.src = auxEvent.srcElement;
	else if (Navigator.hasFeature(auxEvent, "currentTarget"))
		this.src = auxEvent.currentTarget;
	else
		this.src = null;

	if (Navigator.hasFeature(auxEvent, "charCode"))
		this.charCode = auxEvent.charCode;
	else
		this.charCode = auxEvent.keyCode;

	this.keyCode = auxEvent.keyCode;
	this.ctrlKey = auxEvent.ctrlKey;
	this.shiftKey = auxEvent.shiftKey;
	this.clientX = auxEvent.clientX;
	this.clientY = auxEvent.clientY;
	this.x = auxEvent.x;
	this.y = auxEvent.y;
}
CEvent.prototype.stopPropagation = function ()
{
	var oEvent = this.oEvent;
	if (!oEvent)
		oEvent = event;
	oEvent.cancelBubble = true;
	if (Navigator.hasFeature(oEvent, "stopPropagation"))
		oEvent.stopPropagation();
}
CEvent.prototype.cancel = function ()
{
	if (oNav.is(oNav.IE))
		event.returnValue = false;
	if (this.oEvent.cancelable)
		this.oEvent.preventDefault();
}
/*
**	Class NodeArray
*/
NodeArray = function (nodes, types)
{
	if (typeof(types) == "undefined")
		types = [1]; // types of nodes definined in DOM 1
	var hasItem = (typeof(nodes.item) == "function");
	var node;
	for (var i = 0; i < nodes.length; i++) {
		if (hasItem)
			node = nodes.item(i);
		else
			node = nodes[i];
		if (types.length && (types.indexOf(node.nodeType) == -1))
			continue;
		this.push(node);
	}
}
NodeArray.prototype = new Array;
/*
**	Class ElementIterator
*/
ElementIterator = function (elems)
{
	this.index = -1;
	this.elems = elems;
	this.length = elems.length;
}
ElementIterator.prototype.hasNext = function ()
{
	var index = 1;
	var elem = this.elems[this.index + index];
	if (elem && elem.nodeType) {
		do {
			if (elem.nodeType == 1)
				break;
			else
				index++;
			elem = this.elems[this.index + index];
		} while (elem)
	}
		
	return elem && ((this.index + index) < this.length) ? true : false;
}
ElementIterator.prototype.next = function ()
{
	var elem = this.elems[++this.index];
	if (elem && elem.nodeType) {
		do {
			if (elem.nodeType == 1)
				break;
			else
				elem = this.elems[++this.index];
		} while (elem);
	}
	return elem;
}
/*
**	Class ExIter
*/
ExIter = function ()
{
	return {
		forEach: function (iter, visitor)
		{
			while (iter.hasNext())
			{
				var item = iter.next();
				if (visitor.filter(item))
					continue;
				if (!visitor.visit(item))
					return false;
			}
			return true;
		}
	};
}();

	RuleSheet = function (doc)
{
	this.sxpXml = new SimpleXPath(doc);
	this.sxpHtml = new SimpleXPath(document);
}

RuleSheet.prototype.process = function ()
{
	this.processElement(null);
}

RuleSheet.prototype.processElement = function (element)
{
	var rulesheets = this.sxpXml.select("/rulesheet");
	if (rulesheets.length)
		this.applyMatch(rulesheets[0], element, 0);
}

RuleSheet.prototype.applyMatch = function (xmlContext, htmlContext, level)
{
/*
	Debugger.on();
*/
	var matches = this.sxpXml.select("match", xmlContext);
	for (var i=0; i < matches.length; i++)
	{
		var match = matches[i];
		var select = match.getAttribute("select");
		var elements = this.sxpHtml.select(select, htmlContext);
		if (elements.length)
		{
			var attributes = this.sxpXml.select("attribute", match);
			var runs = this.sxpXml.select("run", match);
			if (attributes.length)
				this.applyAttributes(elements, attributes);
			if (runs.length)
				this.applyRuns(elements, runs);
			this.applyMatch(match, elements, level + 1);
		}
	}
}

RuleSheet.prototype.applyAttributes = function (elems, attributes)
{
	for (var i=0; i < elems.length; i++)
		for (var j=0; j < attributes.length; j++)
			this.applyAttribute(elems[i], attributes[j]);
}

RuleSheet.prototype.applyRuns = function (elems, runs)
{
	for (var i=0; i < elems.length; i++)
		for (var j=0; j < runs.length; j++)
			this.applyRun(elems[i], runs[j]);
}

RuleSheet.prototype.applyAttribute = function (elem, rule)
{
	var name = rule.getAttribute("name");
	var dynamic = rule.getAttribute("dynamic");
	var pointer = rule.getAttribute("function");
	var value = ""
	if (rule.firstChild)
		value = new String(rule.firstChild.nodeValue);
	var attrib = getAttribute(elem, name);
	attrib = (attrib == null) ? "" : new String(attrib);
	if (pointer == null)
		setAttribute(elem, name, value);
	else {
		if (dynamic) {
			if (attrib != "")
				attrib = attrib.replace(/void/, pointer);
		} else
			attrib += value;
		if (attrib != "")
			setAttribute(elem, name, attrib);
	}
}

RuleSheet.prototype.applyRun = function (elem, rule)
{
	/* rule corresponde ao nó abaixo:
	** <run name="inputDate" dynamic="true" param="onfocus" />
	** <run name="setID" param="void('toolset')" />
	**
	** name: nome da função a ser execultada
	** dynamic: indica onde localizar os parametros adicionais para a função
	**	- true : localiza o parametro dado em param no attributo do elemento
	**		que no exemplo é o onfocus.
	**	- false: localiza o parametro no proprio attributo param do elemento
	**		run.
	**	param: pode assumir papeis distintos conforme o attributo dynamic.
	**
	** As chamadas serão chamadas como:
	**	-	inputDate(element, 'abcde'); // supondo que o attributo do element sejá onfocus="void('abcde')"
	**	-	setID(element, 'toolset');
	*/
/*
	Debugger.on();
	Debugger.print("elem: " + elem.tagName);
*/
	var name = rule.getAttribute("name");
	var param = rule.getAttribute("param");
	if (rule.getAttribute("dynamic") != null)
		param = elem.getAttribute(param);
	var pointer;
	eval("pointer = " + name);
	if (typeof(pointer) != "function")
		return;
	if (param != null) {
		if (typeof(param) == "function") {
			param = String(param);
			var b = param.indexOf("{");
			var e = param.lastIndexOf("}");
			param = param.substring(b + 1, e - 1);
		}
		param = String(param).replace(/.*void\(([^\)]+)\).*/, "$1");
	}
	if (param)
		eval("pointer(elem, " + param + ")");
	else
		pointer(elem);
}

	DOMUtils = function () {
	return {
		removeTextNode: function (node, deep) {
			var i, no;
			for (i = 0; no = node.childNodes.item(i); i++) {
				if (no.nodeType != 1) {
					node.removeChild(no);
					continue;
				}
				if (deep)
					this.removeTextNode(no, deep);
			}
			return node;
		},
		createXMLDocument: function () {
			var doc;
			if (Navigator.hasFeature(typeof(ActiveXObject)))
				doc = new ActiveXObject("Msxml2.DOMDocument.3.0");
			else if (Navigator.hasFeature(typeof(document.implementation.createDocument)))
				doc = document.implementation.createDocument("", "", null);
			if (!doc)
				throw "1:createXMLDocument";
			var pi = doc.createProcessingInstruction("xml", "version='1.0'");
			doc.appendChild(pi);
			return doc;
		},
		createXMLHttpRequest: function () {
			var xmlhttp;
			if (Navigator.hasFeature(typeof(XMLHttpRequest)))
				xmlhttp = new XMLHttpRequest();
			else if (Navigator.hasFeature(typeof(ActiveXObject)))
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			if (!xmlhttp)
				throw new Exception("createXMLHttpRequest: not supported");
			return xmlhttp;
		},
		createXRequest: function (operation, ret) {
			var xmlns = "http://www.amixsi.com.br/mdr/xrequest";
			var doc = this.createXMLDocument();
			var request;
			if (doc.implementation && doc.implementation.hasFeature("Core", "2.0")) {
				request = doc.createElementNS(xmlns, "request");
			} else {
				request = doc.createElement("request");
				request.setAttribute("xmlns", xmlns);
			}
			request.setAttribute("return", ret ? "true" : "false");
			request.setAttribute("operation", operation);
			doc.appendChild(request);
			return doc;
		},
		getXResponseMessage: function (response) {
			var node;
			for (var i = 0; node = response.childNodes.item(i); i++) {
				if (node.nodeType != 1)
					continue;
				var name = new String(node.nodeName);
				if (name.indexOf("message") != -1)
					return node.firstChild.nodeValue;
			}
			return null;
		},
		post: function (url, doc) {
			var xmlhttp = this.createXMLHttpRequest();
			xmlhttp.open("POST", url, false);
			xmlhttp.setRequestHeader("Content-Type", "text/xml");
			xmlhttp.send(doc);
			if (xmlhttp.status != "200")
				throw new Exception("xpost: response invalid");
			Debugger.on();
			Debugger.print("DOMUtils.post() \n"+htmlentities(xmlhttp.responseText)+"\n");
			Debugger.off();
			return xmlhttp.responseXML;
		},
		get: function (url) {
			var xmlhttp = DOMUtils.createXMLHttpRequest();
			xmlhttp.open("GET", url, false);
			xmlhttp.send(null);
			return xmlhttp.responseXML;
		},
		getText: function (url) {
			var xmlhttp = DOMUtils.createXMLHttpRequest();
			xmlhttp.open("GET", url, false);
			xmlhttp.send(null);
			return xmlhttp.responseText;
		},
		postAsync: function (url, doc, o) {
			var xmlhttp = DOMUtils.createXMLHttpRequest();
			xmlhttp.open("POST", url, true);
			xmlhttp.setRequestHeader("Content-Type", "text/xml");
			xmlhttp.onreadystatechange = function ()
			{
				DOMUtils.asyncHandler(xmlhttp, o);
			}
			xmlhttp.send(doc);
			return xmlhttp;
		},
		getAsync: function (url, o) {
			/*
			 * Possible values of xmlhttp.readyState:
			 * 0 UNINITIALIZED open() has not been called yet. 
			 * 1 LOADING send() has not been called yet. 
			 * 2 LOADED send() has been called, headers and status are available. 
			 * 3 INTERACTIVE Downloading, responseText holds the partial data. 
			 * 4 COMPLETED Finished with all operations.
			 */		
			var xmlhttp = DOMUtils.createXMLHttpRequest();
			xmlhttp.open("GET", url, true);
			xmlhttp.onreadystatechange = function ()
			{
				DOMUtils.asyncHandler(xmlhttp, o);
			}
			xmlhttp.send(null);
		},
		asyncHandler: function (xmlhttp, o) {
			if (xmlhttp.readyState == 0 && typeof(o.uninitialized) == "function")
				o.uninitialized(xmlhttp);
			if (xmlhttp.readyState == 1 && typeof(o.loading) == "function")
				o.loading(xmlhttp);
			if (xmlhttp.readyState == 2 && typeof(o.loaded) == "function")
				o.loaded(xmlhttp);
			if (xmlhttp.readyState == 3 && typeof(o.interactive) == "function")
				o.interactive(xmlhttp);
			if (xmlhttp.readyState == 4) {
				if (typeof(o.completed) == "function")
					o.completed(xmlhttp);
				if (typeof(o.onload) == "function") {
					if (xmlhttp.status == 200)
						o.onload(xmlhttp);
					else if (typeof(o.onfail) == "function")
						o.onfail(xmlhttp);
				}
			}
		},
		copyNodeFromXml: function(doc, xmlNode) {
			var c;
			if (xmlNode.nodeType == 1) {
				c = doc.createElement(xmlNode.nodeName);
				for (var i=0; i < xmlNode.attributes.length; i++) {
					var attribute = xmlNode.attributes.item(i);
					if (attribute.nodeName == "class")
						c.className = attribute.nodeValue;
					c.setAttribute(attribute.nodeName, attribute.nodeValue);
				}
				for (var i=0; i < xmlNode.childNodes.length; i++) {
					var child = this.copyNodeFromXml(doc, xmlNode.childNodes.item(i))
					if (child)
						c.appendChild(child);
				}
			} else if (xmlNode.nodeType == 3) {
				c = doc.createTextNode(xmlNode.data);
			}
			return c;
		}
	};
}();

	function getPosition(o) {
	var left = 0, top = 0;
	var right = 0, bottom = 0;
	var elem = o;
	while (elem) {
		left += elem.offsetLeft;
		top += elem.offsetTop;
		elem = elem.offsetParent;
	}
	if (o) {
		right = left + o.offsetWidth;
		bottom = top + o.offsetHeight;
	}
	return {left: left, top: top, right: right, bottom: bottom};
}
/*
** alignBlock - align element oAlign relative element oAnchor.
** axis: "0;0" align (left, top)
** axis: "100;0" align (right, top)
** axis: "0;100" align (left, bottom)
** axis: "100;100" align (right, bottom)
** axis: "x;y" align (left + x% * width, top + y% * height)
** dX: offsetX absolute
** dY: offsetY absolute
*/
function alignBlock(oAlign, axisAlign, oAnchor, axisAnchor, dX, dY) {
	if (dX == undefined)
		dX = 0;
	if (dY == undefined)
		dY = 0;
	var pos = getPosition(oAnchor);
	var x = 0, y = 0;
	var axis = String(axisAnchor).split(";");
	// i = 0, axis[0] =	0 => left
	// i = 0, axis[0] =	100 => right
	// i = 1, axis[1] =	0 => top
	// i = 1, axis[1] =	100 => bottom
	for (var i = 0; axis[i]; i++) {
		switch (i) {
		case 0:
			x = pos.left + Math.ceil(axis[i] * (pos.right - pos.left) / 100);
			break;
		case 1:
			y = pos.top + Math.ceil(axis[i] * (pos.bottom - pos.top) / 100);
			break;
		}
	}
	oAlign.style.position = "absolute";
	var dx = 0, dy = 0;
	var dAxis = String(axisAlign).split(";");
	for (var i = 0; dAxis[i]; i++) {
		switch (i) {
		case 0:
			dx = -Math.ceil(dAxis[i] * oAlign.offsetWidth / 100);
			break;
		case 1:
			dy = -Math.ceil(dAxis[i] * oAlign.offsetHeight / 100);
			break;
		}
	}
	oAlign.style.left = x + dx + dX + "px";
	oAlign.style.top = y + dy + dY + "px";
	//alert("x = " + x + "; y = " + y + "; dx = " + dx + "; dy = " + dy);
}
function pageOffsetY() {
	var docElem = document.documentElement;
	var offsetY = docElem.scrollTop;
	return offsetY;
}
function intToPx(i) {
	return i + "px";
}

	/*	
**	defaultFormat: Object
**		Attributes:
**		Format compatible with Date.setFormat
**		-date
**		-time
*/
var defaultFormat = {date: "d/m/Y", time: "H:i"};
var isIE, isGE;
if (document.all)
	isIE = true;
else
	isGE = true;

var changed = false;
var prevChanged = changed; // readonly

function setChange(b)
{
	var apply = document.getElementById("apply");
	if (!apply)
		return;
	prevChanged = changed;
	changed = b;
	var visitor = {
		filter: function (e) {
			var oper = String(e.action).substr(-1);
			return (oper != "I") && (oper != "U");
		},
		visit: function (e) {
			if (changed) {
				setClass(apply, "applyChanged");
				Dispatcher.onChangeForm.notify(e);
			} else {
				unSetClass(apply, "applyChanged");
			}
			return true;
		}
	}
	var i = new ElementIterator(document.forms);
	ExIter.forEach(i, visitor);
}

function showByValue(newValue, constValue, ids)
{
	var tags =["input", "select", "textarea"];
	var id;
	for (var i = 0; id = ids[i]; i++) {
		var elem = document.getElementById(id);
		for (var a = 0; a < tags.length; a++) {
			var tag = tags[a];
			var elems = elem.getElementsByTagName(tag);
			for (var e = 0; e < elems.length; e++) {
				if (newValue == constValue)
					replaceClass(elems[e], "norequired", "required");
				else
					replaceClass(elems[e], "required", "norequired");
			}
		}
		if (newValue == constValue)
			unSetClass(elem, "hidden");
		else
			setClass(elem, "hidden");
	}
}

function daysDiff(d1, d2, fmt)
{
	var dt1 = new Date();
	var dt2 = new Date();
	if (typeof(fmt) == "undefined")
		fmt = defaultFormat.date;
	dt1.setFormat(d1, fmt);
	dt2.setFormat(d2, fmt);
	// assigned difference at milliseconds
	var diff = dt1 - dt2;
	diff /= 3600000 * 24;
	diff = parseInt(diff);
	return diff;
}

function installXSubmit(elem)
{
	Listener.add(elem, "click", onXSubmit);
}
function installReQuery(elem)
{
	Listener.add(elem, "click", reQuery);
}

function installToolSet(elem)
{
	Listener.add(elem, "click", ToolSet.prototype.submit);
}

function reQuery(evt)
{
	if (evt.shiftKey)
		window.location = "Q0";
	else if (evt.ctrlKey)
		window.location = "QR";
}

function onXSubmit(evt)
{
	if (!evt.shiftKey)
		return true;
	var form = evt.src.form;
	setChange(!xSubmit(form));
	evt.cancel();
	return false;
}

function disableOtherOptions(elem)
{
	var opts = elem.options;
	for (var i = 0; i < opts.length; i++) {
		var opt = opts.item(i);
		opt.disabled = (i != elem.selectedIndex);
	}
}

function getForm(name, win)
{
	var win = win || window;
	return (win.document.all) ? win.document.forms[name] : win.document.forms.item(name);
}

function optionDisabled(oSelect)
{
	setChange(true);
	if (oSelect.selectedIndex < 0)
		return false;
	var option = oSelect.options.item(oSelect.selectedIndex);
	if (!option)
		return false;
	var isDisabled = option.disabled;
	if (isDisabled) {
		for (var i = 0; i < oSelect.options.length; i++)
			if (oSelect.options.item(i).defaultSelected)
				break;
		oSelect.selectedIndex = i;
		return true;
	}
	return false;
}

Dispatcher = function ()
{
	return {
		onPreLoad: new Subject(),
		onPosLoad: new Subject(),
		onDelete: new Subject(),
		onPreSubmit: new Subject(),
		onSubmit: new Subject(),
		onChangeForm: new Subject()
	};
}();

function enterNext(e)
{
	var o = function (a, b)
	{
		var d = a.tabIndex - b.tabIndex;
		if (!d)
			return 0;
		return (d < 0) ? -1 : 1;
	}
	var f = function (evt)
	{
		if (evt.keyCode == 13 && e.form) {
			var list = [];
			for (var i = 0; i < e.form.elements.length; i++) {
				var element = e.form.elements[i];
				var st = new StyleClass(element);
				if (element.tabIndex && st.isSet("enter"))
					list.push(element);
			}
			if (list.length) {
				list.sort(o);
				var index = -1;
				for (var i = 0; i < list.length; i++) {
					var element = list[i];
					if (element == e) {
						index = i;
						break;
					}
				}
				index = (index + 1) % list.length;
				list[index].focus();
				return false;
			}
		}
		return true;
	}
	Listener.add(e, "keydown", f);
}

ReadOnlyTabIndex = function ()
{
	this.doc = document;
}
ReadOnlyTabIndex.prototype.skip = function (form)
{
	if (!form.elements.length)
		return;
	var index = parseInt(form.elements[0].tabIndex) + 1;
	for (var i = 0; i < form.elements.length; i++)
	{
		var element = form.elements[i];
    if (element.readOnly || element.type == "hidden" || element.disabled)
			element.tabIndex = index;
 
	}
}

ReadOnlyTabIndex.prototype.update = function ()
{
	for (var i = 0; i < this.doc.forms.length; i++)
		this.skip(this.doc.forms[i]);
	return true;
}

var roti = new ReadOnlyTabIndex();
Dispatcher.onPosLoad.attach(roti);

function load()
{
	//Debugger.onload();
	Dispatcher.onPreLoad.notify();
	if (document.body.style)
		document.body.style.cursor = "auto";
	var fi = new ElementIterator(document.forms);
	while (fi.hasNext()) {
		var form = fi.next();
		focus(form);
		updateXValues(form);
	}
	var li = new ElementIterator(document.getElementsByTagName("link"));
	while (li.hasNext()) {
		var link = li.next();
		var href = link.getAttribute("href");
		switch (link.getAttribute("rel")) {
		case "rulesheet":
			var handlerRules = {
				onload: function (xmlhttp) {
					var ruleSheet = new RuleSheet(xmlhttp.responseXML);
					ruleSheet.process();
					Register.set(ruleSheet, "ruleSheet");
					initTool();
					saveViewStates();
					Dispatcher.onPosLoad.notify();
				},
				onfail: function () {
					throw new Exception("Not found('"+href+"')");
				}
			};
			DOMUtils.getAsync(href, handlerRules);
			break;
		case "menu":
			var handlerMenu = {
				onload: function (xmlhttp) {
					createMenubar(xmlhttp.responseXML.documentElement);
				},
				onfail: function () {
					throw new Exception("Not found('"+href+"')");
				}
			}
			DOMUtils.getAsync(href, handlerMenu);
			break;
		}
	}
}

function saveViewStates(overwrite)
{
	reloadSelects();
	var vstates = [];
	var fi = new ElementIterator(document.forms);
	while (fi.hasNext()) {
		var ei = new ElementIterator(fi.next().elements);
		while (ei.hasNext()) {
			var elem = ei.next();
			if (elem.tagName == "SELECT") {
				var vs = new VSSelect(new MSelect(elem));
				vs.saveState();
				vstates.push(vs);
			}
		}
	}
	Register.set(vstates, "ViewStates", overwrite);
}

function loadViewStates()
{
	var fi = new ElementIterator(document.forms);
	while (fi.hasNext())
		fi.next().reset();
	var i = Register.get("ViewStates").iterator();
	while (i.hasNext())
		i.next().loadState();
	reloadSelects();
	return false;
}

function setAttribute(elem, name, value)
{
	var events =["onchange", "onclick", "onbeforeunload", "onsubmit", "onreset", "onfocus"];
	switch (oNav.type) {
	case oNav.IE:
		var version = oNav.getVersion();
		if (version && version.major >= 8) {
			elem.setAttribute(name, value);
		} else {
			if (events.indexOf(name) != -1)
				value = new Function(value);
			elem.setAttribute(name, value);
		}
		break;
	case oNav.GE:
		elem.setAttribute(name, value);
		break;
	}
}

function getAttribute(elem, name, value)
{
	if (elem.getAttribute(name, value) == null)
		return null;
	var attrib;
	switch (oNav.type) {
	case oNav.IE:
		var ss = new String(elem.getAttribute(name, value));
		var ib = ss.indexOf("{");
		var ie = ss.lastIndexOf("}");
		if (ib < ie)
			attrib = ss.substring(ib + 1, ie - 1);
		else
			attrib = ss;
		break;
	case oNav.GE:
		attrib = elem.getAttribute(name, value);
		break;
	}
	return attrib;
}

function setLocation(url)
{
	location = url;
}

function onDelete(url, bConfirm)
{
	var ret = true;
	if (bConfirm)
		ret = confirm(msgs["delete"]);
	if (ret)
		ret = Dispatcher.onDelete.notify(url);
	if (!ret)
		return ret;
	if (ret)
		location = url;
}

function focus(form)
{
	if (!form)
		return false;
	try {
		var i = new ElementIterator(form.elements);
		var visitor = {
			filter: function (e) {
				return (!e.focus || e.disabled || e.readOnly || !e.type || !e.name || (e.type == 'hidden'));
			},
			visit: function (e) {
				try {
					e.focus();
				} catch (e) {
				}
				return false;
			}
		}
		ExIter.forEach(i, visitor);
	}
	catch(e) {
		throw e;
	}
}

function checkMessages(elem, type)
{
	switch (type) {
	case "active":
		if (elem.firstChild)
			alert(elem.firstChild.nodeValue);
		else
			alert("Alerta desconhecido.");
		break;
	case "activeback":
		if (elem.firstChild)
			alert(elem.firstChild.nodeValue);
		else
			alert("Alerta desconhecido.");
		history.back(-1);
		break;
	case "interactive":
		if (confirm(elem.nodeValue))
			history.back(-1);
		break;
	default:
		var div = document.createElement("div");
		div.id = "alert";
		document.body.appendChild(div);
		floatLayer(div, elem, -270, 50);
	}
}

function isEmpty(elem)
{
	var value = "";
	if (elem.name == "")
		return true;
	switch (elem.tagName) {
	case "INPUT":
		if (elem.type == "hidden")
			return true;
		//if (elem.type == "checkbox" || elem.type == "radio")
			//return !elem.checked;
	case "TEXTAREA":
	case "SELECT":
		value = elem.value;
		break;
	}
	if (value != "")
		return false;
	return true;
}

function countFilled(form)
{
	if (!form)
		return 0;
	var count = 0;
	var i = new ElementIterator(form.elements);
	var visitor = {
		filter: function (e) {
			return isEmpty(e);
		},
		visit: function (e) {
			count++;
			return true;
		}
	}
	ExIter.forEach(i, visitor);
	return count;
}

function checkForm(form, count)
{
	var elem, elemFocus;
	var req, ask;
	var listReq = new Array();
	var msg = "";
	var ret = Dispatcher.onPreSubmit.notify(form);
	if (!ret)
		return false;
	for (var i = 0; elem = form.elements[i]; i++) {
		if (!String(elem.value).match(/^ *$/))
			continue;
		req = isSetClass(elem, 'required') && !elem.getAttribute('disabled');
		ask = isSetClass(elem, 'asked');
		if (!req && !ask)
			continue;
		msg = (elem.title ? elem.title : elem.name);
		if (req) {
			listReq.push(msg);
			if (!elemFocus && (elem.focus && !elem.disabled && !elem.readOnly && elem.type && elem.name && (elem.type != 'hidden')))
				elemFocus = elem;
		}
		else if (confirm(vsprintf(msgs["conf"],[msg])))
			continue;
		ret = false;
	}
	if (elemFocus)
		elemFocus.focus();
	if (listReq.length > 0) {
		var m = vsprintf(msgs["req"],[listReq.join(", ")]);
		alert(m);
	}
	if (count > 0 && count > countFilled(form)) {
		alert(vsprintf(msgs["reqfields"],[count]));
		ret = false;
	}
	if (ret)
		ret = Dispatcher.onSubmit.notify(form);

	if (ret)
		setChange(false);
	return ret;
}

function selectConfirm(elem, msg)
{
	if (!elem.defaultSelectedIndex) {
		var opt = elem.options;
		for (var i = 0; i < opt.length; i++)
			if (opt.item(i).defaultSelected)
				elem.defaultSelectedIndex = i;
	}
	if (!elem.confirmed)
		elem.confirmed = window.confirm(msg);

	if (!elem.confirmed)
		elem.selectedIndex = elem.defaultSelectedIndex;

	return elem.confirmed;
}

function vsprintf(fmt, arg)
{
	var idxArg = 0;
	if (!arg)
		return fmt;
	while ((fmt.indexOf("%s") != -1) && (idxArg < arg.length)) {
		fmt = fmt.replace(/%s/, arg[idxArg]);
		idxArg++;
	}
	return fmt;
}

function pageY()
{
	if (oNav.is(oNav.IE)) {
		return getDocumentElement().scrollTop;
	} else {
		return window.pageYOffset;
	}
}

function getDocumentElement(doc)
{
	doc = doc || document;
	return (doc.documentElement) ? doc.documentElement : doc.body;
}

function selectAll(elem)
{
	if (!elem || !elem.options)
		return false;
	for (var i = 0; i < elem.options.length; i++) {
		if (elem.options.item(i).selected)
			return false;
	}
	for (var i = elem.options.length - 1; i >= 0; i--) {
		elem.options.item(i).selected = true;
	}
	return true;
}

function getTemplate(template, elem, dir)
{
	var ancestor = 1;
	var descendant = 2;
	var previous = 3;
	var following = 4;
	var cur = elem;
	var old, ret;
	if (cur) {
		if (String(" " + cur.className + " ").indexOf(" " + template + " ") != -1)
			return cur;
		switch (dir) {
		case ancestor:
			return getTemplate(template, cur.parentNode, dir);
		case descendant:
			cur = elem.firstChild;
			for (; cur; cur = cur.nextSibling)
				if (ret = getTemplate(template, cur, dir))
					break;
			return ret;
		case previous:
			old = cur;
			while (cur) {
				for (cur = cur.previousSibling; cur; cur = cur.previousSibling)
					if (ret = getTemplate(template, cur, descendant))
						return ret;
				if (old.parentNode) {
					old = old.parentNode;
					if (ret = getTemplate(template, old))
						return ret;
					cur = old;
				}
			}
			return cur;
		case following:
			old = cur;
			while (cur) {
				for (cur = cur.nextSibling; cur; cur = cur.nextSibling) {
					if (ret = getTemplate(template, cur, descendant))
						return ret;
				}
				if (old.parentNode) {
					old = old.parentNode;
					cur = old;
				}
			}
			return cur;
		}
	}
}

function copyTemplate(input, level)
{
	var elem = getTemplate("template", input, 3);
	if (!elem)
		return false;
	elem.parentNode.insertBefore(elem.cloneNode(true), elem);
	return true;
}

function deleteTemplate(input)
{
	var elem = getTemplate("template", input, 1);
	if (getTemplate("template", elem.previousSibling, 3) || getTemplate("template", elem.nextSibling, 4))
		elem.parentNode.removeChild(elem);
	return true;
}

function setValues(oRoot, oArray)
{
	var tags =["input", "select", "textarea"];
	for (var a = 0; a < tags.length; a++) {
		var tag = tags[a];
		var elems = oRoot.getElementsByTagName(tag);
		for (var b = 0; b < elems.length; b++) {
			var elem = elems[b];
			for (name in oArray) {
				var value = oArray[name];
				var elemName = new String(elem.name);
				elemName = elemName.replace("[]", "");
				if (String(" " + elemName + " ").indexOf(" " + name + " ") != -1) {
					elem.value = value;
				}
			}
		}
	}
}

function getValues(oRoot, oArray)
{
	var tags =["input", "select", "textarea"];
	for (var a = 0; a < tags.length; a++) {
		var tag = tags[a];
		var elems = oRoot.getElementsByTagName(tag);
		for (var b = 0; b < elems.length; b++) {
			var elem = elems[b];
			for (name in oArray) {
				var value = oArray[name];
				var elemName = new String(elem.name);
				elemName = elemName.replace("[]", "");
				if (String(" " + elemName + " ").indexOf(" " + name + " ") != -1) {
					oArray[name] = elem.value;
				}
			}
		}
	}
}

function inputDate(elem, format)
{
	if (elem.oInputDate)
		return;
	var oID = new InputDate(format);
	oID.setApproach(false);
	oID.add(elem);
}

function inputNumber(elem, format)
{
	if (elem.oInputNumber)
		return;
	var iNum = new InputNumber(format, ".");
	iNum.bindListener(elem);
	elem.oInputNumber = true;
}

function parseUrl(url)
{
	var rProto = "([a-zA-Z]+://)?";
	var rUser= "(([a-zA-Z0-9]+)(:[a-zA-Z]+)?@)?";
	var rHost= "(([a-zA-Z0-9._\\-]+)(:[0-9]+)?)?";
	var rPath= "((/[a-zA-Z0-9_\\-.:%]*)+)?";
	var rQuery= "(\\?([a-zA-Z0-9_\\-]+=[^&]+\\&?)+)?";
	var rFragment= "(#([a-zA-Z0-9]+))?";
	var rList = url.match(rProto+rUser+rHost+rPath+rQuery+rFragment);

	if (!rList || rList[0] != url)
		throw "parseUrl: invalid url";

	var scheme = rList[1];
	var host = rList[6];
	var port = rList[7];
	var user = rList[3];
	var pass = rList[4];
	var path = rList[8];
	var query = rList[10];
	var fragment = rList[13];

	if (scheme)
		scheme = scheme.substr(0, scheme.length - 3);
	if (port)
		port = port.substr(1);
	if (pass)
		pass = pass.substr(1);
	if (query)
		query = query.substr(1);

	return {
		scheme: scheme,
		host: host,
		port: port,
		user: user,
		pass: pass,
		path: path,
		query: query,
		fragment: fragment
	};
}
// check Cadastro Pessoa (Física/Jurídica)
// Verifica se o CNPJ ou CPF são numericamente válidos.
function checkCP(elem) {
	if (elem.value == "")
		return true;
	var reg = /[^0-9]/g;
	var value = String(elem.value);
	value = value.replace(reg, "");
	var ret = true;
	if (value.length < 11) {
		//alert("C.N.P.J./C.P.F incompleto");
		ret = false;
	}
	if (ret) {
		if (value.length == 14 && modulo11(value, 2, 8)) {
			reg = /^([0-9]{2})([0-9]{3})([0-9]{3})([0-9]{4})([0-9]{2})$/;
			elem.value = value.replace(reg, "$1.$2.$3/$4-$5");
		} else if (value.length == 11 && modulo11(value, 2, 10)) {
			reg = /^([0-9]{3})([0-9]{3})([0-9]{3})([0-9]{2})$/;
			elem.value = value.replace(reg, "$1.$2.$3-$4");
		} else {
			//alert("C.N.P.J./C.P.F invalido");
			ret = false;
		}
	}
	if (!ret) {
		if (elem.select)
			elem.select();
		if (elem.focus)
			elem.focus();
		return false;
	}
	return true;
}
function checkCNPJ(elem) {
	var reg = /[^0-9]/g;
	var value = String(elem.value);
	value = value.replace(reg, "");
	var ret = value.length == 14 && modulo11(value, 2, 8);
	if (ret) {
		reg = /^([0-9]{2})([0-9]{3})([0-9]{3})([0-9]{4})([0-9]{2})$/;
		elem.value = value.replace(reg, "$1$2$3$4$5");
	} else {
		if (elem.select)
			elem.select();
		if (elem.focus)
			elem.focus();
	}
	return ret;
}
function modulo11(str, ndig, nsample) {
	str = String(str);
	var ci = str.length - ndig;
	for (var c = ci; c < str.length; c++) {
		var mult = 0;
		var accum = 0;
		for (var i = 0; i < c; i++) {
			var ch = str.charAt(c - i - 1);
			var m = mult++ % nsample + 2;
			accum += m * parseInt(ch);
		}
		var dig1 = accum % 11;
		dig1 = (dig1 < 2) ? 0 : 11 - dig1;
		if (str.substr(c, 1) != dig1)
			return false;
	}
	return true;
}
function htmlentities(html) {
	var ret = String(html).replace(/</g, "&lt;");
	return ret.replace(/>/g, "&gt;");
}
function serialize(o) {
	try {
		o.onSerial = true;
		var dump = "";
		var i, first = true;;
		for (i in o) {
			if (i == "onSerial")
				continue;
			if (!first)
				dump += ", ";
			dump += i + ": ";
			if (o[i].onSerial) {
				dump += "this";
			} else if (typeof(o[i]) == "object") {
				dump += serialize(o[i]);
			} else {
				dump += o[i];
			}
			if (first)
				first = false;
		}
		delete o.onSerial;
		return "{"+dump+"}";
	} catch (exp) {
		return "{[native code]}";
	}
}
function xmlizeNode(node) {
	var dump = "";
	switch (node.nodeType) {
	case 1:
		dump = "<" + node.nodeName;
		var dumpa = "";
		for (var i=0; i < node.attributes.length; i++)
			dumpa += xmlizeNode(node.attributes.item(i));
		dump += dumpa;
		if (node.childNodes.length) {
			dumpa = ">";
			for (var i=0; i < node.childNodes.length; i++)
				dumpa += xmlizeNode(node.childNodes.item(i));
			dump += dumpa + "</"+node.nodeName+">";
		} else {
			dump += "/>";
		}
		break;
	case 2:
		dump = " " + node.nodeName + "=\"" + node.nodeValue + "\"";
		break;
	case 3:
		dump = node.nodeValue;
		break;
	}
	return dump;
}
/********************************* COMMON - END *******************************/
/********************************* ITERATOR - START ***************************/
Node = {
	collectionToArray: function (collection)
	{
		var list = [];
		for (var i=0; i < collection.length; i++)
			list.push(collection.item(i));
		return list;
	},
	ChildIterator: function (node)
	{
		this.node = node.firstChild;
	},
	AttributeIterator: function (node)
	{
		this.attributes = node.attributes;
		this.index = 0;
	},
	AncestorIterator: function (node)
	{
		this.node = node;
	},
	ParentIterator: function (node)
	{
		this.parent = node.parentNode;
	},
	SelfIterator: function (node)
	{
		this.node = node;
	},
	CollectionIterator: function (nodes)
	{
		this.nodes = nodes;
		this.index = 0;
	},
	DescentantIterator: function (node)
	{
		this.list = Node.collectionToArray(node.childNodes);
	}	
};

Node.ChildIterator.prototype.hasNext = function ()
{
	return this.node;
}

Node.ChildIterator.prototype.next = function ()
{
	var node = this.node;
	this.node = this.node.nextSibling;
	return node;
}

Node.AttributeIterator.prototype.hasNext = function ()
{
	return this.index < this.attributes.length;
}

Node.AttributeIterator.prototype.next = function ()
{
	return this.attributes.item(this.index++);
}

Node.AncestorIterator.prototype.hasNext = function ()
{
	return this.node && this.node.parentNode;
}

Node.AncestorIterator.prototype.next = function ()
{
	var node = this.node.parentNode;
	this.node = this.node.parentNode;
	return node;
}

Node.ParentIterator.prototype.hasNext = function ()
{
	return this.parent != null;
}

Node.ParentIterator.prototype.next = function ()
{
	var node = this.parent;
	this.parent = null;
	return node;
}

Node.SelfIterator.prototype.hasNext = function ()
{
	return this.node != null;
}

Node.SelfIterator.prototype.next = function ()
{
	var node = this.node;
	this.node = null;
	return node;
}

Node.CollectionIterator.prototype.hasNext = function ()
{
	return this.index < this.nodes.length;
}

Node.CollectionIterator.prototype.next = function ()
{
	return this.nodes.item(this.index++);
}

Node.DescentantIterator.prototype.hasNext = function ()
{
	return this.list.length > 0;
}

Node.DescentantIterator.prototype.next = function ()
{
	var node = this.list.shift();
	var list = Node.collectionToArray(node.childNodes);
	this.list = list.concat(this.list);
	return node;
}
/********************************** ITERATOR - END ****************************/
/********************************* TOOLROWS - START ***************************/
function addAssocColumn(table, iCol, fonClickStart, fonClickEnd)
{
	if (!table)
		return;
	var rows = table.rows;
	for (var i = 0; i < rows.length; i++) {
		var cell = rows.item(i).cells[iCol];
		if (!cell)
			continue;
		cell.onClickStart = fonClickStart;
		cell.onClickEnd = fonClickEnd;
		cell.table = table;
		Listener.add(cell, "mousedown", addAssocClickStart);
		Listener.add(cell, "mousedown", addAssocClickEnd);
	}
}
function addAssocClickStart(evt)
{
	if (!evt.ctrlKey && (typeof(evt.src.onClickStart) == "function")) {
		evt.src.table.elemSrc = evt.src;
		evt.src.onClickStart(evt.src);
	}
}
function addAssocClickEnd(evt)
{
	var elemSrc;
	if (evt.ctrlKey && (typeof(evt.src.onClickEnd) == "function") && (elemSrc = evt.src.table.elemSrc)) {
		evt.src.onClickEnd(evt.src, elemSrc);
		evt.src.table.elemSrc = null;
	}
}
function addToolRow(table)
{
	if (!table)
		return;
	var rows = table.rows;
	for (var i = 0; i < rows.length; i++) {
		var index = rows.item(i).cells.length - 1;
		var cell = rows.item(i).cells[index];
		if (String(cell.nodeName).toUpperCase() == "TH")
			continue;
		Listener.add(cell, "mousedown", getSrcRow);
		Listener.add(cell, "mouseover", setSrcRow);
	}
}
function setSrcRow(evt)
{
	if (!document.isDrag)
		return;
	while (String(evt.src.nodeName).toUpperCase() != "TR")
		evt.src = evt.src.parentNode;
	var parent = evt.src.parentNode;
	var srcRow = parent.srcRow;
	if (srcRow.offsetTop > evt.src.offsetTop)
		parent.insertBefore(srcRow, evt.src);
	else {
		var src = evt.src.nextSibling;
		parent.insertBefore(srcRow, src);
	}
	return true;
}

function getSrcRow(evt)
{
	while (String(evt.src.nodeName).toUpperCase() != "TR")
		evt.src = evt.src.parentNode;
	var parent = evt.src.parentNode;
	parent.srcRow = evt.src;
	if (document.isDrag) {
		document.isDrag = false;
		unSetClass(evt.src, "selected");
	} else {
		document.isDrag = true;
		setClass(evt.src, "selected");
		evt.stopPropagation();
		return false;
	}
}
function unSetClass(elem, className)
{
	var cn = new String(" " + elem.className + " ");
	cn = cn.replace(" " + className + " ", " ");
	elem.className = cn;
}

function setClass(elem, className)
{
	var cn = new String(elem.className);
	if (cn.indexOf(className) == -1) {
		cn += "     " + className;
	}
	cn.replace(/ \+/, " ");
	elem.className = cn;
}

function replaceClass(elem, className, classReplace)
{
	if (isSetClass(elem, className)) {
		unSetClass(elem, className);
		setClass(elem, classReplace);
	}
}

function isSetClass(elem, className)
{
	var cn = new String(" " + elem.className + " ");
	return (cn.indexOf(" " + className + " ") != -1);
}

/********************************** TOOLROWS - END ****************************/
/************************ MANAGEMENT OF WINDOW - START ************************/
Win = {
	scroll: {
		toBegin: function () {
			window.scrollTo(0, 0);
		},
		toEnd: function () {
			window.scrollTo(0, isIE ? document.body.scrollHeight : document.height);
		}
	},
	position: {
		toCenter: function () {
			var docElem = getDocumentElement();
			with(docElem) {
				var x = (window.screen.availWidth - offsetWidth) / 2;
				var y = (window.screen.availHeight - offsetHeight) / 2;
				window.moveTo(x, y);
			}
		}
	},
	size: {
		autoAdjust: function () {
			var docElem = getDocumentElement();
			with(docElem) {
				var width = Math.max(clientWidth, scrollWidth);
				width = Math.min(width, window.screen.availWidth - 50) + 50;
				var height = Math.max(clientHeight, scrollHeight);
				height = Math.min(height, window.screen.availHeight - 50) + 50;
				window.resizeTo(width, height);
			}
		}
	},
	create: function (url, name, width, height) {
		width = width || (screen.width / 2);
		height = height || (screen.height / 2);
		screenX = (screen.width - width) / 2;
		screenY = (screen.height - height) / 2;

		var opt;
		var features = [];
/*
		var opts = {};
*/
		var opts = {
			resizable: "yes",
			scrollbars: "yes",
			toolbar: "no",
			titlebar: "no",
			directories: "no",
			height: height,
			width: width,
			screenX: screenX,
			screenY: screenY
		};
		for (opt in opts)
			features.push(opt + "=" + opts[opt]);

		var w = window.open(url, name, features.join(","));
		w.focus();

		return w;
	},
	popUp: function (url, names, target) {
		url = createUrl(url, names);
		Win.create(url, target, 700, 450);
	}
};
/************************ MANAGEMENT OF WINDOW - END **************************/
/************************** TABLESORT - START *********************************/
function tableSort(elem, fmt, irows)
{
	if (!elem.oTableSort)
		var oTS = new TableSort(elem, fmt, irows);
	elem.oTableSort.sort()
}
/************************** TABLESORT - END ***********************************/
/***************************** FLOATLAYER - START *****************************/
function findElemLastOrId(node, id)
{
	if (id) {
		if (id.nodeType && id.nodeType == 1)
			return id;
		return document.getElementById(id);
	}
	if (node.nodeType != 1)
		return null;
	var childs = node.childNodes;
	for (var i = childs.length - 1; i > 0; i--) {
		var child = childs.item(i);
		if (child.nodeType == 1)
			return child;
	}
	return null;
}

function floatLayer(srcElem, idFloatLayer, dx, dy, fixedY, fixedX)
{
	if (srcElem.thisLayer)
		return;
	dx = dx || 30;
	dy = dy || 0;
	timeout = 2000;
	var fover = function (evt) {
		clearTimeout(srcElem.thisLayer.timerId);
		srcElem.thisLayer.timerId = null;
		showLayer(evt);
	}
	var fout = function (evt) {
		var f = function () {
			hideLayer(evt);
		}
		srcElem.thisLayer.timerId = setTimeout(f, timeout);
	}
	srcElem.onmouseover = null;
	srcElem.thisLayer = findElemLastOrId(srcElem, idFloatLayer);
	srcElem.thisLayer.timerId = null;
	srcElem.thisLayer.deltaX = dx;
	srcElem.thisLayer.deltaY = dy;
	srcElem.thisLayer.fixedX = fixedX;
	srcElem.thisLayer.fixedY = fixedY;
	document.body.appendChild(srcElem.thisLayer);
	Listener.add(srcElem, 'mouseover', fover);
	Listener.add(srcElem, 'mouseout', fout);
}

function showLayer(evt)
{
	var src = evt.src;
	var layer = src.thisLayer;
	if (!layer)
		return;
	with(layer.style) {
		zIndex = "99999";
		position = "absolute";
		if (layer.fixedX) {
			left = layer.deltaX + "px";
		} else {
			left = evt.clientX + layer.deltaX + "px";
		}
		if (layer.fixedY) {
			top = layer.deltaY + pageY() + "px";
		} else {
			top = evt.clientY + layer.deltaY + pageY() + "px";
		}
		display = "block";
	}
}

function hideLayer(evt)
{
	var src = evt.src;
	var layer = src.thisLayer;
	if (!layer)
		return;
	with(layer.style) {
		display = "none";
	}
}
/***************************** FLOATLAYER - END *******************************/
/*************************** XML FUNCTIONS - START ****************************/
function createUrl(url, names, form)
{
	form = form || document.forms[0];
	if (!form)
		return false;
	if (names) {
		for (var i = 0; i < names.length; i++)
			names[i] += "=" + encodeURI(form[names[i]].value);
		url = url + "?" + names.join("&");
	}
	return url;
}

function getBlockFromUrl(url)
{
	var blockname = url.split("/");
	blockname = blockname[blockname.length-2];
	return blockname;
}

function getValuesFromUrl(url)
{
	var i, tmp, assoc, values = {};
	i = url.indexOf('?');
	if (i < 0)
		return values;
	url = url.substr(i + 1);
	tmp = url.split("&");
	for (i = 0; assoc = tmp[i]; i++) {
		var v = assoc.split("=");
		values[v[0]] = decodeURIComponent(v[1]);
	}
	return values;
}

function xFound(url, blockname, values, result)
{
	result = (result) ? true : false;
	var doc = DOMUtils.createXRequest("query", result);
	var block = doc.documentElement.appendChild(doc.createElement(blockname));
	var k, v;
	for (k in values) {
		v = values[k];
		block.setAttribute(k, v);
	}
	var response = DOMUtils.post(url, doc);
	var status = response.documentElement.getAttribute("status");
	if (result)
		return response;
	return (status == 3) ? true : false;
}

function xDeleteList(elem, query, ask)
{
	var ret = true;
	if (ask)
		ret = confirm(msgs["delete"]);
	if (!ret || !elem.form)
		return;
	try {
		var doc = DOMUtils.createXRequest("delete", true);
		var request = doc.documentElement;
		var loc = ".";
		var form = elem.form;
		var blockName = form.name;
		// ../../xxx?id=1&id2=2
		if (query.indexOf("?") != -1) {
			var querySplit = query.split("?");
			loc = querySplit[0];
			var locSplit = loc.split("/");
			blockName = locSplit[locSplit.length-1];
			query = querySplit[1];
		}
		var block = request.appendChild(doc.createElement(blockName));
		var assoc, assocs = query.split("&");
		for (var i = 0; assoc = assocs[i]; i++) {
			var r = assoc.split("=");
			block.setAttribute(r[0], decodeURIComponent(r[1]));
		}
		var response = DOMUtils.post(loc, doc).documentElement;
		var message = DOMUtils.getXResponseMessage(response);
		var status = response.getAttribute("status");
		if (status == 1) {
			var template = getTemplate("template", elem, 1);
			template.parentNode.removeChild(template);
			updateXValues(form);
		}
		if (message)
			alert(message);
	}
	catch (e) {
		alert(e);
	}
}

function xSubmit(form)
{
	var actions = ["I", "U"];
	var operations = {I: "insert", U: "update"};
	var action = String(form.action).substr(-1);
	if (actions.indexOf(action) == -1)
		return false;
	if (!checkForm(form))
		return false;
	try {
		var operation = operations[action];
		var doc = DOMUtils.createXRequest(operation, true);
		formToXRequest(doc.documentElement, form);
		var response = DOMUtils.post(".", doc).documentElement;
		var message = DOMUtils.getXResponseMessage(response);
		var status = response.getAttribute("status");
		// Status OK
		if (status == 1)
			formFromXResponse(response, form);
		if (message)
			alert(message);
	} catch (e) {
		alert(e);
	}
	if (status == 1)
		updateXValues(form);
	return (status == 1);
}

function xEdit(elem, blockname, query)
{
	try {
		var dataXInsert = Register.get("xInsert");
		if (dataXInsert)
			enableXInsert(false, dataXInsert);
		var values = getValuesFromUrl(query);
		var response = xFound(".", blockname, values, true)
		if (!response.documentElement.childNodes.length)
			throw msgs["ireg"];
		//var attributes = response.documentElement.childNodes.item(0).attributes;
		var form = getForm(blockname);
		formFromXResponse(response.documentElement, form);
/*
		for (var i = 0; i < attributes.length; i++) {
			var attribute = attributes.item(i);
			var element = form[attribute.nodeName];
			if (!element)
				continue;
			element.value = attribute.nodeValue;
			switch (element.tagName) {
			case "INPUT":
				if (String(element.type).toUpperCase() == "CHECKBOX") {
					element.defaultChecked = element.checked;
				} else {
					element.defaultValue = element.value;
				}
				break;
			}
			if (element.onchange)
				element.onchange();
		}
*/
		var apply = document.getElementById("apply");
		Register.set({element: elem, blockname: blockname, query: query}, "xeditElement", true);
		var applied = Register.get("xeditApplied");
		if (applied == null) {
			apply.disabled = false;
			Listener.add(apply, "click", xApply, "xeditApplied");
		}
		saveViewStates(true);
		setChange(false);
		Win.scroll.toBegin();
		focus(form);
		updateXValues(form);
	} catch (exp) {
		alert(exp);
	}
}

function xInsert(element, blockname, keys, enablelist)
{
	var form = getForm(blockname);
	var dataXInsert = {element: element, form: form, keys: keys, enablelist: enablelist};
	Register.set(dataXInsert, "xInsert", true);
	enableXInsert(true, dataXInsert);
	for (var i=0; i < form.elements.length; i++) {
		var element = form.elements[i];
		if (keys.indexOf(element.name) != -1 && enablelist.indexOf(element.name) == -1 || element.type == "checkbox" || element.type == "button")
			continue;
		if (element.defaultValue)
			element.defaultValue = "";
		if (element.defaultSelected)
			element.defaultSelected = 0;
	}
	saveViewStates(true);
	focus(form);
}

function enableXInsert(enable, dataXInsert)
{
	var stlc;
	if (enable) {
		dataXInsert.form.action = "I";
		var tpl = getTemplate("modeUpdate", dataXInsert.form, 2);
		if (tpl) {
			stlc = new StyleClass(tpl);
			stlc.unSet("modeUpdate");
			stlc.set("modeInsert");
		}
	} else {
		dataXInsert.form.action = "U";
		var tpl = getTemplate("modeInsert", dataXInsert.form, 2);
		if (tpl) {
			stlc = new StyleClass(tpl);
			stlc.unSet("modeInsert");
			stlc.set("modeUpdate");
		}
	}
	for (var i=0; i < dataXInsert.enablelist.length; i++) {
		var name = dataXInsert.enablelist[i];
		var elem = dataXInsert.form[name];
		stlc = new StyleClass(elem);
		if (!elem)
			continue;
		if (enable) {
			elem.readOnly = false;
			stlc.unSet("readonly");
		} else {
			elem.readOnly = true;
			stlc.set("readonly");
		}
	}
	var apply = document.getElementById("apply");
	var applied = Register.get("xeditApplied");
	if (applied == null) {
		apply.disabled = false;
		Listener.add(apply, "click", xApply, "xeditApplied");
	}
}

function xApply(evt)
{
	var form = evt.src.form;
	var ret = xSubmit(form);
	setChange(!ret);
	if (ret) {
		var params;
		if (String(form.action).substr(-1) == "U") {
			params = Register.get("xeditElement");
			var row = DOMUtils.get("r" + params.query);
			var copy = DOMUtils.copyNodeFromXml(document, row.documentElement);
			var tpl = getTemplate("template", copy, 2);
			var template = getTemplate("template", params.element, 3);
			if (tpl && template) {
				params.element = tpl;
				Register.set(params, "xeditElement", true);
				template.parentNode.replaceChild(tpl, template);
				var ruleSheet = Register.get("ruleSheet");
				ruleSheet.processElement(tpl);
				var elems = tpl.getElementsByTagName("input");
				if (elems.length) {
					var elem = elems[0];
					setClass(elem, "xedited");
					elem.focus();
				}
			}
		} else {
			try {
				var dataXInsert = Register.get("xInsert");
				var url = createUrl("r", dataXInsert.keys, dataXInsert.form);
				var row = DOMUtils.get(url);
				var copy = DOMUtils.copyNodeFromXml(document, row.documentElement);
				copy = getTemplate("template", copy, 2);
				var template = getTemplate("template", dataXInsert.element, 3);
				if (copy && template) {
					template.parentNode.appendChild(copy);
					var ruleSheet = Register.get("ruleSheet");
					ruleSheet.processElement(copy);
					var elems = copy.getElementsByTagName("input");
					if (elems.length) {
						var elem = elems[0];
						setClass(elem, "xedited");
						elem.focus();
						Register.set({element: elem, blockname: dataXInsert.form.name, query: String(url).substr(1)}, "xeditElement", true);
						enableXInsert(false, dataXInsert);
					}
				}
			} catch (e) {}
		}
	}
	evt.cancel();
	return false;
}

function formToXRequest(node, form)
{
	/*
	** Make element conform spec. XRequest into node.
	*/
	var doc = node.ownerDocument;
	var block = doc.createElement(form.name);
	node.appendChild(block);
	var mf = MapSets.getMapField();
	var visitor = {
		filter: function (e) {
			return (!e.name || e.disabled || (e.type == "checkbox" && !e.checked));
		},
		visit: function (e) {
			//block.setAttribute(e.name, e.value);
			mf.getField(block, e);
			return true;
		}
	}
	var i = new ElementIterator(form.elements);
	ExIter.forEach(i, visitor);
}

function formFromXResponse(node, form)
{
	/*
	** Update form from XResponse
	*/
	var block;
	var visitor = {
		filter: function (node) {
			return (node.nodeName != form.name);
		},
		visit: function (node) {
			block = node;
			return false;
		}
	}
	var i = new ElementIterator(node.childNodes);
	ExIter.forEach(i, visitor);

	var mf = MapSets.getMapField();
	visitor = {
		filter: function (e) {
			return (!e.name || e.disabled);
		},
		visit: function (e) {
			var value = block.getAttribute(e.name);
			mf.setField(e, block);
			return true;
		}
	}
	var j = new ElementIterator(form.elements);
	ExIter.forEach(j, visitor);
}

function foundForm(url, names, form)
{
	var name, values = {};
	for (var i = 0; name = names[i]; i++)
		if (form[name])
			values[name] = form[name].value;
	blockname = getBlockFromUrl(String(url));
	return xFound(url, blockname, values);
}

function foundURL(base, url)
{
	var i, j, blockname, values;
	url = String(url);
	i = base.indexOf('?');
	j = url.indexOf('?');
	if (i < 0 && j >= 0)
		url = base + url.substr(j);
	else if (i > 0 && j >= 0)
		url = base + "&" + url.substr(j + 1);
	else if (i > 0 && j < 0)
		url = base;
	else
		throw new Exception("foundUrl: Query string in url not found");
	blockname = getBlockFromUrl(url);
	values = getValuesFromUrl(url);
	return xFound(url, blockname, values);
}
/*************************** XML FUNCTIONS - END ******************************/
/*************************** CNAVIGATOR - START *******************************/
var oNav = new CNavigator();
function CNavigator()
{
	this.IE = 1;
	this.GE = 2;
	if (document.all)
		this.type = this.IE;
	else
		this.type = this.GE;
	this.fScroll = new Array();
}

CNavigator.prototype.is = function (type)
{
	return (this.type == type);
}

CNavigator.prototype.hasFeature = function (feature)
{
	switch (feature) {
	case "onscroll":
		switch (this.type) {
		case this.IE:
			return true;
		case this.GE:
			return false;
		}
	}
}

CNavigator.prototype.atScroll = function (f)
{
	if (typeof(f) == "function")
		this.fScroll.push(f);
}

CNavigator.prototype.getVersion = function (v)
{
	var agents = [];
	agents.push(String(navigator.userAgent).match(/MSIE ([0-9]+).([0-9]+)/));
	agents.push(String(navigator.userAgent).match(/Firefox\/([0-9]+).([0-9]+)/));
	for (var i = 0; i < agents.length; ++i) {
		var matches = agents[i];
		if (matches && matches.length == 3)
			return {major: matches[1], minor: matches[2]};
	}
}

window.onscroll = function ()
{
	var func;
	for (var i = 0; func = oNav.fScroll[i]; i++)
		func();
}
/**************************** NAVIGATOR - END *********************************/
window.onload = load;

	/*
**	Class InputDate
*/
InputDate = function (format)
{
	this.maskCtrl = "sSiIhHdDmMaAyY.";
	this.maskChar = "0123456789";
	this.approach = false;
	format = format || "d/m/Y";
	this.setFormat(format);
}
InputDate.prototype.bindListener = function (element)
{
	var obj = {
		keypress: "onKeyPress",
		keyup: "onKeyUp",
		blur: "onBlur",
		focus: "onFocus",
		click: "onClick"
	};
	for (var o in obj)
		Listener.add(element, o, [this, obj[o]]);
}
InputDate.prototype.setMaxWidth = function ()
{
	var width, len;
	var format = this.format;
	width = 0;
	len = new Number(format.length);

	format = format.replace(/[sihHdm]/g, "");
	width += 2 * (len - format.length);
	len = format.length;

	format = format.replace(/[Y]/g, "");
	width += 4 * (len - format.length);

	width += format.length;
	this.maskWidth = width;
}
InputDate.prototype.setFormat = function (format)
{
	if (!format)
		throw "1:InputDate.setFormat";
	this.format = format;
	this.setTitle();
	this.setSeparator();
	this.setValidateInput();
	this.setMaxWidth();
	this.mask = this.maskChar + this.maskCtrl + this.separator;
	return this;
}
InputDate.prototype.setSeparator = function ()
{
	var sep = new String(this.format);
	this.separator = sep.replace(/[sihHdmY]/g, "");
}
InputDate.prototype.setTitle = function ()
{
	var read = new String(this.format);
	read = read.replace(/[s]/g, "ss");
	read = read.replace(/[H]/g, "HH");
	read = read.replace(/[d]/g, "DD");
	read = read.replace(/[m]/g, "MM");
	read = read.replace(/[i]/g, "mm");
	read = read.replace(/[Y]/g, "AAAA");
	//this.title = "Formato de data (" + read + ").";
}
InputDate.prototype.setValidateInput = function ()
{
	var regExp = new String(this.format);
	regExp = regExp.replace(/([^sihHdmY]+)/g, "$1?");
	regExp = regExp.replace(/[sihHdm]/g, "([0-9]{0,2})");
	regExp = regExp.replace(/[Y]/g, "([0-9]{0,4})");
	regExp = "^" + regExp + "$";
	this.validRegExp = new RegExp(regExp);
}
InputDate.prototype.setApproach = function (b)
{
	this.approach = (b) ? true : false;
}
InputDate.prototype.isInputDate = function (elem)
{
	var o = elem.oInputDate;
	return (o instanceof InputDate);
}
InputDate.prototype.add = function (elem)
{
	if (this.isInputDate(elem))
		return;
	elem.oInputDate = this;
	//elem.title = this.title;
	this.bindListener(elem);
}
InputDate.prototype.select = function (evt, val)
{
	evt.src.selected = val;
	if (val)
		evt.src.select();
}
InputDate.prototype.onKeyPress = function (evt)
{
	evt.src.oldValue = evt.src.value;
	if (evt.charCode == 0)
		return;

	var value	= new String(evt.src.value);
	var charKey = String.fromCharCode(evt.charCode);
	var isCharCtrl = (this.maskCtrl.indexOf(charKey) != -1);

	var cancel = false;
	if (this.mask.indexOf(charKey) == -1)
		cancel = true;
	if (!isCharCtrl) {
		if ((this.maskWidth <= value.length) && (evt.src.selected))
			value = "";
	}
	if (cancel) {
		evt.cancel();
		return false;
	}

	var date = new Date();
	if (charKey != '.')
		date.setFormat(value, this.format);
	switch (charKey) {
	case 's':
		date.setSeconds(date.getSeconds()-1);
		break;
	case 'S':
		date.setSeconds(date.getSeconds()+1);
		break;
	case 'i':
		date.setMinutes(date.getMinutes()-1);
		break;
	case 'I':
		date.setMinutes(date.getMinutes()+1);
		break;
	case 'h':
		date.setHours(date.getHours()-1);
		break;
	case 'H':
		date.setHours(date.getHours()+1);
		break;
	case 'd':
		date.setDate(date.getDate()-1);
		break;
	case 'D':
		date.setDate(date.getDate()+1);
		break;
	case 'm':
		date.setMonth(date.getMonth()-1);
		break;
	case 'M':
		date.setMonth(date.getMonth()+1);
		break;
	case 'a':
	case 'y':
		date.setFullYear(date.getFullYear()-1);
		break;
	case 'A':
	case 'Y':
		date.setFullYear(date.getFullYear()+1);
		break;
	case '.':
		break;
	}
	if (isCharCtrl) {
		value = date.format(this.format);
		evt.cancel();
	}
	evt.src.refValue = value;
	evt.src.isCharCtrl = isCharCtrl;
}
InputDate.prototype.onKeyUp = function (evt)
{
	if (evt.src.isCharCtrl) {
		if (evt.src.refValue)
			evt.src.value = evt.src.refValue;
		this.select(evt, true);
		evt.src.isCharCtrl = false;
	}
	
	var value = new String(evt.src.value);
	var valid = value.match(this.validRegExp);
	if (valid) {
		valid.shift();
		evt.src.validFormat = valid;
	} else {
		evt.src.value = evt.src.oldValue;
	}
}
InputDate.prototype.onBlur = function (evt)
{
	var value = new String(evt.src.value);

	if (value.length == 0)
		return;

	if (!evt.src.validFormat)
		return;

	var reg = this.format.replace(/[^sihHdmY]/g, "");
	if (!reg)
		return;

	var date = new Date();
	if (this.approach)
		date.setApproachDate(true);
	else
		date.setApproachDate(false);

	var fmtStr = "";
	var valStr = "";
	for (var i=0; i < reg.length; i++) {
		var fmt = reg.charAt(i);
		var val = evt.src.validFormat[i];
		if (fmt == "" || val == "")
			continue;
		fmtStr += fmt + "-";
		valStr += val + "-";
	}
	date.setFormat(valStr, fmtStr);
	evt.src.value = date.format(this.format);
}
InputDate.prototype.onFocus = function (evt)
{
	this.select(evt, true);
}
InputDate.prototype.onClick = function (evt)
{
	this.select(evt, true);
}

	/*
**	Class InputNumber
*/
InputNumber = function (format, decPoint)
{
	this.decPoint = decPoint || ",";
	this.thoPoint = (this.decPoint == ".") ? "," : ".";
	var fmt = String(format);
	var dig = fmt.split(decPoint);
	if (dig.length == 2) {
		this.sigSize = parseInt(dig[0]);
		this.decSize = parseInt(dig[1]);
		this.sigSize -= this.decSize;
		if (this.decSize < 0)
			this.decSize = 0;
		this.size = this.sigSize + this.decSize + (this.decSize ? 1 : 0);
	}
	this.mask = "-0123456789" + this.decPoint + this.thoPoint;
}
InputNumber.prototype.bindListener = function (element)
{
	var obj = {
		keypress: "onKeyPress",
		change: "onChange"
	};
	for (var o in obj)
		Listener.add(element, o, [this, obj[o]]);
}
InputNumber.prototype.onChange = function (evt)
{
	var value	= new String(evt.src.value);
	var b = Math.min(value.indexOf("."), value.indexOf(","));
	if (b == -1)
		b = Math.max(value.indexOf("."), value.indexOf(","));
	var l = Math.max(value.lastIndexOf("."), value.lastIndexOf(","));
	if (b < l) {
		var char1 = value.charAt(b);
		var char2 = value.charAt(l);
		value = value.replace(char1, "", "g");
		if (value.indexOf(char2) == value.lastIndexOf(char2)) {
			value = value.replace(char2, this.decPoint);
			evt.src.value = parseFloat(value);
		} else {
			evt.src.value = "";
		}
	}
}
InputNumber.prototype.onKeyPress = function (evt)
{
	if (evt.charCode == 0)
		return;

	var value	= new String(evt.src.value);
	var charKey = String.fromCharCode(evt.charCode);
	
	if (!evt.ctrlKey && (this.mask.indexOf(charKey) == -1) ||
			this.size && (value.length >= this.size) ||
			(charKey == this.decPoint) && (value.indexOf(charKey) != -1) ||
			(charKey == "-") && (value.indexOf("-") != -1))
		evt.cancel();
}

	// variavel de identificação global
var _idRoots = new Array();
var _itens = new Array();
var classes = new Object();
classes.menu = "cMenu";
classes.item = "cItem";
classes.root = "menuRoot";
classes.itemOver = "cItemOver";

// declaração e definição da classe Menu

Menu = function (idElem, display, classes)
{

	this.idRoot = idElem || Sequence.nextval("menu");
	this.classes = classes;
	this.display = display;

	// Indica qual é a maior string do display
	this.maxStrLen = 0;

	// Attributos
	this.left = 0;
	this.top = 20;
	this.fontFamily = "verdana";
	this.fontHeight = 12;
	this.fontWidth = 10;
	this.paddingLeft = 5;
	this.paddingRight = 0;
	this.paddingTop = 3;
	this.paddingBottom = 3;
	this.border = 1;

	// Visivel ou não
	this.visible = false;

	// Instala o evento de click no corpo HTML para ocultar os menus
	if (!document.oHideClick) {
		document.oHideClick = true;
		Listener.add(document.documentElement, "click", menuhideClick);
	}
	this.disposes = [];
	Dispose.add(this);
}

Menu.prototype.register = function (elem, attr)
{
	this.disposes.push({elem: elem, attr: attr});
}

Menu.prototype.dispose = function ()
{
	for (var i = 0; i < this.disposes.length; i++) {
		var obj = this.disposes[i];
		obj.elem[obj.attr] = undefined;
		this.disposes[i] = undefined;
	}
}

Menu.prototype.setWidth = function (width)
{
	this.fixWidth = width;
}

Menu.prototype.addItem = function (idItem, display, actOrSub)
{
	var item = new Object();
	var submenu, action;

	if (typeof actOrSub == "object")
		submenu = actOrSub;
	else
		action = actOrSub;

	this.maxStrLen = Math.max(this.maxStrLen, display.length);

	if (!this.itens)
		this.itens = new Array();

	item.display = display;
	item.action = action;
	item.submenu = submenu;
	item.id = idItem;
	item.menu = this;
	if (item.submenu) {
		item.submenu.parent = this;
		if (item.submenu.itens)
			for (var i = 0; i < item.submenu.itens.length; i++) {
				item.submenu.itens[i].parentItem = item;
			}
	}
	this.itens.push(item);
	_itens.push(item);
}

Menu.prototype.create = function ()
{
	if (!this.itens)
		return;
	var len = this.itens.length;
	var item, eDivChild, eText;

	var eDiv = document.createElement("div");
	eDiv.setAttribute("id", Sequence.nextval("menu"));
	eDiv.thisMenu = this;
	this.register(eDiv, "thisMenu");
	var eIfr = document.createElement("iframe");
	eIfr.setAttribute("id", Sequence.nextval("menu"));
	eIfr.thisMenu = this;
	this.register(eIfr, "thisMenu");

	var posItem = 0;
	for (var i = 0; i < len; i++) {

		eDivChild = eDiv.cloneNode(false);
		item = this.itens[i];
		item.elem = eDivChild;

		eDivChild.setAttribute("id", item.id || Sequence.nextval("menu"));

		// Set thisMenu
		eDivChild.thisMenu = this;
		this.register(eDivChild, "thisMenu");
		eDivChild.thisItem = item;
		this.register(eDivChild, "thisItem");
		item.elem = eDivChild;
		this.register(item, "elem");

		// Set class item
		this.setClasses(eDivChild, "item");

		// Add events
		Listener.add(eDivChild, "mouseover", [this, "itemOver"]);
		Listener.add(eDivChild, "mouseout", [this, "itemOut"]);
		if (item.action)
			Listener.add(eDivChild, "click", new Function("eval(\"" + item.action + "\");"));

		eText = document.createTextNode(item.display);
		eDivChild.appendChild(eText);
		eDiv.appendChild(eDivChild);

		// SubMenu
		if (item.submenu) {

// organizar essa parte do codigo
			var eDivSetMenu = document.createElement("span");
			item.submenu.pos = posItem;
			eDivSetMenu.thisMenu = this;
			this.register(eDivSetMenu, "thisMenu");
			eDivSetMenu.thisItem = item;
			this.register(eDivSetMenu, "thisItem");
			eDivSetMenu.addIn = ">";
			Listener.add(eDivSetMenu, "mouseover", [this, "itemOver"]);
			Listener.add(eDivSetMenu, "mouseout", [this, "itemOut"]);
			eText = document.createTextNode(">");
			eDivSetMenu.appendChild(eText);
			eDivChild.appendChild(eDivSetMenu);
			eDivSetMenu.className = "";
			eDivSetMenu.style.position = "absolute";
			eDivSetMenu.style.right = "5px";
		}
		posItem++;
	}

	this.elemDiv = eDiv;
	this.register(this, "elemDiv");
	this.elemIfr = eIfr;
	this.register(this, "elemIfr");
	this.setDimensions(eDiv);
	this.setDimensions(eIfr);
	this.setPositions();

	// Set classes menu
	this.setClasses(eDiv, "menu");
	this.setClasses(eIfr, "menu");

	if (!this.parent) {
		root = document.getElementById(this.idRoot);
		_idRoots.push(this.idRoot);
		this.setClasses(root, "root");
		root.appendChild(eDiv);
		// Exceção para o explorer
		if (document.all)
			root.appendChild(eIfr);
		root.thisMenu = this;
		this.register(root, "thisMenu");
		Listener.add(root, "click", [this, "clearClick"]);
	} else {
		// find rootMenu
		var rootMenu = this.parent;
		while (rootMenu.parent)
			rootMenu = rootMenu.parent;

		var root = document.getElementById(rootMenu.idRoot);
		root.appendChild(eDiv);
		// Exceção para o explorer
		if (document.all)
			root.appendChild(eIfr);
	}
	for (var i = 0; i < this.itens.length; i++) {
		item = this.itens[i];
		if (!item.submenu)
			continue;
		item.submenu.create();
	}
}

Menu.prototype.setClasses = function (elem, type)
{
	var style = elem.style;
	switch (type) {
	case "root":
		style.position = "relative";
		elem.className = this.classes.root;
		break;
	case "menu":
		style.position = "absolute";
		if (elem.nodeName != "IFRAME")
			elem.className = this.classes.menu;
		with(elem.style) {
			padding = 0;
			margin = 0;
			if (elem.nodeName != "IFRAME")
				zIndex = 1000;
			else
				zIndex = 999;
			whiteSpace = "nowrap";
		}
		break;
	case "item":
		elem.className = this.classes.item;
		with(elem.style) {
			fontSize = this.fontHeight + "px";
			fontFamily = this.fontFamily;
			paddingLeft = this.paddingLeft + "px";
			paddingRight = this.paddingRight;
			paddingTop = this.paddingTop + "px";
			paddingBottom = this.paddingBottom + "px";
			borderWidth = this.border + "px";
		}
		break;
	}
}

Menu.prototype.itemOver = function (evt)
{
	var src = evt.src;
	var menu = src.thisMenu;
	var item = src.thisItem;
	if (!menu)
		return;
	if (!src.addIn) {
		var className = menu.classes.itemOver;
		src.className = className;
	}
	menu.clearTimer();
	if (item && item.submenu) {
		item.submenu.clearTimer();
		item.submenu.show();
	}
}

Menu.prototype.itemOut = function (evt)
{
	var src = evt.src;
	var menu = src.thisMenu;
	var item = src.thisItem;
	if (!menu)
		return;
	if (!src.addIn) {
		var className = menu.classes.item;
		src.className = className;
	}
	// setar o timer se tiver um submenu
	if (item && item.submenu)
		item.submenu.setTimer();
	else
		menu.setTimer();
}

menuhideClick = function ()
{
	var idRoot, root, menu;
	for (var i = 0; i < _idRoots.length; i++) {
		idRoot = _idRoots[i];
		root = document.getElementById(idRoot);
		menu = root.thisMenu;
		menu.hide();
	}
}

Menu.prototype.clearClick = function (evt)
{
	var root = evt.src;
	var menu = root.thisMenu;
	if (menu.visible)
		menu.hide();
	else {
		menu.show();
		evt.stopPropagation();
	}
}

Menu.prototype.clearTimer = function ()
{
	if (this.timer)
		clearTimeout(this.timer);
	this.timer = null;
	if (this.parent)
		this.parent.clearTimer();
}

Menu.prototype.setTimer = function (delay)
{
	delay = delay || 500;
	this.clearTimer();
	this.timer = setTimeout('menuHideTimeout("' + this.elemDiv.id + '")', delay);
	if (this.parent)
		this.parent.setTimer(delay + 500);
}

function menuHideTimeout(idElem)
{
	var elem = document.getElementById(idElem);
	var menu = elem.thisMenu;
	menu.hide();
}

Menu.prototype.setDimensions = function (elem)
{
	var nItens = 0;
	for (var i = 0; i < this.itens.length; i++)
		nItens++;
	this.height = this.fontHeight + this.paddingTop + this.paddingBottom + 2 * this.border + 2;
	// Exceção para o Mozzila
	var width = this.fixWidth || (this.fontWidth * this.maxStrLen);
	this.width = width + this.paddingLeft + this.paddingRight + 2 * this.border;
	elem.style.width = width + "px";
	// seta o width para todos os itens filhos
	var itens = elem.thisMenu.itens;
	for (var i = 0; i < itens.length; i++) {
		var item = itens[i];
		item.elem.style.width = width + "px";
	}
	var height = nItens * this.height;
	elem.style.height = height + "px";
}

Menu.prototype.setPositions = function ()
{
	var item;
	var eDiv, eIfr;
	eDiv = this.elemDiv;
	eIfr = this.elemIfr;
	if (this.parent) {
		this.left = parseInt(this.parent.left) + parseInt(this.parent.width);
		// Exceção para o Explorer
		if (document.all)
			this.left -= this.paddingLeft + this.paddingRight + 2;
		this.top = parseInt(this.parent.top) + this.pos * parseInt(this.parent.height);
	}
	if (!this.left)
		this.left = 0;
	if (!this.top)
		this.top = 0;
	eDiv.style.left = String(this.left) + "px";
	eIfr.style.left = String(this.left) + "px";
	eDiv.style.top = String(this.top) + "px";
	eIfr.style.top = String(this.top) + "px";
}

menuShowEvent = function (evt)
{
	evt.src.thisMenu.show();
}

Menu.prototype.show = function ()
{
	if (!this.elemDiv)
		return;
	this.elemDiv.style.display = "block";
	this.elemIfr.style.display = "block";
	this.visible = true;
	// Hide para todos os irmaos
	if (!this.parent) {
		for (var i = 0; i < _idRoots.length; i++) {
			var idRoot = _idRoots[i];
			var elem = document.getElementById(idRoot);
			if (!elem.thisMenu.mouseOverActive) {
				elem.thisMenu.mouseOverActive = true;
				Listener.add(elem, "mouseover", menuShowEvent, "menuShowEvent" + i);
			}
			if (this.idRoot == idRoot)
				continue;
			elem.thisMenu.hide();
		}
		return;
	}
	var parent = this.parent;
	for (var i = 0; i < parent.itens.length; i++) {
		var item = parent.itens[i];
		if (!item.submenu)
			continue;
		if (this == item.submenu)
			continue;
		item.submenu.hide();
	}

}

Menu.prototype.hide = function ()
{
	if (!this.visible)
		return;
	this.elemDiv.style.display = "none";
	this.elemIfr.style.display = "none";
	this.visible = false;
	// Hide para todos os filhos
	for (var i = 0; i < this.itens.length; i++) {
		var item = this.itens[i];
		if (item.submenu) {
			item.submenu.hide();
		}
	}
	if (!this.parent) {
		var remove = true;
		for (var i = 0; i < _idRoots.length; i++) {
			var idRoot = _idRoots[i];
			var root = document.getElementById(idRoot);
			if (root.thisMenu.visible) {
				remove = false;
				break;
			}
		}
		if (!remove)
			return;
		for (var i = 0; i < _idRoots.length; i++) {
			var idRoot = _idRoots[i];
			var root = document.getElementById(idRoot);
			if (root.thisMenu.mouseOverActive) {
				root.thisMenu.mouseOverActive = false;
				Listener.remove("menuShowEvent" + i);
			}
		}
	}
}

function createMenubar(menubar)
{
	var itembar, hash, elem, text;
	var divMenu = document.getElementById("menu");
	if (!divMenu)
		return;
	var reference = divMenu.firstChild;
	for (var i = 0; itembar = menubar.childNodes[i]; i++) {
		if (itembar.nodeType != 1)
			continue;
		hash = Sequence.nextval("menu");
		elem = document.createElement("div");
		elem.setAttribute("id", hash);
		elem.setAttribute("class", "menuRoot");
		text = itembar.getAttribute("display");
		elem.appendChild(document.createTextNode(text));
		divMenu.insertBefore(elem, reference);
		createMenu(itembar, hash, true);
	}
}

function createMenu(node, id, root)
{
	var item, submenu, hash;
	var menu = new Menu(id, node.getAttribute("display"), classes);
	var size = node.getAttribute("size");
	if (size != null)
		menu.setWidth(size);
	for (var i = 0; item = node.childNodes[i]; i++) {
		if (item.nodeType != 1)
			continue;
		hash = Sequence.nextval("menu");
		if (item.childNodes.length) {
			// Submenu
			submenu = createMenu(item, hash);
			menu.addItem(hash, item.getAttribute("display"), submenu);
		} else {
			// Href
			menu.addItem(hash, item.getAttribute("display"), "location = '" + item.getAttribute("href") + "';");
		}
	}
	if (root)
		menu.create();
	return menu;
}

/***************************** MENU - END *************************************/

	/*
** class ToolBar
*/
ToolBar = function (id, y0) {
	var toolbar = document.getElementById(id);
	toolbar.style.position = "relative";
	toolbar.style.top = intToPx(0);
	var pos = getPosition(toolbar);
	var ppos = getPosition(toolbar.parentNode);
	this.topmax = (ppos.bottom - ppos.top) - (pos.bottom - pos.top) - 20;
	this.topmax = Math.max(this.topmax, 0);
	this.id = id;
	this.y0 = y0 || 100;
}
ToolBar.prototype.refresh = function() {
	var toolbar = document.getElementById(this.id);
	var y = pageOffsetY();
	var top = Math.abs(Math.min(Math.max(y - this.y0, 0), this.topmax));
	var top0 = parseInt(toolbar.style.top);
	var dtop = Math.floor(0.5 * (top - top0));
	toolbar.style.top = intToPx(top0 + dtop);
}
/*
** class ToolSet
*/
ToolSet = function (id, idref) {
	this.id = id;
	this.idref = idref;
	this.show(false);
}
ToolSet.prototype.show = function(b) {
	var tool = document.getElementById(this.id);
	if (b)
		tool.style.visibility = "visible";
	else
		tool.style.visibility = "hidden";
}
ToolSet.prototype.align = function() {
	var toolset = document.getElementById(this.id);
	var ref = document.getElementById(this.idref);
	alignBlock(toolset, "100;0", ref, "0;0");
}
ToolSet.prototype.submit = function(evt) {
	var elem = evt.src;
	var form = elem.form;
	var cn = String(elem.className);
	var oper = cn.split("-")[1];
	if ((typeof(form.onsubmit) == "function") && !form.onsubmit())
		return false;
	form.action += oper;
	setChange(false);
	form.submit();
}
/*
** Initialize Tools
*/
var oToolBar;
var oToolSet;
var toolBarRun;
var toolTimer = null;
function initTool() {
	if (oToolBar) {
		oToolBar.refresh();
		if (oToolSet)
			oToolSet.align();
		setTimeout("initTool()", 120);
	} else {
		if (document.getElementById("toolbar"))
		{
			oToolBar = new ToolBar("toolbar");
			toolBarRun = document.getElementById("run");
			if (document.getElementById("toolset"))
			{
				oToolSet = new ToolSet("toolset", "run");
				Listener.add(document.getElementById("toolset"), "mouseover", toolOnMouseOver);
				Listener.add(toolBarRun, "mouseover", toolOnMouseOver);
			}
			initTool();
		}
	}
}
/*
** ToolSet's and ToolBar's Listeners
*/
function toolOnMouseOver(e) {
	if (toolTimer != null) {
		clearTimeout(toolTimer);
		toolTimer = null
	}
	var tool = document.getElementById("toolset");
	Listener.add(tool, "mouseout", toolOnMouseOut, "idToolOnMouseOut");
	Listener.add(toolBarRun, "mouseout", toolOnMouseOut, "idToolApplyOnMouseOut");
	Listener.add(toolBarRun, "mousemove", toolOnMouseMove, "idToolApplyOnMouseMove");
}
function toolOnMouseMove(e) {
	oToolSet.show(e.ctrlKey);
	if (e.ctrlKey)
		Listener.remove("idToolApplyOnMouseMove");
}
function toolOnMouseOut(e) {
	var tool = document.getElementById("toolset");
	Listener.remove("idToolOnMouseOut");
	Listener.remove("idToolApplyOnMouseOut");
	Listener.remove("idToolApplyOnMouseMove");
	if (toolTimer == null)
		toolTimer = setTimeout("toolTimeout()", 300);
}
function toolTimeout() {
	oToolSet.show(false);
}

	//var date = new Date();
var WeekPT = new Array("Do", "Se", "Te", "Qu", "Qu", "Se", "Sá");
var WeekEN = new Array("S", "M", "T", "W", "T", "F", "S");
var MonthPT = new Array("Janeiro", "Fevereiro", "Março",
	"Abril", "Maio", "Junho",
	"Julho", "Agosto", "Setembro",
	"Outubro", "Novembro", "Dezembro");

// Define a classe YearCalendar
function YearCalendar(cal)
{
	this.cal = cal;
	this.prev = prevYear;
	this.next = nextYear;
}

function nextYear()
{
	this.cal.date.setYear(this.cal.date.getFullYear() + 1);
	this.cal.draw();
}

function prevYear()
{
	this.cal.date.setYear(this.cal.date.getFullYear() - 1);
	this.cal.draw();
}

								// Define a classe MonthCalendar
function MonthCalendar(cal)
{
	this.cal = cal;
	this.prev = prevMonth;
	this.next = nextMonth;
	this.set = setMonth;
}

function nextMonth()
{
	this.set(this.cal.date.getMonth() + 1);
	this.cal.draw();
}

function prevMonth()
{
	this.set(this.cal.date.getMonth() - 1);
	this.cal.draw();
}

function setMonth(month)
{
	if (!month)
		return;
	this.cal.date.setDate(1);
	this.cal.date.setMonth(month);
	this.cal.draw();
}

// Define a classe Calendar
Calendar = function (date)
{
	this.setDate(date);
}
Calendar.prototype.show = function (b)
{
	var calendar = document.getElementById("calendar");
	var dummy = document.getElementById("calendardummy");
	if (!calendar)
		return;
	if (b) {
		calendar.style.visibility = "visible";
		dummy.style.visibility = "visible";
	} else {
		calendar.style.visibility = "hidden";
		dummy.style.visibility = "hidden";
	}
}
Calendar.prototype.setDate = function (date)
{
	this.date = date;
	this.month = new MonthCalendar(this);
	this.year = new YearCalendar(this);
}
Calendar.prototype.setDateFormat = function (val, fmt)
{
	var date = new Date();
	date.setFormat(val, fmt);
	this.setDate(date);
}
Calendar.prototype.draw = function ()
{
	var date = new Date(this.date);
	date.setDate(1);

	var lastDayMonth = new Date(date);
	lastDayMonth.setMonth(date.getMonth() + 1);
	lastDayMonth.setDate(0);

	var dayWeek = date.getDay();
	var nRows = 5 + ((dayWeek > 4) ? 1 : 0);
	var dateEnd = lastDayMonth.getDate();
	var d = 1;

	var Week = WeekPT;
	var Month = MonthPT;

	// Desenha o calendario
	var cal = new String();
	cal += "<table>";
	cal += "<tr>";
	for (var j = 0; j < 7; j++) {
					cal += "<th>" + Week[j] + "<\/th>";
	}
	cal += "<\/tr>";
	for (var i = 0; i < nRows; i++) {
		cal += "<tr>";
		for (var j = 0; j < 7; j++) {
			if ((i == 0 && j < dayWeek) || (d > dateEnd)) {
				cal += "<td>&nbsp;<\/td>";
			} else {
				date.setDate(d);
				if (this.onDate)
					cal += "<td><a onclick='setDateFromCalendar(" + date.getFullYear() + "," + date.getMonth() + "," + d + ")'>" + this.onDate(date) + "<\/a><\/td>";
				else
					cal += "<td>" + d + "<\/td>";
				d++;
			}
		}
		cal += "<\/tr>";
	}
	cal += "<\/table>";
	if (this.onDraw instanceof Function) {
		this.onDraw(cal);
	}
}

/*			Funções personalizadas */
function setDateFromCalendar(year, month, day)
{
	var elem = cal.element;
	if (!elem)
		return;
	var date = new Date(year, month, day);
	elem.value = date.format(cal.format);
	hideCalendarNow();
}
function out(str)
{
	var elem = document.getElementById("calendar");
	var strout = new String();
	strout += '<h1><a class="sLeft" onclick="cal.year.prev()">&lt;&lt;&lt;<\/a>';
	strout += '<a class="sRight" onclick="cal.year.next()">&gt;&gt;&gt;<\/a>';
	strout += '<span>' + this.date.getFullYear() + '<\/span><\/h1>';
	strout += '<select id="selectMonth" onchange="cal.month.set(this.value)">';
	for (var i = 0; i < MonthPT.length; i++) {
		setmonth = (i == this.date.getMonth())? " selected" : "";
		strout += '<option value="' + i + '"' + setmonth + '>' + MonthPT[i] + '<\/option>';
	}
	strout += '<\/select>';
	strout += str;
	elem.innerHTML = strout;
	//document.getElementById("selectMonth").focus();
}
function drawDate(d)
{
	var date = new Date();
	if (d.format("Y-m-d") == date.format("Y-m-d"))
		return "<b><span title=\"Hoje\">" + d.getDate() + "<\/span><\/b>";
	else if (d.getDay() == 0 || d.getDay() == 6)
		return "<b class=\"weekend\">" + d.getDate() + "<\/b>";
	else
		return d.getDate();
}
var cal = new Calendar(new Date());
cal.onDraw = out;
cal.onDate = drawDate;
cal.time = null;
cal.format = null;
cal.format = 'd/m/Y';
function showCalendar(elem, src, fmt) {
	var calendar = document.getElementById("calendar");
	if (!calendar)
		return;
	if (!elem) {
		elem = src.previousSibling;
		while (elem && elem.nodeType != 1)
			elem = elem.previousSibling;
		if (!elem)
			throw "elem: undefined.";
	}
	Listener.remove("hideCalendarNow");
	clearTimeoutCalendar();
	var pos = getPosition(elem);
	var xc = (pos.left < 250) ? 0 : 100;
	var dummy = document.getElementById("calendardummy");
	if (!dummy) {
		dummy = document.createElement("iframe");
		dummy.setAttribute("id", "calendardummy");
		calendar.parentNode.appendChild(dummy);
	}
	var width = calendar.offsetWidth;
	var height = calendar.offsetHeight;
	dummy.style.width = intToPx(width);
	dummy.style.height = intToPx(height);
	alignBlock(calendar, xc + ";100", elem, xc + ";0");
	alignBlock(dummy, xc + ";100", elem, xc + ";0");
	cal.element = elem;
	cal.format = fmt;
	cal.setDateFormat(elem.value, fmt);
	cal.draw();
	Listener.add(src, "mouseout", hideCalendar, "hideCalendar");
	if (!calendar.installListener) {
		Listener.add(calendar, "mouseover", overCalendar);
		calendar.installListener = true;
	}
	Timer.setTimeout(installHideCalendar, 500);
	cal.show(true);
}
function overCalendar() {
	clearTimeoutCalendar();
	var calendar = document.getElementById("calendar");
	Listener.remove("stopPropagationCalendar");
	Listener.add(calendar, "click", stopPropagationCalendar, "stopPropagationCalendar");
}
function installHideCalendar() {
	Listener.remove("hideCalendarNow");
	Listener.add(document.documentElement, "click", hideCalendarNow, "hideCalendarNow");
}
function stopPropagationCalendar(e) {
	e.stopPropagation();
	return false;
}
function hideCalendarNow() {
	Listener.remove("hideCalendarNow");
	cal.show(false);
}
function hideCalendar() {
	cal.time = Timer.setTimeout(hideCalendarNow, 1000);
	Listener.remove("hideCalendar");
	Listener.remove("stopPropagationCalendar");
}
function clearTimeoutCalendar() {
	if (cal.time) {
		Timer.clearTimeout(cal.time);
		cal.time = null;
	}
}

	MapField = function (data) {
	this.data = data;
	this.getMainFieldName = function (name) {
		var i;
		for (i in this.data) {
			if (i == name)
				return i;
			if (this.data[i].indexOf(name) != -1)
				return i;
		}
		return null;
	}
	this.setField = function (field, values) {
		var main = this.getMainFieldName(field.name);
		var sc = new StyleClass(field);
		var value;
		if (main != null) {
			value = values.getAttribute(main);
			if (sc.isSet("date")) {
				var d = new Date();
				d.setFormat(value, "Y-m-d H:i:s");
				field.value = d.format(field.oInputDate.format);
			} else if (field.type == "checkbox") {
				field.checked = parseInt(field.value) & parseInt(value) ? true : false;
			}
		} else {
			value = values.getAttribute(field.name);
			if (sc.isSet("date")) {
				var d = new Date();
				d.setFormat(value, "Y-m-d");
				field.value = d.format(field.oInputDate.format);
			} else if (field.type == "checkbox") {
				field.checked = field.value == values.getAttribute(field.name);
			} else {
				field.value = values.getAttribute(field.name);
			}
		}
	}
	this.getField = function (values, field) {
		var sc = new StyleClass(field);
		var main = this.getMainFieldName(field.name);
		var value = field.value;
		if (main != null) {
			if (sc.isSet("date")) {
				var d = new Date();
				var attrValue = values.getAttribute(main);
				if (attrValue != null)
					d.setFormat(attrValue, "Y-m-d H:i:s");
				d.setFormat(field.value, field.oInputDate.format);
				value = d.format("Y-m-d H:i:s");
				values.setAttribute(main, value);
			} else if (field.type == "checkbox") {
				value = 0;
				var attrValue = values.getAttribute(main);
				if (attrValue != null)
					value = parseInt(attrValue);
				if (!isNaN(field.value) && field.checked)
					value |= parseInt(field.value);
				values.setAttribute(main, value);
			}
		} else {
			if (sc.isSet("date")) {
				var d = new Date();
				d.setFormat(field.value, field.oInputDate.format);
				values.setAttribute(field.name, d.format("Y-m-d"));
			} else if (field.type == "checkbox") {
				if (field.checked)
					values.setAttribute(field.name, field.value);
			} else {
				values.setAttribute(field.name, field.value);
			}
		}
	}
}
MapSets = function () {
	return {
		get: function (win) {
			if (win)
				return win.MapSets.get();
			var id = "mapsets_" + name;
			if (mapset = Register.get(id))
				return mapset;
			try {
				mapset = DOMUtils.get("m").documentElement;
				Register.set(mapset, id);
			}
			catch (e) {
				throw new Exception("MapSets: " + e);
			}
			return DOMUtils.removeTextNode(mapset, true);
		},
		getByName: function (name, win) {
			var mapsets = this.get(win);
			var i, mapset;
			for (i = 0; mapset = mapsets.childNodes.item(i); i++) {
				if (mapset.nodeName != "map-set")
					continue;
				if (mapset.getAttribute("name") == name)
					return mapset;
			}
			throw new Exception("MapSets: mapset \""+name+"\" not found");
		},
		search: function (field) {
			var mapsets = this.get();
			var i, j, mapset, map, sets = [];
			for (i = 0; mapset = mapsets.childNodes.item(i); i++) {
				if (mapset.nodeName != "map-set")
					continue;
				for (j = 0; map = mapset.childNodes.item(j); j++) {
					var flags = new String(map.getAttribute("flags"));
					if (map.getAttribute("name") == field && flags.indexOf("k") != -1) {
						sets.push(mapset);
						break;
					}
				}
			}
			return sets;
		},
		createQuery: function (form, mapset) {
			var ret = {nKeys: 0, nKeysFilled: 0, nNKeys: 0, nNKeysFilled: 0, map: {}};
			var doc = DOMUtils.createXRequest("query", "true");
			var xrequest = doc.documentElement;
			var docElem = doc.createElement(mapset.getAttribute("name"))
			xrequest.appendChild(docElem);
			for (var i = 0; map = mapset.childNodes.item(i); i++) {
				var name = String(map.getAttribute("name"));
				var flags = String(map.getAttribute("flags"));
				var elem = form[name];
				if (flags == null || flags.indexOf("k") == -1) {
					ret.nNKeys++;
					if (elem && elem.value != "")
						ret.nNKeysFilled++;
					ret.map[name] = {isKey: false, index: i};
				} else {
					ret.nKeys++;
					if (elem && elem.value != "")
						ret.nKeysFilled++;
					ret.map[name] = {isKey: true, index: i};
					if (elem)
						docElem.setAttribute(map.getAttribute("map"), elem.value);
				}
			}
			ret.document = doc;
			/* return {nKeys, nKeysFilled, nNKeys, nNKeysFilled, map: {name: {isKey, index},...}} */
			return ret;
		},
		fillResponse: function (form, mapset, response, preserve) {
			var status = response.documentElement.getAttribute("status");
			var items = response.documentElement.childNodes;
			var found = (status == 3) ? true : false;
			if (status != 3 && status != 4)
				throw new Exception("fillResponse: Error response status("+status+").");
			var map;
			for (var i = 0; map = mapset.childNodes.item(i); i++) {
				var flags = map.getAttribute("flags");
				var name = map.getAttribute("name");
				var elem = form[name];
				if (!elem || flags && flags.indexOf("k") != -1)
					continue;
				if (found) {
					for (var j = 0, item; item = items.item(j); j++) {
						if (item.nodeType != 1)
							continue;
						var value = item.getAttribute(map.getAttribute("map"));
						if (!preserve || preserve && (value != ""))
							elem.value = value;
						break;
					}
				} else {
					if (!preserve)
						elem.value = "";
				}
				if (elem != elem && elem.onchange)
					elem.onchange();
			}
			if (typeof(Dispatcher) == "object")
				Dispatcher.onChangeForm.notify(form);
		},
		getMapField: function(win) {
			var data = {};
			var main, mapsets = this.get(win);
			for (var i = 0; main = mapsets.childNodes.item(i); i++) {
				if (main.nodeName != "main")
					continue;
				var item, s = [];
				for (var j = 0; item = main.childNodes.item(j); j++) {
					if (item.nodeName != "secondary")
						continue;
					s.push(item.getAttribute("name"));
				}
				data[main.getAttribute("name")] = s;
			}
			return new MapField(data);
		}
	};
}();
PopUpList = function () {
	return {
		sep: "_",
		open: function (mapSetName, button) {
			var mapset = MapSets.getByName(mapSetName);
			var url = mapset.getAttribute("list");
			var lastWin = Register.get("idOpenList");
			if (lastWin) {
				//if (lastWin.name != mapSetName)
					//lastWin.close();

				Register.unSet("idOpenList");
			}
			var elem = null;
			if (button) {
				var sxp = new SimpleXPath(document);
				var nodes = sxp.select("../input[1]", button);
				if (nodes.length)
					elem = nodes[0];
			}
			if (elem) {
				var nodeList = document.getElementsByName(elem.name);
				var index = String(elem.name).indexOf("[]");
				if (nodeList && nodeList.length && index != -1) {
					var len = nodeList.length;
					for (var i = 0; i < len; i++) {
						var e = nodeList.item(i);
						if (elem == e)
							break;
					}
					if (i < len) {
						mapSetName += this.sep + i;
					}
				}
			}
			var win = Win.create(url, mapSetName);
			if (win)
				Register.set(win, "idOpenList");
		},
		getWindowValues: function () {
			var wn = String(window.name);
			var name = wn;
			var index = null;
			var i = wn.lastIndexOf(this.sep);
			if (i != -1) {
				var prefix = wn.substr(0, i);
				var suffix = parseInt(wn.substr(i + 1));
				if (!isNaN(suffix)) {
					name = prefix;
					index = suffix;
				}
			}
			return {name: name, index: index};
		},
		getMapsetName: function () {
			var r = this.getWindowValues();
			return r.name;
		},
		getIndex: function () {
			var r = this.getWindowValues();
			return r.index;
		},
		checkParent: function () {
			if (!window.opener) {
				window.close();
				return false;
			}
			var lastWin = window.opener.Register.get("idOpenList");
			if (!lastWin || (lastWin.name != window.name)) {
				window.close();
				return false;
			}
			return true;
		},
		load: function () {
			if (!PopUpList.checkParent())
				return false;
			var mapsetName = PopUpList.getMapsetName();
			var mapset = MapSets.getByName(mapsetName, window.opener);
			var form = window.opener.document.forms[0];
			var listForm = window.document.forms[0];
			if (!mapset || !form || !listForm)
				return false;
			var index = PopUpList.getIndex();
			var i, map;
			for (i = 0; map = mapset.childNodes.item(i); i++) {
				var flags = new String(map.getAttribute("flags"));
				var listName = map.getAttribute("map");
				var name = map.getAttribute("name");
				if (flags.indexOf("p") != -1) {
					if (index == null) {
						listForm[listName].value = form[name].value;
					} else {
						var elements = window.opener.document.getElementsByName(name + "[]");
						listForm[listName].value = elements.item(index).value;
					}
				}
			}
			return true;
		},
		pickUp: function (elem) {
			if (!PopUpList.checkParent())
				return false;
			var mapset = MapSets.getByName(PopUpList.getMapsetName(), window.opener);
			var form = window.opener.document.forms[0];
			if (!form)
				return false;
			var index = PopUpList.getIndex();
			var p = parseUrl(elem.href);
			var params = p.query.split("&");
			var values = {};
			for (var j=0; j < params.length; j++) {
				var param = params[j].split("=");
				var key = param[0];
				var value = decodeURIComponent(param[1]);
				values[key] = value;
			}
			var i, map;
			for (i = 0; map = mapset.childNodes.item(i); i++) {
				var flags = new String(map.getAttribute("flags"));
				if (flags.indexOf("k") == -1)
					continue;
				var name = map.getAttribute("map");
				if (values[name]) {
					if (index == null) {
						var elem = form[map.getAttribute("name")];
					} else {
						//var elem = form[map.getAttribute("name") + "[]"].item(index);
						var elements = window.opener.document.getElementsByName(map.getAttribute("name") + "[]");
						var elem = elements.item(index);
					}
					elem.value = values[name];
					if (elem.onchange)
						elem.onchange();
				}
			}
			if (typeof(window.opener.Dispatcher) == "object")
				window.opener.Dispatcher.onChangeForm.notify(form);
			window.close();
		}
	};
}();
function updateValuesByMapSet(elem, mapset) {
	var form = elem.form;
	var maps = mapset.childNodes;
	var preserve = Register.get("preserveUpdateValues");
	var url = mapset.getAttribute("data");
	var i, index, lastIndex, map, doRequest = false, following = false, defined = true;

/*
	var ret = MapSets.createQuery(form, mapset);
*/
	var doc = DOMUtils.createXRequest("query", "true");
	var xrequest = doc.documentElement;
	var blockname = getBlockFromUrl(url);
	var block = doc.createElement(blockname)
	xrequest.appendChild(block);
	for (i = 0; map = maps.item(i); i++) {
		var name = map.getAttribute("name");
		var flags = new String(map.getAttribute("flags"));
		if (flags.indexOf("k") == -1) {
			if (form[name]) {
				doRequest = true;
				break;
			}
			continue;
		}
		if (!following) {
			defined = false;
			if (form[name]) {
				if (form[name].value != "")
					defined = true;
				block.setAttribute(map.getAttribute("map"), form[name].value);
			}
		}
		if (elem.name == name) {
			index = i;
			following = true;
		}
		lastIndex = i;
	}
/*
	var doc = ret.document;
	index = ret.map[elem.name].index;
	for (var i=0; i < index; i++) {
		var name = maps.item(i).getAttribute("name");
		var elem = form[name];
		if (elem && elem.value == "")
			defined = false;
	}
	lastIndex = ret.nKeys - 1;
	doRequest = ret.nNKeys;
	Debugger.on();
	Debugger.print(htmlentities(xmlizeNode(mapset)));
	Debugger.print(htmlentities(xmlizeNode(doc)));
	Debugger.print("updateValuesByMapSet {index: "+index+", lastIndex: "+lastIndex+", doRequest: "+doRequest+", defined: "+defined+", dist: "+dist+"}");
	Debugger.ret();
*/
	var dist = lastIndex - index;
	if (!doRequest && (dist == 0))
		return true;

	var elemChanged;
	var found = false;
	if (dist == 1) {
		var mapValue = maps.item(lastIndex);
		elemChanged = form[mapValue.getAttribute("name")];
		if (!elemChanged || elemChanged.tagName != "SELECT")
			dist = null;
	}

	// Faz a requisição
	if (defined && (dist == 0 || dist == 1)) {
		found = true;
		var response = DOMUtils.post(url, doc);
		if (!response)
			throw new Exception("updateValuesByMapSet: response failed");
		var status = response.documentElement.getAttribute("status");
		var items = response.documentElement.childNodes;
		if (status == 4) {
			found = false;
		} else if (status == 2 || status == 1) {
			return true;
		}
	}


	// Trata a requisição
	switch (dist) {
	case 0: // ultima chave
		/*
		MapSets.fillResponse(form, mapset, response, preserve);
		*/
		for (i = index + 1; map = maps.item(i); i++) {
			var name = map.getAttribute("name");
			elemChanged = form[name];
			if (!elemChanged)
				continue;
			if (found) {
				for (var j = 0, item; item = items.item(j); j++) {
					if (item.nodeType != 1)
						continue;
					var value = item.getAttribute(map.getAttribute("map"));
					if (!preserve || preserve && (value != ""))
						elemChanged.value = value;
					break;
				}
			} else {
				if (!preserve)
					elemChanged.value = "";
			}
			if (elem != elemChanged && elemChanged.onchange)
				elemChanged.onchange();
			if (typeof(Dispatcher) == "object")
				Dispatcher.onChangeForm.notify(form);
		}
		return true;
	case 1: // penultima chave
		var prevValue = elemChanged.value;
		var selectedIndex = elemChanged.selectedIndex;
		var mSelect = new MSelect(elemChanged);
		mSelect.clear(true);
		if (found) {
			for (var j = 0, item; item = items.item(j); j++) {
				if (item.nodeType != 1)
					continue;
				var mapLabel = maps.item(lastIndex + 1);
				var label = item.getAttribute(mapLabel.getAttribute("map"));
				var value = item.getAttribute(mapValue.getAttribute("map"));
				var opt = mSelect.createOption(value, label);
				mSelect.add(opt);
			}
		}
		if (preserve && selectedIndex >= 0)
			elemChanged.value = prevValue;
		if (elemChanged && elemChanged.onchange)
			elemChanged.onchange();
		if (typeof(Dispatcher) == "object")
			Dispatcher.onChangeForm.notify(form);
		return true;
	default:
		map = maps.item(index + 1);
		elemChanged = form[map.getAttribute("name")];
		if (!elemChanged)
			return true;
		if (!preserve)
			elemChanged.value = "";
		if (elemChanged && elemChanged.onchange)
			elemChanged.onchange();
		if (typeof(Dispatcher) == "object")
			Dispatcher.onChangeForm.notify(form);
		return true;
	}
}
function updateValues(elem) {
	var mapsets = MapSets.search(elem.name);
	if (!mapsets.length)
		return;
	var i, mapset;
	for (i = 0; mapset = mapsets[i]; i++) {
		var flags = String(mapset.getAttribute("flags"));
		if (!flags || flags.indexOf("x") == -1)
			updateValuesByMapSet(elem, mapset);
	}
}
function updateXValues(form) {
	try {
		var mapsets = MapSets.get();
		var i, mapset;
		for (i = 0; i < mapsets.childNodes.length; i++) {
			var mapset = mapsets.childNodes.item(i);
			if (mapset.nodeName != "map-set")
				continue;
			var flags = String(mapset.getAttribute("flags"));
			if (flags.indexOf("x") != -1) {
				var ret = MapSets.createQuery(form, mapset);
				if (ret.nKeys == ret.nKeysFilled) {
					var response = DOMUtils.post(mapset.getAttribute("data"), ret.document);
					if (!response)
						throw new Exception("updateXValues: response failed");
					MapSets.fillResponse(form, mapset, response, true);
				}
			}
		}
	} catch (e) {
	}
}
function reloadSelects(doc)
{
	doc = doc || document;
	var form = doc.forms[0];
	if (!form || form && String(form.action).substr(-1) == "U")
		return;
	Register.set(true, "preserveUpdateValues", true);
	var mapsets = MapSets.get();
	var executed = {};
	for (var i = 0; i < mapsets.childNodes.length; i++) {
		var mapset = mapsets.childNodes.item(i);
		if (mapset.nodeName != "map-set")
			continue;
		for (var j = 0; j < mapset.childNodes.length; j++) {
			var map = mapset.childNodes.item(j);
			var flags = map.getAttribute("flags");
			var name = map.getAttribute("name");
			var elem = form[name];
			if (!elem || executed[name] || (String(flags).indexOf("k") == -1))
				continue;
			if (typeof(elem.onchange) == "function") {
				elem.onchange();
			}
			executed[name] = true;
		}
	}
	setChange(false);
	Register.set(false, "preserveUpdateValues", true);
}

	BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();

	CertResponse = function (request, status, message) {
	this.request = request;
	this.status = status;
	this.message = message;
	this.values = {};
}
CertResponse.prototype.check = function () {
	if (this.status)
		throw this.message;
}
CertResponse.prototype.set = function (name, value) {
	this.values[name] = value;
}
CertResponse.prototype.get = function (name) {
	return this.values[name];
}
			
CertRequestSPKAC = function () {
}
CertRequestSPKAC.prototype.create = function (info, bits, id) {
	var span = document.createElement("span");
	span.setAttribute("id", id);
	span.style.position = "absolute";
	span.style.left = "-999px";
	span.style.top = "-999px";
	span.style.width = "0px";
	span.style.height = "0px";
	var s = "<iframe name='" + id + "_iframe' />";
	span.innerHTML = s;
	document.body.appendChild(span);
	return {id: id, info: info, place: span, bits: bits};
}
CertRequestSPKAC.prototype.send = function (url, request, handler) {
	var bits = request.bits;
	var s = "<html><body><form action='" + url + "' method='post'>";
	s += "<keygen name='spkac' />";
	s += "<input type='hidden' name='id' value='" + request.id + "' />";
	for (name in request.info)
		s += "<input type='hidden' name='" + name + "' value='" + request.info[name]+ "' />";
	s += "</form></body></html>";
	s += "<script>";
	s += "var options = document.forms[0].spkac.options;";
	s += "for (var i = 0; i < options.length; i++)";
	s += "	if (String(options[i].firstChild.nodeValue).indexOf(" + bits + ") != -1)";
	s += "		options[i].selected = true;";
	s += "</script>";
	var win = window.frames[request.id + "_iframe"];
	win.document.open();
	win.document.write(s);
	
	win.document.close();
	
	
	// Registra o request
	request.handler = handler;
	CertTool.setRequest(request.id, request);
	
	win.document.forms[0].submit();
}
CertRequestSPKAC.prototype.accept = function (x509) {
	//window.crypto.importUserCertificates("", x509, false);
}

CertRequestPKCS10 = function () {
	this.classFactory = null;
	this.oCEnroll = null;
	this.loadCertObject();
}
CertRequestPKCS10.prototype.loadCertObject = function () {
	try {
		this.classFactory = new ActiveXObject("X509Enrollment.CX509EnrollmentWebClassFactory");
	} catch (e) {
		//if ((BrowserDetect.browser == "Explorer") && (BrowserDetect.version >= 7))
			//throw e;
		try {
			this.oCEnroll = new ActiveXObject("CEnroll.CEnroll");
		} catch (e) {
			this.oCEnroll = document.getElementById("Enroll");
			if (this.oCEnroll == null) {
				var obj = document.createElement("object");
				obj.setAttribute("classid", "clsid:127698e4-e730-4e5c-a2b1-21490a70c8a1");
				obj.setAttribute("codebase", "/CertControl/xenrlinf.cab#Version=5,131,2510,0");
				obj.setAttribute("id", "Enroll");
				document.body.appendChild(obj);
				this.oCEnroll = document.getElementById("Enroll");
			}
		}
	}
}
CertRequestPKCS10.prototype.create = function (info, bits, id) {

	var span = document.createElement("span");
	span.setAttribute("id", id);
	span.style.position = "absolute";
	span.style.left = -999;
	span.style.top = -999;
	span.style.width = 0;
	span.style.height = 0;
	var s = "<iframe name='" + id + "_iframe' />";
	span.innerHTML = s;
	document.body.appendChild(span);

	var dns = [];
	var name;				
	var names = ["CN", "O", "OU", "L", "ST", "C", "EMAIL"];
	names.indexOf = function (value) {
		for (var i = 0; i < this.length; i++) {
			if (value == this[i])
				return i;
		}
		return -1;
	}
	for (name in info)
		if (names.indexOf(String(name).toUpperCase()) != -1)
			dns.push(String(name).toUpperCase() + "=" + info[name]);
	var strDN = dns.join(",");
	var oid = "1.3.6.1.4.1.311.2.1.21";
	var pkcs10;

	/*
		Para habilitar o uso do ActiveX no IE7:
			Ferramentas > OpÃ§Ãµes da Internet > SeguranÃ§a
				NÃ­vel Personalizado > Plug-ins e Controles ActiveX
					Inicializar e cria script de controle ActiveX nÃ£o marcados com seguro para script
						Prompt
	*/
	if (this.classFactory) {
		var objEnroll = this.classFactory.CreateObject("X509Enrollment.CX509Enrollment");
		var objPrivateKey = this.classFactory.CreateObject("X509Enrollment.CX509PrivateKey");
		var objRequest = this.classFactory.CreateObject("X509Enrollment.CX509CertificateRequestPkcs10");
		var objDN = this.classFactory.CreateObject("X509Enrollment.CX500DistinguishedName");
		objPrivateKey.ProviderName = "Microsoft Enhanced RSA and AES Cryptographic Provider";
		objPrivateKey.KeySpec = "1";
		objPrivateKey.ProviderType = "24";
		objRequest.InitializeFromPrivateKey(1, objPrivateKey, "");
		objDN.Encode(strDN, 0);
		objRequest.Subject = objDN;
		objEnroll.InitializeFromRequest(objRequest);
		szDN = objEnroll.CreateRequest(1);
		pkcs10 = szDN;
	} else {
		pkcs10 = this.oCEnroll.createPKCS10(strDN, oid);
	}
	
	return {info: info, pkcs10: pkcs10, id: id, place: span};
}
CertRequestPKCS10.prototype.send = function (url, request, handler) {
	var s = "<form action='" + url + "' method='post'>";
	s += "<input type='hidden' name='pkcs10' value='" + request.pkcs10 + "' />";
	s += "<input type='hidden' name='id' value='" + request.id + "' />";
	for (name in request.info)
		s += "<input type='hidden' name='" + name + "' value='" + request.info[name]+ "' />";
	s += "</form>";
	var win = window.frames[request.id + "_iframe"];
	win.document.open();
	win.document.write(s);
	win.document.close();

	// Registra o request
	request.handler = handler;
	CertTool.setRequest(request.id, request);
	
	win.document.forms[0].submit();
}
CertRequestPKCS10.prototype.accept = function (x509) {
	if (this.classFactory) {
		var objEnroll = this.classFactory.CreateObject("X509Enrollment.CX509Enrollment");
		objEnroll.Initialize(1);
		try {
				objEnroll.InstallResponse(0, x509, 0, "");
		} catch (e) {
			alert(e.message);
			throw e;
		}
	} else {
		if (this.oCEnroll)
			this.oCEnroll.acceptPKCS7(x509);
	}
}

CertTool = function () {
	var compatible = document.body.all ? CertTool.PKCS10 : CertTool.SPKAC;
	if (compatible & CertTool.SPKAC)
		this.certRequest = new CertRequestSPKAC();
	else if (compatible & CertTool.PKCS10)
		this.certRequest = new CertRequestPKCS10();
}
CertTool.SPKAC = 1;
CertTool.PKCS10 = 2;
CertTool.REQUEST_OK = 1;
CertTool.REQUEST_ERROR = 2;
CertTool.requests = {};
CertTool.setRequest = function (id, request) {
	CertTool.requests[id] = request;
}
CertTool.getRequest = function (id) {
	return CertTool.requests[id];
}			
CertTool.prototype.createRequest = function (info, bits, id) {
	return this.certRequest.create(info, bits, id);
}
CertTool.handlerResponse = function (response) {
	if (typeof(response.request.handler) == 'function')
		response.request.handler(response);
/*
	var place = response.request.place;
	place.parentNode.removeChild(place);
*/
} 
CertTool.prototype.sendRequest = function (url, request, handler) {
	return this.certRequest.send(url, request, handler);
}
CertTool.prototype.accept = function (x509) {
	return this.certRequest.accept(x509);
}

	ReqCert = {
	update: function (form) {
		try {
			if (form.tp_cert.value != 'A' && !checkCNPJ(form.ou)) {
				alert("CNPJ inválido. Verifique se há somente dígitos numéricos.");
				return false;
			}
			var info = {};
			for (var i = 0; i < form.elements.length; i++) {
				var elem = form.elements[i];
				if (!elem.disabled)
					info[elem.name] = elem.value;
			}
			var ct = new CertTool();
			var rq = ct.createRequest(info, 1024, "csr");
			
			var handler = function (response) {
				try {
					response.check();
					var exception = response.get("exception");
					if (exception) {
						alert(exception);
					} else {
						setChange(false);
						var apply = document.getElementById("apply");
						apply.parentNode.parentNode.removeChild(apply.parentNode);
						alert(response.get("message"));
					}
				} catch (e) {
					alert(e);
				}
			}
			ct.sendRequest("I", rq, handler);
		} catch (e) {
			alert(e.message);
			throw e;
		}
		return false;
	}
};


