




















var Cookies = {

setCookie: function(name, value, lifespan, access_path) {

var cookietext = name + "=" + escape(value)
if (lifespan != null) {
var today=new Date()
var expiredate = new Date()
expiredate.setTime(today.getTime() + 1000*60*60*24*lifespan)
cookietext += "; expires=" + expiredate.toGMTString()
}
if (access_path != null) {
cookietext += "; PATH="+access_path
}
document.cookie = cookietext
return null
},


setDatedCookie: function(name, value, expire, access_path) {
var cookietext = name + "=" + escape(value)
+ ((expire == null) ? "" : ("; expires=" + expire.toGMTString()))
if (access_path != null) {
cookietext += "; PATH="+access_path
}
document.cookie = cookietext
return null
},


getCookie: function(Name) {
var search = Name + "="
var CookieString = document.cookie
var result = null
if (CookieString.length > 0) {
offset = CookieString.indexOf(search)
if (offset != -1) {
offset += search.length
end = CookieString.indexOf(";", offset)
if (end == -1)
end = CookieString.length
result = unescape(CookieString.substring(offset, end))

}
}
return result
},


deleteCookie: function(name) {
Cookies.setCookie(name, "Deleted", -1)
}

}

var pc = navigator.userAgent.toLowerCase();
var ie4_win = (pc.indexOf("win")!=-1) && (pc.indexOf("msie") != -1)
&& (parseInt(navigator.appVersion) >= 4);
var checked = false;


var is_gecko = pc.indexOf("gecko/") != -1 &&
parseFloat(pc.substring(pc.indexOf("gecko/") + 6, pc.indexOf("gecko/") + 14)) > 20030108;

function checkPost() {
if (arguments.length > 0) { window.onbeforeunload = null; }

if (!checked) {
checked = true;
return true;
}
return false;
}

function insertAtCursor(text, ta) {
var end = 0;
var scrollTop = ta.scrollTop;

ta.focus();

if (document.selection && document.selection.createRange().parentElement().tagName == 'TEXTAREA') {
var selected = document.selection.createRange().text;


end = getSelectionRangeEnd(ta);


document.selection.createRange().text = selected + text;

end += text.length;
}
else if (typeof(ta.selectionStart) != 'undefined' && typeof(ta.selectionEnd) != 'undefined') {
var selLength = ta.textLength;
var selStart = ta.selectionStart;
var selEnd = ta.selectionEnd;
if (selEnd == 1 || selEnd == 2) {
selEnd = selLength;
}
var s1 = (ta.value).substring(0, selEnd);
var s2 = (ta.value).substring(selEnd, selLength);


ta.value = s1 + text + s2;

end = selEnd + text.length;
}
else {
ta.value += text;
}

if (end > 0) {
setCaretTo(ta, end, scrollTop);
}
}

function styleTag(tag, ta) {
var end = 0;
var scrollTop = ta.scrollTop;

if (document.selection) {
if (document.selection.createRange().parentElement().tagName == 'TEXTAREA') {
var selected = document.selection.createRange().text;


end = getSelectionRangeEnd(ta);


var r = _markupText(selected, tag);

document.selection.createRange().text = r[0];

end += r[1];
}
}
else if (typeof(ta.selectionStart) != 'undefined' && typeof(ta.selectionEnd) != 'undefined') {
if (ta.selectionStart == ta.selectionEnd) {
return;
}
var selLength = ta.textLength;
var selStart = ta.selectionStart;
var selEnd = ta.selectionEnd;
if (selEnd == 1 || selEnd == 2) {
selEnd = selLength;
}
var s1 = (ta.value).substring(0, selStart);
var s2 = (ta.value).substring(selStart, selEnd);
var s3 = (ta.value).substring(selEnd, selLength);


var r = _markupText(s2, tag);

ta.value = s1 + r[0] + s3;

end = selEnd + r[1];
}
else {
return;
}

if (end > 0) {
setCaretTo(ta, end, scrollTop);
}
}

function _markupText(text, tag) {

var r = trimLeadingSpace(text);
text = r[0];
var removeSpace = r[1];


r = trimTrailingSpace(text);
text = r[0];
var addSpace = r[1];


var addedCharacters = 0;

if (text.indexOf('\n') > 0) {

var lines = text.split('\n');
var newText = '';
for (var i = 0; i < lines.length; i++) {
var line = lines[i];

r = trimLeadingSpace(line);
line = r[0];
var leadingSpaces = r[1];


r = trimTrailingSpace(line);
line = r[0];
var trailingSpaces = r[1];

if (line == '') {
newText += leadingSpaces + line + trailingSpaces;
}
else {
newText += leadingSpaces + tag + line + tag + trailingSpaces;
addedCharacters += (tag.length * 2);
}

if (i < lines.length -1) {
newText += '\n';
}
}
text = removeSpace + newText + addSpace;
}
else {
text = removeSpace + tag + text + tag + addSpace;
}

r = new Array(2);
r[0] = text;
r[1] = addedCharacters;

return r;
}

function trimLeadingSpace(text) {
var removeSpace = "";
while (text.length > 0 &&
(text.charAt(0) == ' ' ||
text.charAt(0) == '\n' ||
text.charAt(0) == '\r'))
{
removeSpace += text.charAt(0);
text = text.substring(1);
}

var r = new Array(2);
r[0] = text;
r[1] = removeSpace;
return r;
}

function trimTrailingSpace(text) {
var addSpace = "";
while (text.length > 0 &&
(text.charAt(text.length-1) == ' ' ||
text.charAt(text.length-1) == '\n' ||
text.charAt(text.length-1) == '\r'))
{
addSpace += text.charAt(text.length-1);
text = text.substring(0, text.length-1);
}

var r = new Array(2);
r[0] = text;
r[1] = addSpace;
return r;
}

function getSelectionRangeText(ta) {
if (document.selection) {

return document.selection.createRange().text;
}
else if (is_gecko) {
var start = ta.selectionStart;
var end   = ta.selectionEnd;
return ta.value.substr(start, end-start);
}
else {
return '';
}
}

function getSelectionRangeEnd(ta) {
if (document.selection) {

var range = document.selection.createRange();

var stored_range = range.duplicate();

stored_range.moveToElementText(ta);

stored_range.setEndPoint('EndToEnd', range);


var start = stored_range.text.length - range.text.length;
return start + range.text.length;
}
else if (is_gecko) {
return ta.selectionEnd;
}
else {
return 0;
}
}
function setCaretTo(ta, pos, scrollTop) {
ta.focus();
if (ta.createTextRange) {


var i = 0;
var count = 0;
var text = ta.value;
while (i > -1 && i < pos) {
i = text.indexOf("\r\n", i);
if (i >= 0) {
count++;
i += 2;
}
}

if (count > 1) {
count--;
}


var range = ta.createTextRange();
range.move("character", (pos - count));
range.select();
}
else if (ta.selectionStart) {
ta.setSelectionRange(pos, pos);
}


if (scrollTop > 0) {
ta.scrollTop = scrollTop;
}
}

function caret(ta) {
if (ie4_win && ta.createTextRange &&
document.selection.createRange().parentElement().tagName == 'TEXTAREA')
{
ta.caretPos = document.selection.createRange().duplicate();
}
}




function funcname(f) {
var s = f.toString().match(/function (\w*)/)[1];
if ((s == null) || (s.length == 0)) return "anonymous";
return s;
}


function stacktrace() {
var s = "";  // This is the string we'll return.



for(var a = arguments.caller; a != null; a = a.caller) {

s += funcname(a.callee) + "\n";




if (a.caller == a) break;
}
return s;
}

function printStackTrace() {
alert('stack trace is ' + stacktrace());
}




var hoverElements = new Array();

function onhover(el) {
if (typeof(el) == "undefined" || typeof(el.className) != "undefined") {
return;
}
hoverElements[el] = el.className;
el.className = el.className + " hilite";
}

function onhoverbyclass(el, cl) {
hoverElements[el] = el.className;
el.className = el.className + " " + cl;
}

function offhover(el) {
if (hoverElements[el]) {
el.className = hoverElements[el];
}
}

function onclick(el) {
onhover(el);
}


function clearhover(el) {
el.className = el.className.replace(/hilite/g, "")
}








var Prototype = {
Version: '1.5.0',
BrowserFeatures: {
XPath: !!document.evaluate
},

ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
emptyFunction: function() {},
K: function(x) { return x }
}

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

var Abstract = new Object();

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

Object.extend(Object, {
inspect: function(object) {
try {
if (object === undefined) return 'undefined';
if (object === null) return 'null';
return object.inspect ? object.inspect() : object.toString();
} catch (e) {
if (e instanceof RangeError) return '...';
throw e;
}
},

keys: function(object) {
var keys = [];
for (var property in object)
keys.push(property);
return keys;
},

values: function(object) {
var values = [];
for (var property in object)
values.push(object[property]);
return values;
},

clone: function(object) {
return Object.extend({}, object);
}
});

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

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

Object.extend(Number.prototype, {
toColorPart: function() {
var digits = this.toString(16);
if (this < 16) return '0' + digits;
return digits;
},

succ: function() {
return this + 1;
},

times: function(iterator) {
$R(0, this, true).each(iterator);
return this;
}
});

var Try = {
these: function() {
var returnValue;

for (var i = 0, length = arguments.length; i < length; i++) {
var lambda = arguments[i];
try {
returnValue = lambda();
break;
} catch (e) {}
}

return returnValue;
}
}



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

this.registerCallback();
},

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

stop: function() {
if (!this.timer) return;
clearInterval(this.timer);
this.timer = null;
},

onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
this.callback(this);
} finally {
this.currentlyExecuting = false;
}
}
}
}
String.interpret = function(value){
return value == null ? '' : String(value);
}

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

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

sub: function(pattern, replacement, count) {
replacement = this.gsub.prepareReplacement(replacement);
count = count === undefined ? 1 : count;

return this.gsub(pattern, function(match) {
if (--count < 0) return match[0];
return replacement(match);
});
},

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

truncate: function(length, truncation) {
length = length || 30;
truncation = truncation === undefined ? '...' : truncation;
return this.length > length ?
this.slice(0, length - truncation.length) + truncation : this;
},

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

stripTags: function() {
return this.replace(/<\/?[^>]+>/gi, '');
},

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

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

evalScripts: function() {
return this.extractScripts().map(function(script) { return eval(script) });
},

escapeHTML: function() {
var div = document.createElement('div');
var text = document.createTextNode(this);
div.appendChild(text);
return div.innerHTML;
},

unescapeHTML: function() {
var div = document.createElement('div');
div.innerHTML = this.stripTags();
return div.childNodes[0] ? (div.childNodes.length > 1 ?
$A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) :
div.childNodes[0].nodeValue) : '';
},

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

return match[1].split(separator || '&').inject({}, function(hash, pair) {
if ((pair = pair.split('='))[0]) {
var name = decodeURIComponent(pair[0]);
var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;

if (hash[name] !== undefined) {
if (hash[name].constructor != Array)
hash[name] = [hash[name]];
if (value) hash[name].push(value);
}
else hash[name] = value;
}
return hash;
});
},

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

succ: function() {
return this.slice(0, this.length - 1) +
String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
},

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

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

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

return camelized;
},

capitalize: function(){
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
},

underscore: function() {
return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
},

dasherize: function() {
return this.gsub(/_/,'-');
},

inspect: function(useDoubleQuotes) {
var escapedString = this.replace(/\\/g, '\\\\');
if (useDoubleQuotes)
return '"' + escapedString.replace(/"/g, '\\"') + '"';
else
return "'" + escapedString.replace(/'/g, '\\\'') + "'";
}
});

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

String.prototype.parseQuery = String.prototype.toQueryParams;

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

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

var $break    = new Object();
var $continue = new Object();

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

eachSlice: function(number, iterator) {
var index = -number, slices = [], array = this.toArray();
while ((index += number) < array.length)
slices.push(array.slice(index, index+number));
return slices.map(iterator);
},

all: function(iterator) {
var result = true;
this.each(function(value, index) {
result = result && !!(iterator || Prototype.K)(value, index);
if (!result) throw $break;
});
return result;
},

any: function(iterator) {
var result = false;
this.each(function(value, index) {
if (result = !!(iterator || Prototype.K)(value, index))
throw $break;
});
return result;
},

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

detect: function(iterator) {
var result;
this.each(function(value, index) {
if (iterator(value, index)) {
result = value;
throw $break;
}
});
return result;
},

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

grep: function(pattern, iterator) {
var results = [];
this.each(function(value, index) {
var stringValue = value.toString();
if (stringValue.match(pattern))
results.push((iterator || Prototype.K)(value, index));
})
return results;
},

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

inGroupsOf: function(number, fillWith) {
fillWith = fillWith === undefined ? null : fillWith;
return this.eachSlice(number, function(slice) {
while(slice.length < number) slice.push(fillWith);
return slice;
});
},

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

invoke: function(method) {
var args = $A(arguments).slice(1);
return this.map(function(value) {
return value[method].apply(value, args);
});
},

max: function(iterator) {
var result;
this.each(function(value, index) {
value = (iterator || Prototype.K)(value, index);
if (result == undefined || value >= result)
result = value;
});
return result;
},

min: function(iterator) {
var result;
this.each(function(value, index) {
value = (iterator || Prototype.K)(value, index);
if (result == undefined || value < result)
result = value;
});
return result;
},

partition: function(iterator) {
var trues = [], falses = [];
this.each(function(value, index) {
((iterator || Prototype.K)(value, index) ?
trues : falses).push(value);
});
return [trues, falses];
},

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

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

sortBy: function(iterator) {
return this.map(function(value, index) {
return {value: value, criteria: iterator(value, index)};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
}).pluck('value');
},

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

zip: function() {
var iterator = Prototype.K, args = $A(arguments);
if (typeof args.last() == 'function')
iterator = args.pop();

var collections = [this].concat(args).map($A);
return this.map(function(value, index) {
return iterator(collections.pluck(index));
});
},

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

inspect: function() {
return '#<Enumerable:' + this.toArray().inspect() + '>';
}
}

Object.extend(Enumerable, {
map:     Enumerable.collect,
find:    Enumerable.detect,
select:  Enumerable.findAll,
member:  Enumerable.include,
entries: Enumerable.toArray
});
var $A = Array.from = function(iterable) {
if (!iterable) return [];
if (iterable.toArray) {
return iterable.toArray();
} else {
var results = [];
for (var i = 0, length = iterable.length; i < length; i++)
results.push(iterable[i]);
return results;
}
}

Object.extend(Array.prototype, Enumerable);

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

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

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

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

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

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

flatten: function() {
return this.inject([], function(array, value) {
return array.concat(value && value.constructor == Array ?
value.flatten() : [value]);
});
},

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

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

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

reduce: function() {
return this.length > 1 ? this : this[0];
},

uniq: function() {
return this.inject([], function(array, value) {
return array.include(value) ? array : array.concat([value]);
});
},

clone: function() {
return [].concat(this);
},

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

inspect: function() {
return '[' + this.map(Object.inspect).join(', ') + ']';
}
});

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

function $w(string){
string = string.strip();
return string ? string.split(/\s+/) : [];
}

if(window.opera){
Array.prototype.concat = function(){
var array = [];
for(var i = 0, length = this.length; i < length; i++) array.push(this[i]);
for(var i = 0, length = arguments.length; i < length; i++) {
if(arguments[i].constructor == Array) {
for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
array.push(arguments[i][j]);
} else {
array.push(arguments[i]);
}
}
return array;
}
}
var Hash = function(obj) {
Object.extend(this, obj || {});
};

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

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

if (pair.value && pair.value.constructor == Array) {
var values = pair.value.compact();
if (values.length < 2) pair.value = values.reduce();
else {
key = encodeURIComponent(pair.key);
values.each(function(value) {
value = value != undefined ? encodeURIComponent(value) : '';
parts.push(key + '=' + encodeURIComponent(value));
});
return;
}
}
if (pair.value == undefined) pair[1] = '';
parts.push(pair.map(encodeURIComponent).join('='));
});

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

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

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

keys: function() {
return this.pluck('key');
},

values: function() {
return this.pluck('value');
},

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

remove: function() {
var result;
for(var i = 0, length = arguments.length; i < length; i++) {
var value = this[arguments[i]];
if (value !== undefined){
if (result === undefined) result = value;
else {
if (result.constructor != Array) result = [result];
result.push(value)
}
}
delete this[arguments[i]];
}
return result;
},

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

inspect: function() {
return '#<Hash:{' + this.map(function(pair) {
return pair.map(Object.inspect).join(': ');
}).join(', ') + '}>';
}
});

function $H(object) {
if (object && object.constructor == Hash) return object;
return new Hash(object);
};
ObjectRange = Class.create();
Object.extend(ObjectRange.prototype, Enumerable);
Object.extend(ObjectRange.prototype, {
initialize: function(start, end, exclusive) {
this.start = start;
this.end = end;
this.exclusive = exclusive;
},

_each: function(iterator) {
var value = this.start;
while (this.include(value)) {
iterator(value);
value = value.succ();
}
},

include: function(value) {
if (value < this.start)
return false;
if (this.exclusive)
return value < this.end;
return value <= this.end;
}
});

var $R = function(start, end, exclusive) {
return new ObjectRange(start, end, exclusive);
}

var Ajax = {
getTransport: function() {
return Try.these(
function() {return new XMLHttpRequest()},
function() {return new ActiveXObject('Msxml2.XMLHTTP')},
function() {return new ActiveXObject('Microsoft.XMLHTTP')}
) || false;
},

activeRequestCount: 0
}

Ajax.Responders = {
responders: [],

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

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

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

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

Object.extend(Ajax.Responders, Enumerable);

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

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

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

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

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

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

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

if (!['get', 'post'].include(this.method)) {

params['_method'] = this.method;
this.method = 'post';
}

params = Hash.toQueryString(params);
if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='


if (this.method == 'get' && params)
this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;

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

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

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

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

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

this.transport.send(body);


if (!this.options.asynchronous && this.transport.overrideMimeType)
this.onStateChange();

}
catch (e) {
this.dispatchException(e);
}
},

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

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

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





if (this.transport.overrideMimeType &&
(navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
headers['Connection'] = 'close';
}


if (typeof this.options.requestHeaders == 'object') {
var extras = this.options.requestHeaders;

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

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

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

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

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

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

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

if (state == 'Complete') {

this.transport.onreadystatechange = Prototype.emptyFunction;
}
},

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

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

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

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

Ajax.Updater = Class.create();

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

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

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

this.request(url);
},

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

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

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

if (this.success()) {
if (this.onComplete)
setTimeout(this.onComplete.bind(this), 10);
}
}
});

Ajax.PeriodicalUpdater = Class.create();
Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
initialize: function(container, url, options) {
this.setOptions(options);
this.onComplete = this.options.onComplete;

this.frequency = (this.options.frequency || 2);
this.decay = (this.options.decay || 1);

this.updater = {};
this.container = container;
this.url = url;

this.start();
},

start: function() {
this.options.onComplete = this.updateComplete.bind(this);
this.onTimerEvent();
},

stop: function() {
this.updater.options.onComplete = undefined;
clearTimeout(this.timer);
(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
},

updateComplete: function(request) {
if (this.options.decay) {
this.decay = (request.responseText == this.lastText ?
this.decay * this.options.decay : 1);

this.lastText = request.responseText;
}
this.timer = setTimeout(this.onTimerEvent.bind(this),
this.decay * this.frequency * 1000);
},

onTimerEvent: function() {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
function $(element) {
if (arguments.length > 1) {
for (var i = 0, elements = [], length = arguments.length; i < length; i++)
elements.push($(arguments[i]));
return elements;
}
if (typeof element == 'string')
element = document.getElementById(element);
return Element.extend(element);
}

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

document.getElementsByClassName = function(className, parentElement) {
if (Prototype.BrowserFeatures.XPath) {
var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
return document._getElementsByXPath(q, parentElement);
} else {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
var elements = [], child;
for (var i = 0, length = children.length; i < length; i++) {
child = children[i];
if (Element.hasClassName(child, className))
elements.push(Element.extend(child));
}
return elements;
}
};



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

Element.extend = function(element) {
if (!element || _nativeExtensions || element.nodeType == 3) return element;

if (!element._extended && element.tagName && element != window) {
var methods = Object.clone(Element.Methods), cache = Element.extend.cache;

if (element.tagName == 'FORM')
Object.extend(methods, Form.Methods);
if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
Object.extend(methods, Form.Element.Methods);

Object.extend(methods, Element.Methods.Simulated);

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

element._extended = true;
return element;
};

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

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

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

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

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

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

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

replace: function(element, html) {
element = $(element);
html = typeof html == 'undefined' ? '' : html.toString();
if (element.outerHTML) {
element.outerHTML = html.stripScripts();
} else {
var range = element.ownerDocument.createRange();
range.selectNodeContents(element);
element.parentNode.replaceChild(
range.createContextualFragment(html.stripScripts()), element);
}
setTimeout(function() {html.evalScripts()}, 10);
return element;
},

inspect: function(element) {
element = $(element);
var result = '<' + element.tagName.toLowerCase();
$H({'id': 'id', 'className': 'class'}).each(function(pair) {
var property = pair.first(), attribute = pair.last();
var value = (element[property] || '').toString();
if (value) result += ' ' + attribute + '=' + value.inspect(true);
});
return result + '>';
},

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

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

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

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

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

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

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

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

up: function(element, expression, index) {
return Selector.findElement($(element).ancestors(), expression, index);
},

down: function(element, expression, index) {
return Selector.findElement($(element).descendants(), expression, index);
},

previous: function(element, expression, index) {
return Selector.findElement($(element).previousSiblings(), expression, index);
},

next: function(element, expression, index) {
return Selector.findElement($(element).nextSiblings(), expression, index);
},

getElementsBySelector: function() {
var args = $A(arguments), element = $(args.shift());
return Selector.findChildElements(element, args);
},

getElementsByClassName: function(element, className) {
return document.getElementsByClassName(className, element);
},

readAttribute: function(element, name) {
element = $(element);
if (document.all && !window.opera) {
var t = Element._attributeTranslations;
if (t.values[name]) return t.values[name](element, name);
if (t.names[name])  name = t.names[name];
var attribute = element.attributes[name];
if(attribute) return attribute.nodeValue;
}
return element.getAttribute(name);
},

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

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

classNames: function(element) {
return new Element.ClassNames(element);
},

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

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

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

toggleClassName: function(element, className) {
if (!(element = $(element))) return;
Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
return element;
},

observe: function() {
Event.observe.apply(Event, arguments);
return $A(arguments).first();
},

stopObserving: function() {
Event.stopObserving.apply(Event, arguments);
return $A(arguments).first();
},


cleanWhitespace: function(element) {
element = $(element);
var node = element.firstChild;
while (node) {
var nextNode = node.nextSibling;
if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
element.removeChild(node);
node = nextNode;
}
return element;
},

empty: function(element) {
return $(element).innerHTML.match(/^\s*$/);
},

descendantOf: function(element, ancestor) {
element = $(element), ancestor = $(ancestor);
while (element = element.parentNode)
if (element == ancestor) return true;
return false;
},

scrollTo: function(element) {
element = $(element);
var pos = Position.cumulativeOffset(element);
window.scrollTo(pos[0], pos[1]);
return element;
},

getStyle: function(element, style) {
element = $(element);
if (['float','cssFloat'].include(style))
style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
style = style.camelize();
var value = element.style[style];
if (!value) {
if (document.defaultView && document.defaultView.getComputedStyle) {
var css = document.defaultView.getComputedStyle(element, null);
value = css ? css[style] : null;
} else if (element.currentStyle) {
value = element.currentStyle[style];
}
}

if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
value = element['offset'+style.capitalize()] + 'px';

if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
if (Element.getStyle(element, 'position') == 'static') value = 'auto';
if(style == 'opacity') {
if(value) return parseFloat(value);
if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
if(value[1]) return parseFloat(value[1]) / 100;
return 1.0;
}
return value == 'auto' ? null : value;
},

setStyle: function(element, style) {
element = $(element);
for (var name in style) {
var value = style[name];
if(name == 'opacity') {
if (value == 1) {
value = (/Gecko/.test(navigator.userAgent) &&
!/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
if(/MSIE/.test(navigator.userAgent) && !window.opera)
element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
} else if(value == '') {
if(/MSIE/.test(navigator.userAgent) && !window.opera)
element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
} else {
if(value < 0.00001) value = 0;
if(/MSIE/.test(navigator.userAgent) && !window.opera)
element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
'alpha(opacity='+value*100+')';
}
} else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
element.style[name.camelize()] = value;
}
return element;
},

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



var els = element.style;
var originalVisibility = els.visibility;
var originalPosition = els.position;
var originalDisplay = els.display;
els.visibility = 'hidden';
els.position = 'absolute';
els.display = 'block';
var originalWidth = element.clientWidth;
var originalHeight = element.clientHeight;
els.display = originalDisplay;
els.position = originalPosition;
els.visibility = originalVisibility;
return {width: originalWidth, height: originalHeight};
},

makePositioned: function(element) {
element = $(element);
var pos = Element.getStyle(element, 'position');
if (pos == 'static' || !pos) {
element._madePositioned = true;
element.style.position = 'relative';


if (window.opera) {
element.style.top = 0;
element.style.left = 0;
}
}
return element;
},

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

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

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

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

Element._attributeTranslations = {};

Element._attributeTranslations.names = {
colspan:   "colSpan",
rowspan:   "rowSpan",
valign:    "vAlign",
datetime:  "dateTime",
accesskey: "accessKey",
tabindex:  "tabIndex",
enctype:   "encType",
maxlength: "maxLength",
readonly:  "readOnly",
longdesc:  "longDesc"
};

Element._attributeTranslations.values = {
_getAttr: function(element, attribute) {
return element.getAttribute(attribute, 2);
},

_flag: function(element, attribute) {
return $(element).hasAttribute(attribute) ? attribute : null;
},

style: function(element) {
return element.style.cssText.toLowerCase();
},

title: function(element) {
var node = element.getAttributeNode('title');
return node.specified ? node.nodeValue : null;
}
};

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

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


if (document.all && !window.opera){
Element.Methods.update = function(element, html) {
element = $(element);
html = typeof html == 'undefined' ? '' : html.toString();
var tagName = element.tagName.toUpperCase();
if (['THEAD','TBODY','TR','TD'].include(tagName)) {
var div = document.createElement('div');
switch (tagName) {
case 'THEAD':
case 'TBODY':
div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
depth = 2;
break;
case 'TR':
div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
depth = 3;
break;
case 'TD':
div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
depth = 4;
}
$A(element.childNodes).each(function(node){
element.removeChild(node)
});
depth.times(function(){ div = div.firstChild });

$A(div.childNodes).each(
function(node){ element.appendChild(node) });
} else {
element.innerHTML = html.stripScripts();
}
setTimeout(function() {html.evalScripts()}, 10);
return element;
}
};

Object.extend(Element, Element.Methods);

var _nativeExtensions = false;

if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
var className = 'HTML' + tag + 'Element';
if(window[className]) return;
var klass = window[className] = {};
klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
});

Element.addMethods = function(methods) {
Object.extend(Element.Methods, methods || {});

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

if (typeof HTMLElement != 'undefined') {
copy(Element.Methods, HTMLElement.prototype);
copy(Element.Methods.Simulated, HTMLElement.prototype, true);
copy(Form.Methods, HTMLFormElement.prototype);
[HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
copy(Form.Element.Methods, klass.prototype);
});
_nativeExtensions = true;
}
}

var Toggle = new Object();
Toggle.display = Element.toggle;



Abstract.Insertion = function(adjacency) {
this.adjacency = adjacency;
}

Abstract.Insertion.prototype = {
initialize: function(element, content) {
this.element = $(element);
this.content = content.stripScripts();

if (this.adjacency && this.element.insertAdjacentHTML) {
try {
this.element.insertAdjacentHTML(this.adjacency, this.content);
} catch (e) {
var tagName = this.element.tagName.toUpperCase();
if (['TBODY', 'TR'].include(tagName)) {
this.insertContent(this.contentFromAnonymousTable());
} else {
throw e;
}
}
} else {
this.range = this.element.ownerDocument.createRange();
if (this.initializeRange) this.initializeRange();
this.insertContent([this.range.createContextualFragment(this.content)]);
}

setTimeout(function() {content.evalScripts()}, 10);
},

contentFromAnonymousTable: function() {
var div = document.createElement('div');
div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
return $A(div.childNodes[0].childNodes[0].childNodes);
}
}

var Insertion = new Object();

Insertion.Before = Class.create();
Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
initializeRange: function() {
this.range.setStartBefore(this.element);
},

insertContent: function(fragments) {
fragments.each((function(fragment) {
this.element.parentNode.insertBefore(fragment, this.element);
}).bind(this));
}
});

Insertion.Top = Class.create();
Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
initializeRange: function() {
this.range.selectNodeContents(this.element);
this.range.collapse(true);
},

insertContent: function(fragments) {
fragments.reverse(false).each((function(fragment) {
this.element.insertBefore(fragment, this.element.firstChild);
}).bind(this));
}
});

Insertion.Bottom = Class.create();
Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
initializeRange: function() {
this.range.selectNodeContents(this.element);
this.range.collapse(this.element);
},

insertContent: function(fragments) {
fragments.each((function(fragment) {
this.element.appendChild(fragment);
}).bind(this));
}
});

Insertion.After = Class.create();
Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
initializeRange: function() {
this.range.setStartAfter(this.element);
},

insertContent: function(fragments) {
fragments.each((function(fragment) {
this.element.parentNode.insertBefore(fragment,
this.element.nextSibling);
}).bind(this));
}
});



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

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

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

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

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

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

Object.extend(Element.ClassNames.prototype, Enumerable);
var Selector = Class.create();
Selector.prototype = {
initialize: function(expression) {
this.params = {classNames: []};
this.expression = expression.toString().strip();
this.parseExpression();
this.compileMatcher();
},

parseExpression: function() {
function abort(message) { throw 'Parse error in selector: ' + message; }

if (this.expression == '')  abort('empty expression');

var params = this.params, expr = this.expression, match, modifier, clause, rest;
while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
params.attributes = params.attributes || [];
params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
expr = match[1];
}

if (expr == '*') return this.params.wildcard = true;

while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
modifier = match[1], clause = match[2], rest = match[3];
switch (modifier) {
case '#':       params.id = clause; break;
case '.':       params.classNames.push(clause); break;
case '':
case undefined: params.tagName = clause.toUpperCase(); break;
default:        abort(expr.inspect());
}
expr = rest;
}

if (expr.length > 0) abort(expr.inspect());
},

buildMatchExpression: function() {
var params = this.params, conditions = [], clause;

if (params.wildcard)
conditions.push('true');
if (clause = params.id)
conditions.push('element.readAttribute("id") == ' + clause.inspect());
if (clause = params.tagName)
conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
if ((clause = params.classNames).length > 0)
for (var i = 0, length = clause.length; i < length; i++)
conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
if (clause = params.attributes) {
clause.each(function(attribute) {
var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
var splitValueBy = function(delimiter) {
return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
}

switch (attribute.operator) {
case '=':       conditions.push(value + ' == ' + attribute.value.inspect()); break;
case '~=':      conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
case '|=':      conditions.push(
splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
); break;
case '!=':      conditions.push(value + ' != ' + attribute.value.inspect()); break;
case '':
case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
default:        throw 'Unknown operator ' + attribute.operator + ' in selector';
}
});
}

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

compileMatcher: function() {
this.match = new Function('element', 'if (!element.tagName) return false; \
element = $(element); \
return ' + this.buildMatchExpression());
},

findElements: function(scope) {
var element;

if (element = $(this.params.id))
if (this.match(element))
if (!scope || Element.childOf(element, scope))
return [element];

scope = (scope || document).getElementsByTagName(this.params.tagName || '*');

var results = [];
for (var i = 0, length = scope.length; i < length; i++)
if (this.match(element = scope[i]))
results.push(Element.extend(element));

return results;
},

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

Object.extend(Selector, {
matchElements: function(elements, expression) {
var selector = new Selector(expression);
return elements.select(selector.match.bind(selector)).map(Element.extend);
},

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

findChildElements: function(element, expressions) {
return expressions.map(function(expression) {
return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
var selector = new Selector(expr);
return results.inject([], function(elements, result) {
return elements.concat(selector.findElements(result || element));
});
});
}).flatten();
}
});

function $$() {
return Selector.findChildElements(document, $A(arguments));
}
var Form = {
reset: function(form) {
$(form).reset();
return form;
},

serializeElements: function(elements, getHash) {
var data = elements.inject({}, function(result, element) {
if (!element.disabled && element.name) {
var key = element.name, value = $(element).getValue();
if (value != undefined) {
if (result[key]) {
if (result[key].constructor != Array) result[key] = [result[key]];
result[key].push(value);
}
else result[key] = value;
}
}
return result;
});

return getHash ? data : Hash.toQueryString(data);
}
};

Form.Methods = {
serialize: function(form, getHash) {
return Form.serializeElements(Form.getElements(form), getHash);
},

getElements: function(form) {
return $A($(form).getElementsByTagName('*')).inject([],
function(elements, child) {
if (Form.Element.Serializers[child.tagName.toLowerCase()])
elements.push(Element.extend(child));
return elements;
}
);
},

getInputs: function(form, typeName, name) {
form = $(form);
var inputs = form.getElementsByTagName('input');

if (!typeName && !name) return $A(inputs).map(Element.extend);

for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
var input = inputs[i];
if ((typeName && input.type != typeName) || (name && input.name != name))
continue;
matchingInputs.push(Element.extend(input));
}

return matchingInputs;
},

disable: function(form) {
form = $(form);
form.getElements().each(function(element) {
element.blur();
element.disabled = 'true';
});
return form;
},

enable: function(form) {
form = $(form);
form.getElements().each(function(element) {
element.disabled = '';
});
return form;
},

findFirstElement: function(form) {
return $(form).getElements().find(function(element) {
return element.type != 'hidden' && !element.disabled &&
['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
});
},

focusFirstElement: function(form) {
form = $(form);
form.findFirstElement().activate();
return form;
}
}

Object.extend(Form, Form.Methods);



Form.Element = {
focus: function(element) {
$(element).focus();
return element;
},

select: function(element) {
$(element).select();
return element;
}
}

Form.Element.Methods = {
serialize: function(element) {
element = $(element);
if (!element.disabled && element.name) {
var value = element.getValue();
if (value != undefined) {
var pair = {};
pair[element.name] = value;
return Hash.toQueryString(pair);
}
}
return '';
},

getValue: function(element) {
element = $(element);
var method = element.tagName.toLowerCase();
return Form.Element.Serializers[method](element);
},

clear: function(element) {
$(element).value = '';
return element;
},

present: function(element) {
return $(element).value != '';
},

activate: function(element) {
element = $(element);
element.focus();
if (element.select && ( element.tagName.toLowerCase() != 'input' ||
!['button', 'reset', 'submit'].include(element.type) ) )
element.select();
return element;
},

disable: function(element) {
element = $(element);
element.disabled = true;
return element;
},

enable: function(element) {
element = $(element);
element.blur();
element.disabled = false;
return element;
}
}

Object.extend(Form.Element, Form.Element.Methods);
var Field = Form.Element;
var $F = Form.Element.getValue;



Form.Element.Serializers = {
input: function(element) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
return Form.Element.Serializers.inputSelector(element);
default:
return Form.Element.Serializers.textarea(element);
}
},

inputSelector: function(element) {
return element.checked ? element.value : null;
},

textarea: function(element) {
return element.value;
},

select: function(element) {
return this[element.type == 'select-one' ?
'selectOne' : 'selectMany'](element);
},

selectOne: function(element) {
var index = element.selectedIndex;
return index >= 0 ? this.optionValue(element.options[index]) : null;
},

selectMany: function(element) {
var values, length = element.length;
if (!length) return null;

for (var i = 0, values = []; i < length; i++) {
var opt = element.options[i];
if (opt.selected) values.push(this.optionValue(opt));
}
return values;
},

optionValue: function(opt) {

return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
}
}



Abstract.TimedObserver = function() {}
Abstract.TimedObserver.prototype = {
initialize: function(element, frequency, callback) {
this.frequency = frequency;
this.element   = $(element);
this.callback  = callback;

this.lastValue = this.getValue();
this.registerCallback();
},

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

onTimerEvent: function() {
var value = this.getValue();
var changed = ('string' == typeof this.lastValue && 'string' == typeof value
? this.lastValue != value : String(this.lastValue) != String(value));
if (changed) {
this.callback(this.element, value);
this.lastValue = value;
}
}
}

Form.Element.Observer = Class.create();
Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
getValue: function() {
return Form.Element.getValue(this.element);
}
});

Form.Observer = Class.create();
Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
getValue: function() {
return Form.serialize(this.element);
}
});



Abstract.EventObserver = function() {}
Abstract.EventObserver.prototype = {
initialize: function(element, callback) {
this.element  = $(element);
this.callback = callback;

this.lastValue = this.getValue();
if (this.element.tagName.toLowerCase() == 'form')
this.registerFormCallbacks();
else
this.registerCallback(this.element);
},

onElementEvent: function() {
var value = this.getValue();
if (this.lastValue != value) {
this.callback(this.element, value);
this.lastValue = value;
}
},

registerFormCallbacks: function() {
Form.getElements(this.element).each(this.registerCallback.bind(this));
},

registerCallback: function(element) {
if (element.type) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
default:
Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}
}
}
}

Form.Element.EventObserver = Class.create();
Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
getValue: function() {
return Form.Element.getValue(this.element);
}
});

Form.EventObserver = Class.create();
Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
getValue: function() {
return Form.serialize(this.element);
}
});
if (!window.Event) {
var Event = new Object();
}

Object.extend(Event, {
KEY_BACKSPACE: 8,
KEY_TAB:       9,
KEY_RETURN:   13,
KEY_ESC:      27,
KEY_LEFT:     37,
KEY_UP:       38,
KEY_RIGHT:    39,
KEY_DOWN:     40,
KEY_DELETE:   46,
KEY_HOME:     36,
KEY_END:      35,
KEY_PAGEUP:   33,
KEY_PAGEDOWN: 34,

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

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

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

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

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



findElement: function(event, tagName) {
var element = Event.element(event);
while (element.parentNode && (!element.tagName ||
(element.tagName.toUpperCase() != tagName.toUpperCase())))
element = element.parentNode;
return element;
},

observers: false,

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

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

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

if (name == 'keypress' &&
(navigator.appVersion.match(/Konqueror|Safari|KHTML/)
|| element.attachEvent))
name = 'keydown';

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

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

if (name == 'keypress' &&
(navigator.appVersion.match(/Konqueror|Safari|KHTML/)
|| element.detachEvent))
name = 'keydown';

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


if (navigator.appVersion.match(/\bMSIE\b/))
Event.observe(window, 'unload', Event.unloadCache, false);
var Position = {



includeScrollOffsets: false,



prepare: function() {
this.deltaX =  window.pageXOffset
|| document.documentElement.scrollLeft
|| document.body.scrollLeft
|| 0;
this.deltaY =  window.pageYOffset
|| document.documentElement.scrollTop
|| document.body.scrollTop
|| 0;
},

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

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

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

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

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

return document.body;
},


within: function(element, x, y) {
if (this.includeScrollOffsets)
return this.withinIncludingScrolloffsets(element, x, y);
this.xcomp = x;
this.ycomp = y;
this.offset = this.cumulativeOffset(element);

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

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

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

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


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

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

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


if (element.offsetParent==document.body)
if (Element.getStyle(element,'position')=='absolute') break;

} while (element = element.offsetParent);

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

return [valueL, valueT];
},

clone: function(source, target) {
var options = Object.extend({
setLeft:    true,
setTop:     true,
setWidth:   true,
setHeight:  true,
offsetTop:  0,
offsetLeft: 0
}, arguments[2] || {})


source = $(source);
var p = Position.page(source);


target = $(target);
var delta = [0, 0];
var parent = null;


if (Element.getStyle(target,'position') == 'absolute') {
parent = Position.offsetParent(target);
delta = Position.page(parent);
}


if (parent == document.body) {
delta[0] -= document.body.offsetLeft;
delta[1] -= document.body.offsetTop;
}


if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
if(options.setHeight) target.style.height = source.offsetHeight + 'px';
},

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

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

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

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

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

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

element.style.top    = top + 'px';
element.style.left   = left + 'px';
element.style.height = element._originalHeight;
element.style.width  = element._originalWidth;
}
}




if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
Position.cumulativeOffset = function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop  || 0;
valueL += element.offsetLeft || 0;
if (element.offsetParent == document.body)
if (Element.getStyle(element, 'position') == 'absolute') break;

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

return [valueL, valueT];
}
}

Element.addMethods();

























var Scriptaculous = {
Version: '1.7.0',
require: function(libraryName) {

document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
},
load: function() {
if((typeof Prototype=='undefined') ||
(typeof Element == 'undefined') ||
(typeof Element.Methods=='undefined') ||
parseFloat(Prototype.Version.split(".")[0] + "." +
Prototype.Version.split(".")[1]) < 1.5)
throw("script.aculo.us requires the Prototype JavaScript framework >= 1.5.0");

$A(document.getElementsByTagName("script")).findAll( function(s) {
return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
}).each( function(s) {
var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
var includes = s.src.match(/\?.*load=([a-z,]*)/);
(includes ? includes[1] : 'builder,effects,dragdrop,controls,slider').split(',').each(
function(include) { Scriptaculous.require(path+include+'.js') });
});
}
}

Scriptaculous.load();













String.prototype.parseColor = function() {
var color = '#';
if(this.slice(0,4) == 'rgb(') {
var cols = this.slice(4,this.length-1).split(',');
var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
} else {
if(this.slice(0,1) == '#') {
if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
if(this.length==7) color = this.toLowerCase();
}
}
return(color.length==7 ? color : (arguments[0] || this));
}



Element.collectTextNodes = function(element) {
return $A($(element).childNodes).collect( function(node) {
return (node.nodeType==3 ? node.nodeValue :
(node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
}).flatten().join('');
}

Element.collectTextNodesIgnoreClass = function(element, className) {
return $A($(element).childNodes).collect( function(node) {
return (node.nodeType==3 ? node.nodeValue :
((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
Element.collectTextNodesIgnoreClass(node, className) : ''));
}).flatten().join('');
}

Element.setContentZoom = function(element, percent) {
element = $(element);
element.setStyle({fontSize: (percent/100) + 'em'});
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
return element;
}

Element.getOpacity = function(element){
return $(element).getStyle('opacity');
}

Element.setOpacity = function(element, value){
return $(element).setStyle({opacity:value});
}

Element.getInlineOpacity = function(element){
return $(element).style.opacity || '';
}

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



Array.prototype.call = function() {
var args = arguments;
this.each(function(f){ f.apply(this, args) });
}



var Effect = {
_elementDoesNotExistError: {
name: 'ElementDoesNotExistError',
message: 'The specified DOM element does not exist, but is required for this effect to operate'
},
tagifyText: function(element) {
if(typeof Builder == 'undefined')
throw("Effect.tagifyText requires including script.aculo.us' builder.js library");

var tagifyStyle = 'position:relative';
if(/MSIE/.test(navigator.userAgent) && !window.opera) tagifyStyle += ';zoom:1';

element = $(element);
$A(element.childNodes).each( function(child) {
if(child.nodeType==3) {
child.nodeValue.toArray().each( function(character) {
element.insertBefore(
Builder.node('span',{style: tagifyStyle},
character == ' ' ? String.fromCharCode(160) : character),
child);
});
Element.remove(child);
}
});
},
multiple: function(element, effect) {
var elements;
if(((typeof element == 'object') ||
(typeof element == 'function')) &&
(element.length))
elements = element;
else
elements = $(element).childNodes;

var options = Object.extend({
speed: 0.1,
delay: 0.0
}, arguments[2] || {});
var masterDelay = options.delay;

$A(elements).each( function(element, index) {
new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
});
},
PAIRS: {
'slide':  ['SlideDown','SlideUp'],
'blind':  ['BlindDown','BlindUp'],
'appear': ['Appear','Fade']
},
toggle: function(element, effect) {
element = $(element);
effect = (effect || 'appear').toLowerCase();
var options = Object.extend({
queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
}, arguments[2] || {});
Effect[element.visible() ?
Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
}
};

var Effect2 = Effect; // deprecated



Effect.Transitions = {
linear: Prototype.K,
sinoidal: function(pos) {
return (-Math.cos(pos*Math.PI)/2) + 0.5;
},
reverse: function(pos) {
return 1-pos;
},
flicker: function(pos) {
return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
},
wobble: function(pos) {
return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
},
pulse: function(pos, pulses) {
pulses = pulses || 5;
return (
Math.round((pos % (1/pulses)) * pulses) == 0 ?
((pos * pulses * 2) - Math.floor(pos * pulses * 2)) :
1 - ((pos * pulses * 2) - Math.floor(pos * pulses * 2))
);
},
none: function(pos) {
return 0;
},
full: function(pos) {
return 1;
}
};



Effect.ScopedQueue = Class.create();
Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
initialize: function() {
this.effects  = [];
this.interval = null;
},
_each: function(iterator) {
this.effects._each(iterator);
},
add: function(effect) {
var timestamp = new Date().getTime();

var position = (typeof effect.options.queue == 'string') ?
effect.options.queue : effect.options.queue.position;

switch(position) {
case 'front':

this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
e.startOn  += effect.finishOn;
e.finishOn += effect.finishOn;
});
break;
case 'with-last':
timestamp = this.effects.pluck('startOn').max() || timestamp;
break;
case 'end':

timestamp = this.effects.pluck('finishOn').max() || timestamp;
break;
}

effect.startOn  += timestamp;
effect.finishOn += timestamp;

if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
this.effects.push(effect);

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

Effect.Queues = {
instances: $H(),
get: function(queueName) {
if(typeof queueName != 'string') return queueName;

if(!this.instances[queueName])
this.instances[queueName] = new Effect.ScopedQueue();

return this.instances[queueName];
}
}
Effect.Queue = Effect.Queues.get('global');

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

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

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

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

Effect.Opacity = Class.create();
Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
if(!this.element) throw(Effect._elementDoesNotExistError);

if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
this.element.setStyle({zoom: 1});
var options = Object.extend({
from: this.element.getOpacity() || 0.0,
to:   1.0
}, arguments[1] || {});
this.start(options);
},
update: function(position) {
this.element.setOpacity(position);
}
});

Effect.Move = Class.create();
Object.extend(Object.extend(Effect.Move.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
if(!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
x:    0,
y:    0,
mode: 'relative'
}, arguments[1] || {});
this.start(options);
},
setup: function() {




this.element.makePositioned();
this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
if(this.options.mode == 'absolute') {

this.options.x = this.options.x - this.originalLeft;
this.options.y = this.options.y - this.originalTop;
}
},
update: function(position) {
this.element.setStyle({
left: Math.round(this.options.x  * position + this.originalLeft) + 'px',
top:  Math.round(this.options.y  * position + this.originalTop)  + 'px'
});
}
});


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

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

this.originalStyle = {};
['top','left','width','height','fontSize'].each( function(k) {
this.originalStyle[k] = this.element.style[k];
}.bind(this));

this.originalTop  = this.element.offsetTop;
this.originalLeft = this.element.offsetLeft;

var fontSize = this.element.getStyle('font-size') || '100%';
['em','px','%','pt'].each( function(fontSizeType) {
if(fontSize.indexOf(fontSizeType)>0) {
this.fontSize     = parseFloat(fontSize);
this.fontSizeType = fontSizeType;
}
}.bind(this));

this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;

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

Effect.Highlight = Class.create();
Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
if(!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
this.start(options);
},
setup: function() {

if(this.element.getStyle('display')=='none') { this.cancel(); return; }

this.oldStyle = {};
if (!this.options.keepBackgroundImage) {
this.oldStyle.backgroundImage = this.element.getStyle('background-image');
this.element.setStyle({backgroundImage: 'none'});
}
if(!this.options.endcolor)
this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
if(!this.options.restorecolor)
this.options.restorecolor = this.element.getStyle('background-color');

this._base  = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
},
update: function(position) {
this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
},
finish: function() {
this.element.setStyle(Object.extend(this.oldStyle, {
backgroundColor: this.options.restorecolor
}));
}
});

Effect.ScrollTo = Class.create();
Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
this.start(arguments[1] || {});
},
setup: function() {
Position.prepare();
var offsets = Position.cumulativeOffset(this.element);
if(this.options.offset) offsets[1] += this.options.offset;
var max = window.innerHeight ?
window.height - window.innerHeight :
document.body.scrollHeight -
(document.documentElement.clientHeight ?
document.documentElement.clientHeight : document.body.clientHeight);
this.scrollStart = Position.deltaY;
this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
},
update: function(position) {
Position.prepare();
window.scrollTo(Position.deltaX,
this.scrollStart + (position*this.delta));
}
});



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

Effect.Appear = function(element) {
element = $(element);
var options = Object.extend({
from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
to:   1.0,

afterFinishInternal: function(effect) {
effect.element.forceRerendering();
},
beforeSetup: function(effect) {
effect.element.setOpacity(effect.options.from).show();
}}, arguments[1] || {});
return new Effect.Opacity(element,options);
}

Effect.Puff = function(element) {
element = $(element);
var oldStyle = {
opacity: element.getInlineOpacity(),
position: element.getStyle('position'),
top:  element.style.top,
left: element.style.left,
width: element.style.width,
height: element.style.height
};
return new Effect.Parallel(
[ new Effect.Scale(element, 200,
{ sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
Object.extend({ duration: 1.0,
beforeSetupInternal: function(effect) {
Position.absolutize(effect.effects[0].element)
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().setStyle(oldStyle); }
}, arguments[1] || {})
);
}

Effect.BlindUp = function(element) {
element = $(element);
element.makeClipping();
return new Effect.Scale(element, 0,
Object.extend({ scaleContent: false,
scaleX: false,
restoreAfterFinish: true,
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping();
}
}, arguments[1] || {})
);
}

Effect.BlindDown = function(element) {
element = $(element);
var elementDimensions = element.getDimensions();
return new Effect.Scale(element, 100, Object.extend({
scaleContent: false,
scaleX: false,
scaleFrom: 0,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
effect.element.makeClipping().setStyle({height: '0px'}).show();
},
afterFinishInternal: function(effect) {
effect.element.undoClipping();
}
}, arguments[1] || {}));
}

Effect.SwitchOff = function(element) {
element = $(element);
var oldOpacity = element.getInlineOpacity();
return new Effect.Appear(element, Object.extend({
duration: 0.4,
from: 0,
transition: Effect.Transitions.flicker,
afterFinishInternal: function(effect) {
new Effect.Scale(effect.element, 1, {
duration: 0.3, scaleFromCenter: true,
scaleX: false, scaleContent: false, restoreAfterFinish: true,
beforeSetup: function(effect) {
effect.element.makePositioned().makeClipping();
},
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
}
})
}
}, arguments[1] || {}));
}

Effect.DropOut = function(element) {
element = $(element);
var oldStyle = {
top: element.getStyle('top'),
left: element.getStyle('left'),
opacity: element.getInlineOpacity() };
return new Effect.Parallel(
[ new Effect.Move(element, {x: 0, y: 100, sync: true }),
new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
Object.extend(
{ duration: 0.5,
beforeSetup: function(effect) {
effect.effects[0].element.makePositioned();
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
}
}, arguments[1] || {}));
}

Effect.Shake = function(element) {
element = $(element);
var oldStyle = {
top: element.getStyle('top'),
left: element.getStyle('left') };
return new Effect.Move(element,
{ x:  20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: -40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x:  40, y: 0, duration: 0.1,  afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: -20, y: 0, duration: 0.05, afterFinishInternal: function(effect) {
effect.element.undoPositioned().setStyle(oldStyle);
}}) }}) }}) }}) }}) }});
}

Effect.SlideDown = function(element) {
element = $(element).cleanWhitespace();

var oldInnerBottom = element.down().getStyle('bottom');
var elementDimensions = element.getDimensions();
return new Effect.Scale(element, 100, Object.extend({
scaleContent: false,
scaleX: false,
scaleFrom: window.opera ? 0 : 1,
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
restoreAfterFinish: true,
afterSetup: function(effect) {
effect.element.makePositioned();
effect.element.down().makePositioned();
if(window.opera) effect.element.setStyle({top: ''});
effect.element.makeClipping().setStyle({height: '0px'}).show();
},
afterUpdateInternal: function(effect) {
effect.element.down().setStyle({bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' });
},
afterFinishInternal: function(effect) {
effect.element.undoClipping().undoPositioned();
effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
}, arguments[1] || {})
);
}

Effect.SlideUp = function(element) {
element = $(element).cleanWhitespace();
var oldInnerBottom = element.down().getStyle('bottom');
return new Effect.Scale(element, window.opera ? 0 : 1,
Object.extend({ scaleContent: false,
scaleX: false,
scaleMode: 'box',
scaleFrom: 100,
restoreAfterFinish: true,
beforeStartInternal: function(effect) {
effect.element.makePositioned();
effect.element.down().makePositioned();
if(window.opera) effect.element.setStyle({top: ''});
effect.element.makeClipping().show();
},
afterUpdateInternal: function(effect) {
effect.element.down().setStyle({bottom:
(effect.dims[0] - effect.element.clientHeight) + 'px' });
},
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().undoPositioned().setStyle({bottom: oldInnerBottom});
effect.element.down().undoPositioned();
}
}, arguments[1] || {})
);
}


Effect.Squish = function(element) {
return new Effect.Scale(element, window.opera ? 1 : 0, {
restoreAfterFinish: true,
beforeSetup: function(effect) {
effect.element.makeClipping();
},
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping();
}
});
}

Effect.Grow = function(element) {
element = $(element);
var options = Object.extend({
direction: 'center',
moveTransition: Effect.Transitions.sinoidal,
scaleTransition: Effect.Transitions.sinoidal,
opacityTransition: Effect.Transitions.full
}, arguments[1] || {});
var oldStyle = {
top: element.style.top,
left: element.style.left,
height: element.style.height,
width: element.style.width,
opacity: element.getInlineOpacity() };

var dims = element.getDimensions();
var initialMoveX, initialMoveY;
var moveX, moveY;

switch (options.direction) {
case 'top-left':
initialMoveX = initialMoveY = moveX = moveY = 0;
break;
case 'top-right':
initialMoveX = dims.width;
initialMoveY = moveY = 0;
moveX = -dims.width;
break;
case 'bottom-left':
initialMoveX = moveX = 0;
initialMoveY = dims.height;
moveY = -dims.height;
break;
case 'bottom-right':
initialMoveX = dims.width;
initialMoveY = dims.height;
moveX = -dims.width;
moveY = -dims.height;
break;
case 'center':
initialMoveX = dims.width / 2;
initialMoveY = dims.height / 2;
moveX = -dims.width / 2;
moveY = -dims.height / 2;
break;
}

return new Effect.Move(element, {
x: initialMoveX,
y: initialMoveY,
duration: 0.01,
beforeSetup: function(effect) {
effect.element.hide().makeClipping().makePositioned();
},
afterFinishInternal: function(effect) {
new Effect.Parallel(
[ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
new Effect.Scale(effect.element, 100, {
scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
], Object.extend({
beforeSetup: function(effect) {
effect.effects[0].element.setStyle({height: '0px'}).show();
},
afterFinishInternal: function(effect) {
effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
}
}, options)
)
}
});
}

Effect.Shrink = function(element) {
element = $(element);
var options = Object.extend({
direction: 'center',
moveTransition: Effect.Transitions.sinoidal,
scaleTransition: Effect.Transitions.sinoidal,
opacityTransition: Effect.Transitions.none
}, arguments[1] || {});
var oldStyle = {
top: element.style.top,
left: element.style.left,
height: element.style.height,
width: element.style.width,
opacity: element.getInlineOpacity() };

var dims = element.getDimensions();
var moveX, moveY;

switch (options.direction) {
case 'top-left':
moveX = moveY = 0;
break;
case 'top-right':
moveX = dims.width;
moveY = 0;
break;
case 'bottom-left':
moveX = 0;
moveY = dims.height;
break;
case 'bottom-right':
moveX = dims.width;
moveY = dims.height;
break;
case 'center':
moveX = dims.width / 2;
moveY = dims.height / 2;
break;
}

return new Effect.Parallel(
[ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
], Object.extend({
beforeStartInternal: function(effect) {
effect.effects[0].element.makePositioned().makeClipping();
},
afterFinishInternal: function(effect) {
effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
}, options)
);
}

Effect.Pulsate = function(element) {
element = $(element);
var options    = arguments[1] || {};
var oldOpacity = element.getInlineOpacity();
var transition = options.transition || Effect.Transitions.sinoidal;
var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
reverser.bind(transition);
return new Effect.Opacity(element,
Object.extend(Object.extend({  duration: 2.0, from: 0,
afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
}, options), {transition: reverser}));
}

Effect.Fold = function(element) {
element = $(element);
var oldStyle = {
top: element.style.top,
left: element.style.left,
width: element.style.width,
height: element.style.height };
element.makeClipping();
return new Effect.Scale(element, 5, Object.extend({
scaleContent: false,
scaleX: false,
afterFinishInternal: function(effect) {
new Effect.Scale(element, 1, {
scaleContent: false,
scaleY: false,
afterFinishInternal: function(effect) {
effect.element.hide().undoClipping().setStyle(oldStyle);
} });
}}, arguments[1] || {}));
};

Effect.Morph = Class.create();
Object.extend(Object.extend(Effect.Morph.prototype, Effect.Base.prototype), {
initialize: function(element) {
this.element = $(element);
if(!this.element) throw(Effect._elementDoesNotExistError);
var options = Object.extend({
style: {}
}, arguments[1] || {});
if (typeof options.style == 'string') {
if(options.style.indexOf(':') == -1) {
var cssText = '', selector = '.' + options.style;
$A(document.styleSheets).reverse().each(function(styleSheet) {
if (styleSheet.cssRules) cssRules = styleSheet.cssRules;
else if (styleSheet.rules) cssRules = styleSheet.rules;
$A(cssRules).reverse().each(function(rule) {
if (selector == rule.selectorText) {
cssText = rule.style.cssText;
throw $break;
}
});
if (cssText) throw $break;
});
this.style = cssText.parseStyle();
options.afterFinishInternal = function(effect){
effect.element.addClassName(effect.options.style);
effect.transforms.each(function(transform) {
if(transform.style != 'opacity')
effect.element.style[transform.style.camelize()] = '';
});
}
} else this.style = options.style.parseStyle();
} else this.style = $H(options.style)
this.start(options);
},
setup: function(){
function parseColor(color){
if(!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
color = color.parseColor();
return $R(0,2).map(function(i){
return parseInt( color.slice(i*2+1,i*2+3), 16 )
});
}
this.transforms = this.style.map(function(pair){
var property = pair[0].underscore().dasherize(), value = pair[1], unit = null;

if(value.parseColor('#zzzzzz') != '#zzzzzz') {
value = value.parseColor();
unit  = 'color';
} else if(property == 'opacity') {
value = parseFloat(value);
if(/MSIE/.test(navigator.userAgent) && !window.opera && (!this.element.currentStyle.hasLayout))
this.element.setStyle({zoom: 1});
} else if(Element.CSS_LENGTH.test(value))
var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/),
value = parseFloat(components[1]), unit = (components.length == 3) ? components[2] : null;

var originalValue = this.element.getStyle(property);
return $H({
style: property,
originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
targetValue: unit=='color' ? parseColor(value) : value,
unit: unit
});
}.bind(this)).reject(function(transform){
return (
(transform.originalValue == transform.targetValue) ||
(
transform.unit != 'color' &&
(isNaN(transform.originalValue) || isNaN(transform.targetValue))
)
)
});
},
update: function(position) {
var style = $H(), value = null;
this.transforms.each(function(transform){
value = transform.unit=='color' ?
$R(0,2).inject('#',function(m,v,i){
return m+(Math.round(transform.originalValue[i]+
(transform.targetValue[i] - transform.originalValue[i])*position)).toColorPart() }) :
transform.originalValue + Math.round(
((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
style[transform.style] = value;
});
this.element.setStyle(style);
}
});

Effect.Transform = Class.create();
Object.extend(Effect.Transform.prototype, {
initialize: function(tracks){
this.tracks  = [];
this.options = arguments[1] || {};
this.addTracks(tracks);
},
addTracks: function(tracks){
tracks.each(function(track){
var data = $H(track).values().first();
this.tracks.push($H({
ids:     $H(track).keys().first(),
effect:  Effect.Morph,
options: { style: data }
}));
}.bind(this));
return this;
},
play: function(){
return new Effect.Parallel(
this.tracks.map(function(track){
var elements = [$(track.ids) || $$(track.ids)].flatten();
return elements.map(function(e){ return new track.effect(e, Object.extend({ sync:true }, track.options)) });
}).flatten(),
this.options
);
}
});

Element.CSS_PROPERTIES = $w(
'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
'fontSize fontWeight height left letterSpacing lineHeight ' +
'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
'right textIndent top width wordSpacing zIndex');

Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;

String.prototype.parseStyle = function(){
var element = Element.extend(document.createElement('div'));
element.innerHTML = '<div style="' + this + '"></div>';
var style = element.down().style, styleRules = $H();

Element.CSS_PROPERTIES.each(function(property){
if(style[property]) styleRules[property] = style[property];
});
if(/MSIE/.test(navigator.userAgent) && !window.opera && this.indexOf('opacity') > -1) {
styleRules.opacity = this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1];
}
return styleRules;
};

Element.morph = function(element, style) {
new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || {}));
return element;
};

['setOpacity','getOpacity','getInlineOpacity','forceRerendering','setContentZoom',
'collectTextNodes','collectTextNodesIgnoreClass','morph'].each(
function(f) { Element.Methods[f] = Element[f]; }
);

Element.Methods.visualEffect = function(element, effect, options) {
s = effect.gsub(/_/, '-').camelize();
effect_class = s.charAt(0).toUpperCase() + s.substring(1);
new Effect[effect_class](element, options);
return $(element);
};

Element.addMethods();






































if(typeof Effect == 'undefined')
throw("controls.js requires including script.aculo.us' effects.js library");

var Autocompleter = {}
Autocompleter.Base = function() {};
Autocompleter.Base.prototype = {
baseInitialize: function(element, update, options) {
this.element     = $(element);
this.update      = $(update);
this.hasFocus    = false;
this.changed     = false;
this.active      = false;
this.index       = 0;
this.entryCount  = 0;

if(this.setOptions)
this.setOptions(options);
else
this.options = options || {};

this.options.paramName    = this.options.paramName || this.element.name;
this.options.tokens       = this.options.tokens || [];
this.options.frequency    = this.options.frequency || 0.4;
this.options.minChars     = this.options.minChars || 1;
this.options.onShow       = this.options.onShow ||
function(element, update){
if(!update.style.position || update.style.position=='absolute') {
update.style.position = 'absolute';
Position.clone(element, update, {
setHeight: false,
offsetTop: element.offsetHeight
});
}
Effect.Appear(update,{duration:0.15});
};
this.options.onHide = this.options.onHide ||
function(element, update){ new Effect.Fade(update,{duration:0.15}) };

if(typeof(this.options.tokens) == 'string')
this.options.tokens = new Array(this.options.tokens);

this.observer = null;

this.element.setAttribute('autocomplete','off');

Element.hide(this.update);

Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this));
},

show: function() {
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
if(!this.iefix &&
(navigator.appVersion.indexOf('MSIE')>0) &&
(navigator.userAgent.indexOf('Opera')<0) &&
(Element.getStyle(this.update, 'position')=='absolute')) {
new Insertion.After(this.update,
'<iframe id="' + this.update.id + '_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
this.iefix = $(this.update.id+'_iefix');
}
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
},

fixIEOverlapping: function() {
Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
this.iefix.style.zIndex = 1;
this.update.style.zIndex = 2;
Element.show(this.iefix);
},

hide: function() {
this.stopIndicator();
if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
if(this.iefix) Element.hide(this.iefix);
},

startIndicator: function() {
if(this.options.indicator) Element.show(this.options.indicator);
},

stopIndicator: function() {
if(this.options.indicator) Element.hide(this.options.indicator);
},

onKeyPress: function(event) {
if(this.active)
switch(event.keyCode) {
case Event.KEY_TAB:
case Event.KEY_RETURN:
this.selectEntry();
Event.stop(event);
case Event.KEY_ESC:
this.hide();
this.active = false;
Event.stop(event);
return;
case Event.KEY_LEFT:
case Event.KEY_RIGHT:
return;
case Event.KEY_UP:
this.markPrevious();
this.render();
if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
return;
case Event.KEY_DOWN:
this.markNext();
this.render();
if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
return;
}
else
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
(navigator.appVersion.indexOf('AppleWebKit') > 0 && event.keyCode == 0)) return;

this.changed = true;
this.hasFocus = true;

if(this.observer) clearTimeout(this.observer);
this.observer =
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
},

activate: function() {
this.changed = false;
this.hasFocus = true;
this.getUpdatedChoices();
},

onHover: function(event) {
var element = Event.findElement(event, 'LI');
if(this.index != element.autocompleteIndex)
{
this.index = element.autocompleteIndex;
this.render();
}
Event.stop(event);
},

onClick: function(event) {
var element = Event.findElement(event, 'LI');
this.index = element.autocompleteIndex;
this.selectEntry();
this.hide();
},

onBlur: function(event) {

setTimeout(this.hide.bind(this), 250);
this.hasFocus = false;
this.active = false;
},

render: function() {
if(this.entryCount > 0) {
for (var i = 0; i < this.entryCount; i++)
this.index==i ?
Element.addClassName(this.getEntry(i),"selected") :
Element.removeClassName(this.getEntry(i),"selected");

if(this.hasFocus) {
this.show();
this.active = true;
}
} else {
this.active = false;
this.hide();
}
},

markPrevious: function() {
if(this.index > 0) this.index--
else this.index = this.entryCount-1;
this.getEntry(this.index).scrollIntoView(true);
},

markNext: function() {
if(this.index < this.entryCount-1) this.index++
else this.index = 0;
this.getEntry(this.index).scrollIntoView(false);
},

getEntry: function(index) {
return this.update.firstChild.childNodes[index];
},

getCurrentEntry: function() {
return this.getEntry(this.index);
},

selectEntry: function() {
this.active = false;
this.updateElement(this.getCurrentEntry());
},

updateElement: function(selectedElement) {
if (this.options.updateElement) {
this.options.updateElement(selectedElement);
return;
}
var value = '';
if (this.options.select) {
var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
} else
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');

var lastTokenPos = this.findLastToken();
if (lastTokenPos != -1) {
var newValue = this.element.value.substr(0, lastTokenPos + 1);
var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
if (whitespace)
newValue += whitespace[0];
this.element.value = newValue + value;
} else {
this.element.value = value;
}
this.element.focus();

if (this.options.afterUpdateElement)
this.options.afterUpdateElement(this.element, selectedElement);
},

updateChoices: function(choices) {
if(!this.changed && this.hasFocus) {
this.update.innerHTML = choices;
Element.cleanWhitespace(this.update);
Element.cleanWhitespace(this.update.down());

if(this.update.firstChild && this.update.down().childNodes) {
this.entryCount =
this.update.down().childNodes.length;
for (var i = 0; i < this.entryCount; i++) {
var entry = this.getEntry(i);
entry.autocompleteIndex = i;
this.addObservers(entry);
}
} else {
this.entryCount = 0;
}

this.stopIndicator();
this.index = 0;

if(this.entryCount==1 && this.options.autoSelect) {
this.selectEntry();
this.hide();
} else {
this.render();
}
}
},

addObservers: function(element) {
Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
Event.observe(element, "click", this.onClick.bindAsEventListener(this));
},

onObserverEvent: function() {
this.changed = false;
if(this.getToken().length>=this.options.minChars) {
this.startIndicator();
this.getUpdatedChoices();
} else {
this.active = false;
this.hide();
}
},

getToken: function() {
var tokenPos = this.findLastToken();
if (tokenPos != -1)
var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,'');
else
var ret = this.element.value;

return /\n/.test(ret) ? '' : ret;
},

findLastToken: function() {
var lastTokenPos = -1;

for (var i=0; i<this.options.tokens.length; i++) {
var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
if (thisTokenPos > lastTokenPos)
lastTokenPos = thisTokenPos;
}
return lastTokenPos;
}
}

Ajax.Autocompleter = Class.create();
Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
initialize: function(element, update, url, options) {
this.baseInitialize(element, update, options);
this.options.asynchronous  = true;
this.options.onComplete    = this.onComplete.bind(this);
this.options.defaultParams = this.options.parameters || null;
this.url                   = url;
},

getUpdatedChoices: function() {
entry = encodeURIComponent(this.options.paramName) + '=' +
encodeURIComponent(this.getToken());

this.options.parameters = this.options.callback ?
this.options.callback(this.element, entry) : entry;

if(this.options.defaultParams)
this.options.parameters += '&' + this.options.defaultParams;

new Ajax.Request(this.url, this.options);
},

onComplete: function(request) {
this.updateChoices(request.responseText);
}

});




































Autocompleter.Local = Class.create();
Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
initialize: function(element, update, array, options) {
this.baseInitialize(element, update, options);
this.options.array = array;
},

getUpdatedChoices: function() {
this.updateChoices(this.options.selector(this));
},

setOptions: function(options) {
this.options = Object.extend({
choices: 10,
partialSearch: true,
partialChars: 2,
ignoreCase: true,
fullSearch: false,
selector: function(instance) {
var ret       = []; // Beginning matches
var partial   = []; // Inside matches
var entry     = instance.getToken();
var count     = 0;

for (var i = 0; i < instance.options.array.length &&
ret.length < instance.options.choices ; i++) {

var elem = instance.options.array[i];
var foundPos = instance.options.ignoreCase ?
elem.toLowerCase().indexOf(entry.toLowerCase()) :
elem.indexOf(entry);

while (foundPos != -1) {
if (foundPos == 0 && elem.length != entry.length) {
ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
elem.substr(entry.length) + "</li>");
break;
} else if (entry.length >= instance.options.partialChars &&
instance.options.partialSearch && foundPos != -1) {
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
foundPos + entry.length) + "</li>");
break;
}
}

foundPos = instance.options.ignoreCase ?
elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
elem.indexOf(entry, foundPos + 1);

}
}
if (partial.length)
ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
return "<ul>" + ret.join('') + "</ul>";
}
}, options || {});
}
});








Field.scrollFreeActivate = function(field) {
setTimeout(function() {
Field.activate(field);
}, 1);
}

Ajax.InPlaceEditor = Class.create();
Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
Ajax.InPlaceEditor.prototype = {
initialize: function(element, url, options) {
this.url = url;
this.element = $(element);

this.options = Object.extend({
paramName: "value",
okButton: true,
okText: "ok",
cancelLink: true,
cancelText: "cancel",
savingText: "Saving...",
clickToEditText: "Click to edit",
okText: "ok",
rows: 1,
onComplete: function(transport, element) {
new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
},
onFailure: function(transport) {
alert("Error communicating with the server: " + transport.responseText.stripTags());
},
callback: function(form) {
return Form.serialize(form);
},
handleLineBreaks: true,
loadingText: 'Loading...',
savingClassName: 'inplaceeditor-saving',
loadingClassName: 'inplaceeditor-loading',
formClassName: 'inplaceeditor-form',
highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
highlightendcolor: "#FFFFFF",
externalControl: null,
submitOnBlur: false,
ajaxOptions: {},
evalScripts: false
}, options || {});

if(!this.options.formId && this.element.id) {
this.options.formId = this.element.id + "-inplaceeditor";
if ($(this.options.formId)) {

this.options.formId = null;
}
}

if (this.options.externalControl) {
this.options.externalControl = $(this.options.externalControl);
}

this.originalBackground = Element.getStyle(this.element, 'background-color');
if (!this.originalBackground) {
this.originalBackground = "transparent";
}

this.element.title = this.options.clickToEditText;

this.onclickListener = this.enterEditMode.bindAsEventListener(this);
this.mouseoverListener = this.enterHover.bindAsEventListener(this);
this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
Event.observe(this.element, 'click', this.onclickListener);
Event.observe(this.element, 'mouseover', this.mouseoverListener);
Event.observe(this.element, 'mouseout', this.mouseoutListener);
if (this.options.externalControl) {
Event.observe(this.options.externalControl, 'click', this.onclickListener);
Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
}
},
enterEditMode: function(evt) {
if (this.saving) return;
if (this.editing) return;
this.editing = true;
this.onEnterEditMode();
if (this.options.externalControl) {
Element.hide(this.options.externalControl);
}
Element.hide(this.element);
this.createForm();
this.element.parentNode.insertBefore(this.form, this.element);
if (!this.options.loadTextURL) Field.scrollFreeActivate(this.editField);

if (evt) {
Event.stop(evt);
}
return false;
},
createForm: function() {
this.form = document.createElement("form");
this.form.id = this.options.formId;
Element.addClassName(this.form, this.options.formClassName)
this.form.onsubmit = this.onSubmit.bind(this);

this.createEditField();

if (this.options.textarea) {
var br = document.createElement("br");
this.form.appendChild(br);
}

if (this.options.okButton) {
okButton = document.createElement("input");
okButton.type = "submit";
okButton.value = this.options.okText;
okButton.className = 'editor_ok_button';
this.form.appendChild(okButton);
}

if (this.options.cancelLink) {
cancelLink = document.createElement("a");
cancelLink.href = "#";
cancelLink.appendChild(document.createTextNode(this.options.cancelText));
cancelLink.onclick = this.onclickCancel.bind(this);
cancelLink.className = 'editor_cancel';
this.form.appendChild(cancelLink);
}
},
hasHTMLLineBreaks: function(string) {
if (!this.options.handleLineBreaks) return false;
return string.match(/<br/i) || string.match(/<p>/i);
},
convertHTMLLineBreaks: function(string) {
return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
},
createEditField: function() {
var text;
if(this.options.loadTextURL) {
text = this.options.loadingText;
} else {
text = this.getText();
}

var obj = this;

if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
this.options.textarea = false;
var textField = document.createElement("input");
textField.obj = this;
textField.type = "text";
textField.name = this.options.paramName;
textField.value = text;
textField.style.backgroundColor = this.options.highlightcolor;
textField.className = 'editor_field';
var size = this.options.size || this.options.cols || 0;
if (size != 0) textField.size = size;
if (this.options.submitOnBlur)
textField.onblur = this.onSubmit.bind(this);
this.editField = textField;
} else {
this.options.textarea = true;
var textArea = document.createElement("textarea");
textArea.obj = this;
textArea.name = this.options.paramName;
textArea.value = this.convertHTMLLineBreaks(text);
textArea.rows = this.options.rows;
textArea.cols = this.options.cols || 40;
textArea.className = 'editor_field';
if (this.options.submitOnBlur)
textArea.onblur = this.onSubmit.bind(this);
this.editField = textArea;
}

if(this.options.loadTextURL) {
this.loadExternalText();
}
this.form.appendChild(this.editField);
},
getText: function() {
return this.element.innerHTML;
},
loadExternalText: function() {
Element.addClassName(this.form, this.options.loadingClassName);
this.editField.disabled = true;
new Ajax.Request(
this.options.loadTextURL,
Object.extend({
asynchronous: true,
onComplete: this.onLoadedExternalText.bind(this)
}, this.options.ajaxOptions)
);
},
onLoadedExternalText: function(transport) {
Element.removeClassName(this.form, this.options.loadingClassName);
this.editField.disabled = false;
this.editField.value = transport.responseText.stripTags();
Field.scrollFreeActivate(this.editField);
},
onclickCancel: function() {
this.onComplete();
this.leaveEditMode();
return false;
},
onFailure: function(transport) {
this.options.onFailure(transport);
if (this.oldInnerHTML) {
this.element.innerHTML = this.oldInnerHTML;
this.oldInnerHTML = null;
}
return false;
},
onSubmit: function() {

var form = this.form;
var value = this.editField.value;




this.onLoading();

if (this.options.evalScripts) {
new Ajax.Request(
this.url, Object.extend({
parameters: this.options.callback(form, value),
onComplete: this.onComplete.bind(this),
onFailure: this.onFailure.bind(this),
asynchronous:true,
evalScripts:true
}, this.options.ajaxOptions));
} else  {
new Ajax.Updater(
{ success: this.element,

failure: null },
this.url, Object.extend({
parameters: this.options.callback(form, value),
onComplete: this.onComplete.bind(this),
onFailure: this.onFailure.bind(this)
}, this.options.ajaxOptions));
}

if (arguments.length > 1) {
Event.stop(arguments[0]);
}
return false;
},
onLoading: function() {
this.saving = true;
this.removeForm();
this.leaveHover();
this.showSaving();
},
showSaving: function() {
this.oldInnerHTML = this.element.innerHTML;
this.element.innerHTML = this.options.savingText;
Element.addClassName(this.element, this.options.savingClassName);
this.element.style.backgroundColor = this.originalBackground;
Element.show(this.element);
},
removeForm: function() {
if(this.form) {
if (this.form.parentNode) Element.remove(this.form);
this.form = null;
}
},
enterHover: function() {
if (this.saving) return;
this.element.style.backgroundColor = this.options.highlightcolor;
if (this.effect) {
this.effect.cancel();
}
Element.addClassName(this.element, this.options.hoverClassName)
},
leaveHover: function() {
if (this.options.backgroundColor) {
this.element.style.backgroundColor = this.oldBackground;
}
Element.removeClassName(this.element, this.options.hoverClassName)
if (this.saving) return;
this.effect = new Effect.Highlight(this.element, {
startcolor: this.options.highlightcolor,
endcolor: this.options.highlightendcolor,
restorecolor: this.originalBackground
});
},
leaveEditMode: function() {
Element.removeClassName(this.element, this.options.savingClassName);
this.removeForm();
this.leaveHover();
this.element.style.backgroundColor = this.originalBackground;
Element.show(this.element);
if (this.options.externalControl) {
Element.show(this.options.externalControl);
}
this.editing = false;
this.saving = false;
this.oldInnerHTML = null;
this.onLeaveEditMode();
},
onComplete: function(transport) {
this.leaveEditMode();
this.options.onComplete.bind(this)(transport, this.element);
},
onEnterEditMode: function() {},
onLeaveEditMode: function() {},
dispose: function() {
if (this.oldInnerHTML) {
this.element.innerHTML = this.oldInnerHTML;
}
this.leaveEditMode();
Event.stopObserving(this.element, 'click', this.onclickListener);
Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
if (this.options.externalControl) {
Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
}
}
};

Ajax.InPlaceCollectionEditor = Class.create();
Object.extend(Ajax.InPlaceCollectionEditor.prototype, Ajax.InPlaceEditor.prototype);
Object.extend(Ajax.InPlaceCollectionEditor.prototype, {
createEditField: function() {
if (!this.cached_selectTag) {
var selectTag = document.createElement("select");
var collection = this.options.collection || [];
var optionTag;
collection.each(function(e,i) {
optionTag = document.createElement("option");
optionTag.value = (e instanceof Array) ? e[0] : e;
if((typeof this.options.value == 'undefined') &&
((e instanceof Array) ? this.element.innerHTML == e[1] : e == optionTag.value)) optionTag.selected = true;
if(this.options.value==optionTag.value) optionTag.selected = true;
optionTag.appendChild(document.createTextNode((e instanceof Array) ? e[1] : e));
selectTag.appendChild(optionTag);
}.bind(this));
this.cached_selectTag = selectTag;
}

this.editField = this.cached_selectTag;
if(this.options.loadTextURL) this.loadExternalText();
this.form.appendChild(this.editField);
this.options.callback = function(form, value) {
return "value=" + encodeURIComponent(value);
}
}
});





Form.Element.DelayedObserver = Class.create();
Form.Element.DelayedObserver.prototype = {
initialize: function(element, delay, callback) {
this.delay     = delay || 0.5;
this.element   = $(element);
this.callback  = callback;
this.timer     = null;
this.lastValue = $F(this.element);
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
},
delayedListener: function(event) {
if(this.lastValue == $F(this.element)) return;
if(this.timer) clearTimeout(this.timer);
this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
this.lastValue = $F(this.element);
},
onTimerEvent: function() {
this.timer = null;
this.callback(this.element, $F(this.element));
}
};











































var domLib_userAgent = navigator.userAgent.toLowerCase();
var domLib_isMac = navigator.appVersion.indexOf('Mac') != -1;
var domLib_isWin = domLib_userAgent.indexOf('windows') != -1;

var domLib_isOpera = domLib_userAgent.indexOf('opera') != -1;
var domLib_isOpera7up = domLib_userAgent.match(/opera.(7|8)/i);
var domLib_isSafari = domLib_userAgent.indexOf('safari') != -1;
var domLib_isKonq = domLib_userAgent.indexOf('konqueror') != -1;

var domLib_isKHTML = (domLib_isKonq || domLib_isSafari || domLib_userAgent.indexOf('khtml') != -1);
var domLib_isIE = (!domLib_isKHTML && !domLib_isOpera && (domLib_userAgent.indexOf('msie 5') != -1 || domLib_userAgent.indexOf('msie 6') != -1 || domLib_userAgent.indexOf('msie 7') != -1));
var domLib_isIE5up = domLib_isIE;
var domLib_isIE50 = (domLib_isIE && domLib_userAgent.indexOf('msie 5.0') != -1);
var domLib_isIE55 = (domLib_isIE && domLib_userAgent.indexOf('msie 5.5') != -1);
var domLib_isIE5 = (domLib_isIE50 || domLib_isIE55);

var domLib_isGecko = domLib_userAgent.indexOf('gecko/') != -1;
var domLib_isMacIE = (domLib_isIE && domLib_isMac);
var domLib_isIE55up = domLib_isIE5up && !domLib_isIE50 && !domLib_isMacIE;
var domLib_isIE6up = domLib_isIE55up && !domLib_isIE55;


var domLib_standardsMode = (document.compatMode && document.compatMode == 'CSS1Compat');
var domLib_useLibrary = (domLib_isOpera7up || domLib_isKHTML || domLib_isIE5up || domLib_isGecko || domLib_isMacIE || document.defaultView);

var domLib_hasBrokenTimeout = (domLib_isMacIE || (domLib_isKonq && domLib_userAgent.match(/konqueror\/3.([2-9])/) == null));
var domLib_canFade = (domLib_isGecko || domLib_isIE || domLib_isSafari || domLib_isOpera);
var domLib_canDrawOverSelect = (domLib_isMac || domLib_isOpera || domLib_isGecko);
var domLib_canDrawOverFlash = (domLib_isMac || domLib_isWin);


var domLib_eventTarget = domLib_isIE ? 'srcElement' : 'currentTarget';
var domLib_eventButton = domLib_isIE ? 'button' : 'which';
var domLib_eventTo = domLib_isIE ? 'toElement' : 'relatedTarget';
var domLib_stylePointer = domLib_isIE ? 'hand' : 'pointer';

var domLib_styleNoMaxWidth = domLib_isOpera ? '10000px' : 'none';
var domLib_hidePosition = '-1000px';
var domLib_scrollbarWidth = 14;
var domLib_autoId = 1;
var domLib_zIndex = 100;


var domLib_collisionElements;
var domLib_collisionsCached = false;

var domLib_timeoutStateId = 0;
var domLib_timeoutStates = new DomLibHash();




if (!document.ELEMENT_NODE)
{
document.ELEMENT_NODE = 1;
document.ATTRIBUTE_NODE = 2;
document.TEXT_NODE = 3;
document.DOCUMENT_NODE = 9;
document.DOCUMENT_FRAGMENT_NODE = 11;
}

function domLib_clone(obj)
{
var copy = {};
for (var i in obj)
{
var value = obj[i];
try
{
if (value != null && typeof(value) == 'object' && value != window && !value.nodeType)
{
copy[i] = domLib_clone(value);
}
else
{
copy[i] = value;
}
}
catch(e)
{
copy[i] = value;
}
}

return copy;
}




function DomLibHash()
{
this.length = 0;
this.numericLength = 0;
this.elementData = [];
for (var i = 0; i < arguments.length; i += 2)
{
if (typeof(arguments[i + 1]) != 'undefined')
{
this.elementData[arguments[i]] = arguments[i + 1];
this.length++;
if (arguments[i] == parseInt(arguments[i]))
{
this.numericLength++;
}
}
}
}


DomLibHash.prototype.get = function(in_key)
{
if (typeof(this.elementData[in_key]) != 'undefined') {
return this.elementData[in_key];
}

return null;
}

DomLibHash.prototype.set = function(in_key, in_value)
{
if (typeof(in_value) != 'undefined')
{
if (typeof(this.elementData[in_key]) == 'undefined')
{
this.length++;
if (in_key == parseInt(in_key))
{
this.numericLength++;
}
}

return this.elementData[in_key] = in_value;
}

return false;
}

DomLibHash.prototype.remove = function(in_key)
{
var tmp_value;
if (typeof(this.elementData[in_key]) != 'undefined')
{
this.length--;
if (in_key == parseInt(in_key))
{
this.numericLength--;
}

tmp_value = this.elementData[in_key];
delete this.elementData[in_key];
}

return tmp_value;
}

DomLibHash.prototype.size = function()
{
return this.length;
}

DomLibHash.prototype.has = function(in_key)
{
return typeof(this.elementData[in_key]) != 'undefined';
}

DomLibHash.prototype.find = function(in_obj)
{
for (var tmp_key in this.elementData)
{
if (this.elementData[tmp_key] == in_obj)
{
return tmp_key;
}
}

return null;
}

DomLibHash.prototype.merge = function(in_hash)
{
for (var tmp_key in in_hash.elementData)
{
if (typeof(this.elementData[tmp_key]) == 'undefined')
{
this.length++;
if (tmp_key == parseInt(tmp_key))
{
this.numericLength++;
}
}

this.elementData[tmp_key] = in_hash.elementData[tmp_key];
}
}

DomLibHash.prototype.compare = function(in_hash)
{
if (this.length != in_hash.length)
{
return false;
}

for (var tmp_key in this.elementData)
{
if (this.elementData[tmp_key] != in_hash.elementData[tmp_key])
{
return false;
}
}

return true;
}




function domLib_isDescendantOf(in_object, in_ancestor, in_bannedTags)
{
if (in_object == null)
{
return false;
}

if (in_object == in_ancestor)
{
return true;
}

if (typeof(in_bannedTags) != 'undefined' &&
(',' + in_bannedTags.join(',') + ',').indexOf(',' + in_object.tagName + ',') != -1)
{
return false;
}

while (in_object != document.documentElement)
{
try
{
if ((tmp_object = in_object.offsetParent) && tmp_object == in_ancestor)
{
return true;
}
else if ((tmp_object = in_object.parentNode) == in_ancestor)
{
return true;
}
else
{
in_object = tmp_object;
}
}

catch(e)
{
return false;
}
}

return false;
}








function domLib_detectCollisions(in_object, in_recover, in_useCache)
{




if (!domLib_collisionsCached)
{
var tags = [];

if (!domLib_canDrawOverFlash)
{
tags[tags.length] = 'object';
}

if (!domLib_canDrawOverSelect)
{
tags[tags.length] = 'select';
}

domLib_collisionElements = domLib_getElementsByTagNames(tags, true);
domLib_collisionsCached = in_useCache;
}


if (in_recover)
{
for (var cnt = 0; cnt < domLib_collisionElements.length; cnt++)
{
var thisElement = domLib_collisionElements[cnt];

if (!thisElement.hideList)
{
thisElement.hideList = new DomLibHash();
}

thisElement.hideList.remove(in_object.id);
if (!thisElement.hideList.length)
{
domLib_collisionElements[cnt].style.visibility = 'visible';
if (domLib_isKonq)
{
domLib_collisionElements[cnt].style.display = '';
}
}
}

return;
}
else if (domLib_collisionElements.length == 0)
{
return;
}


var objectOffsets = domLib_getOffsets(in_object);

for (var cnt = 0; cnt < domLib_collisionElements.length; cnt++)
{
var thisElement = domLib_collisionElements[cnt];



if (domLib_isDescendantOf(thisElement, in_object))
{
continue;
}


if (domLib_isKonq &&
thisElement.tagName == 'SELECT' &&
(thisElement.size <= 1 && !thisElement.multiple))
{
continue;
}

if (!thisElement.hideList)
{
thisElement.hideList = new DomLibHash();
}

var selectOffsets = domLib_getOffsets(thisElement);
var center2centerDistance = Math.sqrt(Math.pow(selectOffsets.get('leftCenter') - objectOffsets.get('leftCenter'), 2) + Math.pow(selectOffsets.get('topCenter') - objectOffsets.get('topCenter'), 2));
var radiusSum = selectOffsets.get('radius') + objectOffsets.get('radius');

if (center2centerDistance < radiusSum)
{

if ((objectOffsets.get('leftCenter') <= selectOffsets.get('leftCenter') && objectOffsets.get('right') < selectOffsets.get('left')) ||

(objectOffsets.get('leftCenter') > selectOffsets.get('leftCenter') && objectOffsets.get('left') > selectOffsets.get('right')) ||

(objectOffsets.get('topCenter') <= selectOffsets.get('topCenter') && objectOffsets.get('bottom') < selectOffsets.get('top')) ||

(objectOffsets.get('topCenter') > selectOffsets.get('topCenter') && objectOffsets.get('top') > selectOffsets.get('bottom')))
{
thisElement.hideList.remove(in_object.id);
if (!thisElement.hideList.length)
{
thisElement.style.visibility = 'visible';
if (domLib_isKonq)
{
thisElement.style.display = '';
}
}
}
else
{
thisElement.hideList.set(in_object.id, true);
thisElement.style.visibility = 'hidden';
if (domLib_isKonq)
{
thisElement.style.display = 'none';
}
}
}
}
}




function domLib_getOffsets(in_object, in_preserveScroll)
{
if (typeof(in_preserveScroll) == 'undefined') {
in_preserveScroll = false;
}

var originalObject = in_object;
var originalWidth = in_object.offsetWidth;
var originalHeight = in_object.offsetHeight;
var offsetLeft = 0;
var offsetTop = 0;

while (in_object)
{
offsetLeft += in_object.offsetLeft;
offsetTop += in_object.offsetTop;
in_object = in_object.offsetParent;

if (in_object && !in_preserveScroll)
{
offsetLeft -= in_object.scrollLeft;
offsetTop -= in_object.scrollTop;
}
}


if (domLib_isMacIE) {
offsetLeft += 10;
offsetTop += 10;
}

return new DomLibHash(
'left',		offsetLeft,
'top',		offsetTop,
'right',	offsetLeft + originalWidth,
'bottom',	offsetTop + originalHeight,
'leftCenter',	offsetLeft + originalWidth/2,
'topCenter',	offsetTop + originalHeight/2,
'radius',	Math.max(originalWidth, originalHeight)
);
}




function domLib_setTimeout(in_function, in_timeout, in_args)
{
if (typeof(in_args) == 'undefined')
{
in_args = [];
}

if (in_timeout == -1)
{

return 0;
}
else if (in_timeout == 0)
{
in_function(in_args);
return 0;
}


var args = domLib_clone(in_args);

if (!domLib_hasBrokenTimeout)
{
return setTimeout(function() { in_function(args); }, in_timeout);
}
else
{
var id = domLib_timeoutStateId++;
var data = new DomLibHash();
data.set('function', in_function);
data.set('args', args);
domLib_timeoutStates.set(id, data);

data.set('timeoutId', setTimeout('domLib_timeoutStates.get(' + id + ').get(\'function\')(domLib_timeoutStates.get(' + id + ').get(\'args\')); domLib_timeoutStates.remove(' + id + ');', in_timeout));
return id;
}
}




function domLib_clearTimeout(in_id)
{
if (!domLib_hasBrokenTimeout)
{
if (in_id > 0) {
clearTimeout(in_id);
}
}
else
{
if (domLib_timeoutStates.has(in_id))
{
clearTimeout(domLib_timeoutStates.get(in_id).get('timeoutId'))
domLib_timeoutStates.remove(in_id);
}
}
}




function domLib_getEventPosition(in_eventObj)
{
var eventPosition = new DomLibHash('x', 0, 'y', 0, 'scrollX', 0, 'scrollY', 0);


if (domLib_isIE)
{
var doc = (domLib_standardsMode ? document.documentElement : document.body);

if (doc)
{
eventPosition.set('x', in_eventObj.clientX + doc.scrollLeft);
eventPosition.set('y', in_eventObj.clientY + doc.scrollTop);
eventPosition.set('scrollX', doc.scrollLeft);
eventPosition.set('scrollY', doc.scrollTop);
}
}
else
{
eventPosition.set('x', in_eventObj.pageX);
eventPosition.set('y', in_eventObj.pageY);
eventPosition.set('scrollX', in_eventObj.pageX - in_eventObj.clientX);
eventPosition.set('scrollY', in_eventObj.pageY - in_eventObj.clientY);
}

return eventPosition;
}




function domLib_cancelBubble(in_event)
{
var eventObj = in_event ? in_event : window.event;
eventObj.cancelBubble = true;
}




function domLib_getIFrameReference(in_frame)
{
if (domLib_isGecko || domLib_isIE)
{
return in_frame.frameElement;
}
else
{


var name = in_frame.name;
if (!name || !in_frame.parent)
{
return null;
}

var candidates = in_frame.parent.document.getElementsByTagName('iframe');
for (var i = 0; i < candidates.length; i++)
{
if (candidates[i].name == name)
{
return candidates[i];
}
}

return null;
}
}




function domLib_getElementsByClass(in_class)
{
var elements = domLib_isIE5 ? document.all : document.getElementsByTagName('*');
var matches = [];
var cnt = 0;
for (var i = 0; i < elements.length; i++)
{
if ((" " + elements[i].className + " ").indexOf(" " + in_class + " ") != -1)
{
matches[cnt++] = elements[i];
}
}

return matches;
}




function domLib_getElementsByTagNames(in_list, in_excludeHidden)
{
var elements = [];
for (var i = 0; i < in_list.length; i++)
{
var matches = document.getElementsByTagName(in_list[i]);
for (var j = 0; j < matches.length; j++)
{

if (matches[j].tagName == 'OBJECT' && domLib_isGecko)
{
var kids = matches[j].childNodes;
var skip = false;
for (var k = 0; k < kids.length; k++)
{
if (kids[k].tagName == 'EMBED')
{
skip = true;
break;
}
}
if (skip) continue;
}

if (in_excludeHidden && domLib_getComputedStyle(matches[j], 'visibility') == 'hidden')
{
continue;
}

elements[elements.length] = matches[j];
}
}

return elements;
}




function domLib_getComputedStyle(in_obj, in_property)
{
if (domLib_isIE)
{
var humpBackProp = in_property.replace(/-(.)/, function (a, b) { return b.toUpperCase(); });
return eval('in_obj.currentStyle.' + humpBackProp);
}

else if (domLib_isKonq)
{

return eval('in_obj.style.' + in_property);
}
else
{
return document.defaultView.getComputedStyle(in_obj, null).getPropertyValue(in_property);
}
}




function makeTrue()
{
return true;
}




function makeFalse()
{
return false;
}





































































var domTT_offsetX = (domLib_isIE ? -2 : 0);
var domTT_offsetY = (domLib_isIE ? 4 : 2);
var domTT_direction = 'southeast';
var domTT_mouseHeight = domLib_isIE ? 13 : 19;
var domTT_closeLink = 'X';
var domTT_closeAction = 'hide';
var domTT_activateDelay = 500;
var domTT_maxWidth = false;
var domTT_styleClass = 'domTT';
var domTT_fade = 'neither';
var domTT_lifetime = 0;
var domTT_grid = 0;
var domTT_trailDelay = 200;
var domTT_useGlobalMousePosition = true;
var domTT_postponeActivation = false;
var domTT_tooltipIdPrefix = '[domTT]';
var domTT_screenEdgeDetection = true;
var domTT_screenEdgePadding = 4;
var domTT_oneOnly = false;
var domTT_cloneNodes = false;
var domTT_detectCollisions = true;
var domTT_bannedTags = ['OPTION'];
var domTT_draggable = false;
if (typeof(domTT_dragEnabled) == 'undefined')
{
domTT_dragEnabled = false;
}




var domTT_predefined = new DomLibHash();


var domTT_tooltips = new DomLibHash();
var domTT_lastOpened = 0;
var domTT_documentLoaded = false;
var domTT_mousePosition = null;




if (domLib_useLibrary && domTT_useGlobalMousePosition)
{
document.onmousemove = function(in_event)
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }

domTT_mousePosition = domLib_getEventPosition(in_event);
if (domTT_dragEnabled && domTT_dragMouseDown)
{
domTT_dragUpdate(in_event);
}
}
}




function domTT_activate(in_this, in_event)
{
if (!domLib_useLibrary || (domTT_postponeActivation && !domTT_documentLoaded)) { return false; }


if (typeof(in_event) == 'undefined') { in_event = window.event;	}


if (in_event != null) {
var target = in_event.srcElement ? in_event.srcElement : in_event.target;
if (target != null && (',' + domTT_bannedTags.join(',') + ',').indexOf(',' + target.tagName + ',') != -1)
{
return false;
}
}

var owner = document.body;

if (in_event != null && in_event.type.match(/key|mouse|click|contextmenu/i))
{

if (in_this.nodeType && in_this.nodeType != document.DOCUMENT_NODE)
{
owner = in_this;
}
}

else
{
if (typeof(in_this) != 'object' && !(owner = domTT_tooltips.get(in_this)))
{

var embryo = document.createElement('div');
owner = document.body.appendChild(embryo);
owner.style.display = 'none';
owner.id = in_this;
}
}


if (!owner.id)
{
owner.id = '__autoId' + domLib_autoId++;
}




if (domTT_oneOnly && domTT_lastOpened)
{
domTT_deactivate(domTT_lastOpened);
}

domTT_lastOpened = owner.id;

var tooltip = domTT_tooltips.get(owner.id);
if (tooltip)
{
if (tooltip.get('eventType') != in_event.type)
{
if (tooltip.get('type') == 'greasy')
{
tooltip.set('closeAction', 'destroy');
domTT_deactivate(owner.id);
}
else if (tooltip.get('status') != 'inactive')
{
return owner.id;
}
}
else
{
if (tooltip.get('status') == 'inactive')
{
tooltip.set('status', 'pending');
tooltip.set('activateTimeout', domLib_setTimeout(domTT_runShow, tooltip.get('delay'), [owner.id, in_event]));

return owner.id;
}

else
{
return owner.id;
}
}
}


var options = new DomLibHash(
'caption',		'',
'content',		'',
'clearMouse',	true,
'closeAction',	domTT_closeAction,
'closeLink',	domTT_closeLink,
'delay',		domTT_activateDelay,
'direction',	domTT_direction,
'draggable',	domTT_draggable,
'fade',			domTT_fade,
'fadeMax',		100,
'grid',			domTT_grid,
'id',			domTT_tooltipIdPrefix + owner.id,
'inframe',		false,
'lifetime',		domTT_lifetime,
'offsetX',		domTT_offsetX,
'offsetY',		domTT_offsetY,
'parent',		document.body,
'position',		'absolute',
'styleClass',	domTT_styleClass,
'type',			'greasy',
'trail',		false,
'lazy',			false
);


for (var i = 2; i < arguments.length; i += 2)
{

if (arguments[i] == 'predefined')
{
var predefinedOptions = domTT_predefined.get(arguments[i + 1]);
for (var j in predefinedOptions.elementData)
{
options.set(j, predefinedOptions.get(j));
}
}

else
{
options.set(arguments[i], arguments[i + 1]);
}
}

options.set('eventType', in_event != null ? in_event.type : null);


if (options.has('statusText'))
{
try { window.status = options.get('statusText'); } catch(e) {}
}


if (!options.has('content') || options.get('content') == '' || options.get('content') == null)
{
if (typeof(owner.onmouseout) != 'function')
{
owner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
}

return owner.id;
}

options.set('owner', owner);

domTT_create(options);


options.set('delay', (in_event != null && in_event.type.match(/click|mousedown|contextmenu/i)) ? 0 : parseInt(options.get('delay')));
domTT_tooltips.set(owner.id, options);
domTT_tooltips.set(options.get('id'), options);
options.set('status', 'pending');
options.set('activateTimeout', domLib_setTimeout(domTT_runShow, options.get('delay'), [owner.id, in_event]));

return owner.id;
}




function domTT_create(in_options)
{
var tipOwner = in_options.get('owner');
var parentObj = in_options.get('parent');
var parentDoc = parentObj.ownerDocument || parentObj.document;



var embryo = parentDoc.createElement('div');
var tipObj = parentObj.appendChild(embryo);
tipObj.style.position = 'absolute';
tipObj.style.left = '0px';
tipObj.style.top = '0px';
tipObj.style.visibility = 'hidden';
tipObj.id = in_options.get('id');
tipObj.className = in_options.get('styleClass');

var contentBlock;
var tableLayout = false;

if (in_options.get('caption') || (in_options.get('type') == 'sticky' && in_options.get('caption') !== false))
{
tableLayout = true;

var tipLayoutTable = tipObj.appendChild(parentDoc.createElement('table'));
tipLayoutTable.style.borderCollapse = 'collapse';
if (domLib_isKHTML)
{
tipLayoutTable.cellSpacing = 0;
}

var tipLayoutTbody = tipLayoutTable.appendChild(parentDoc.createElement('tbody'));

var numCaptionCells = 0;
var captionRow = tipLayoutTbody.appendChild(parentDoc.createElement('tr'));
var captionCell = captionRow.appendChild(parentDoc.createElement('td'));
captionCell.style.padding = '0px';
var caption = captionCell.appendChild(parentDoc.createElement('div'));
caption.className = 'caption';
if (domLib_isIE50)
{
caption.style.height = '100%';
}

if (in_options.get('caption').nodeType)
{
caption.appendChild(domTT_cloneNodes ? in_options.get('caption').cloneNode(1) : in_options.get('caption'));
}
else
{
caption.innerHTML = in_options.get('caption');
}

if (in_options.get('type') == 'sticky')
{
var numCaptionCells = 2;
var closeLinkCell = captionRow.appendChild(parentDoc.createElement('td'));
closeLinkCell.style.padding = '0px';
var closeLink = closeLinkCell.appendChild(parentDoc.createElement('div'));
closeLink.className = 'caption';
if (domLib_isIE50)
{
closeLink.style.height = '100%';
}

closeLink.style.textAlign = 'right';
closeLink.style.cursor = domLib_stylePointer;

closeLink.style.borderLeftWidth = caption.style.borderRightWidth = '0px';
closeLink.style.paddingLeft = caption.style.paddingRight = '0px';
closeLink.style.marginLeft = caption.style.marginRight = '0px';
if (in_options.get('closeLink').nodeType)
{
closeLink.appendChild(in_options.get('closeLink').cloneNode(1));
}
else
{
closeLink.innerHTML = in_options.get('closeLink');
}

closeLink.onclick = function()
{
domTT_deactivate(tipOwner.id);
};
closeLink.onmousedown = function(in_event)
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }
in_event.cancelBubble = true;
};

if (domLib_isMacIE)
{
closeLinkCell.appendChild(parentDoc.createTextNode("\n"));
}
}


if (domLib_isMacIE)
{
captionCell.appendChild(parentDoc.createTextNode("\n"));
}

var contentRow = tipLayoutTbody.appendChild(parentDoc.createElement('tr'));
var contentCell = contentRow.appendChild(parentDoc.createElement('td'));
contentCell.style.padding = '0px';
if (numCaptionCells)
{
if (domLib_isIE || domLib_isOpera)
{
contentCell.colSpan = numCaptionCells;
}
else
{
contentCell.setAttribute('colspan', numCaptionCells);
}
}

contentBlock = contentCell.appendChild(parentDoc.createElement('div'));
if (domLib_isIE50)
{
contentBlock.style.height = '100%';
}
}
else
{
contentBlock = tipObj.appendChild(parentDoc.createElement('div'));
}

contentBlock.className = 'contents';

var content = in_options.get('content');

if (typeof(content) == 'function') {
content = content(in_options.get('id'));
}

if (content != null && content.nodeType)
{
contentBlock.appendChild(domTT_cloneNodes ? content.cloneNode(1) : content);
}
else
{
contentBlock.innerHTML = content;
}


if (in_options.has('width'))
{
tipObj.style.width = parseInt(in_options.get('width')) + 'px';
}



var maxWidth = domTT_maxWidth;
if (in_options.has('maxWidth'))
{
if ((maxWidth = in_options.get('maxWidth')) === false)
{
tipObj.style.maxWidth = domLib_styleNoMaxWidth;
}
else
{
maxWidth = parseInt(in_options.get('maxWidth'));
tipObj.style.maxWidth = maxWidth + 'px';
}
}


if (maxWidth !== false && (domLib_isIE || domLib_isKHTML) && tipObj.offsetWidth > maxWidth)
{
tipObj.style.width = maxWidth + 'px';
}

in_options.set('offsetWidth', tipObj.offsetWidth);
in_options.set('offsetHeight', tipObj.offsetHeight);



if (domLib_isKonq && tableLayout && !tipObj.style.width)
{
var left = document.defaultView.getComputedStyle(tipObj, '').getPropertyValue('border-left-width');
var right = document.defaultView.getComputedStyle(tipObj, '').getPropertyValue('border-right-width');

left = left.substring(left.indexOf(':') + 2, left.indexOf(';'));
right = right.substring(right.indexOf(':') + 2, right.indexOf(';'));
var correction = 2 * ((left ? parseInt(left) : 0) + (right ? parseInt(right) : 0));
tipObj.style.width = (tipObj.offsetWidth - correction) + 'px';
}



if (domLib_isIE || domLib_isOpera)
{
if (!tipObj.style.width)
{

tipObj.style.width = (tipObj.offsetWidth - 2) + 'px';
}


tipObj.style.height = (tipObj.offsetHeight - 2) + 'px';
}


var offsetX, offsetY;


if (in_options.get('position') == 'absolute' && !(in_options.has('x') && in_options.has('y')))
{

switch (in_options.get('direction'))
{
case 'northeast':
offsetX = in_options.get('offsetX');
offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
break;
case 'northwest':
offsetX = 0 - tipObj.offsetWidth - in_options.get('offsetX');
offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
break;
case 'north':
offsetX = 0 - parseInt(tipObj.offsetWidth/2);
offsetY = 0 - tipObj.offsetHeight - in_options.get('offsetY');
break;
case 'southwest':
offsetX = 0 - tipObj.offsetWidth - in_options.get('offsetX');
offsetY = in_options.get('offsetY');
break;
case 'southeast':
offsetX = in_options.get('offsetX');
offsetY = in_options.get('offsetY');
break;
case 'south':
offsetX = 0 - parseInt(tipObj.offsetWidth/2);
offsetY = in_options.get('offsetY');
break;
}


if (in_options.get('inframe'))
{
var iframeObj = domLib_getIFrameReference(window);
if (iframeObj)
{
var frameOffsets = domLib_getOffsets(iframeObj);
offsetX += frameOffsets.get('left');
offsetY += frameOffsets.get('top');
}
}
}

else
{
offsetX = 0;
offsetY = 0;
in_options.set('trail', false);
}


in_options.set('offsetX', offsetX);
in_options.set('offsetY', offsetY);
if (in_options.get('clearMouse') && in_options.get('direction').indexOf('south') != -1)
{
in_options.set('mouseOffset', domTT_mouseHeight);
}
else
{
in_options.set('mouseOffset', 0);
}

if (domLib_canFade && typeof(Fadomatic) == 'function')
{
if (in_options.get('fade') != 'neither')
{
var fadeHandler = new Fadomatic(tipObj, 10, 0, 0, in_options.get('fadeMax'));
in_options.set('fadeHandler', fadeHandler);
}
}
else
{
in_options.set('fade', 'neither');
}


if (in_options.get('trail') && typeof(tipOwner.onmousemove) != 'function')
{
tipOwner.onmousemove = function(in_event) { domTT_mousemove(this, in_event); };
}

if (typeof(tipOwner.onmouseout) != 'function')
{
tipOwner.onmouseout = function(in_event) { domTT_mouseout(this, in_event); };
}

if (in_options.get('type') == 'sticky')
{
if (in_options.get('position') == 'absolute' && domTT_dragEnabled && in_options.get('draggable'))
{
if (domLib_isIE)
{
captionRow.onselectstart = function() { return false; };
}


captionRow.onmousedown = function(in_event) { domTT_dragStart(tipObj, in_event);  };
captionRow.onmousemove = function(in_event) { domTT_dragUpdate(in_event); };
captionRow.onmouseup = function() { domTT_dragStop(); };
}
}
else if (in_options.get('type') == 'velcro')
{










tipObj.onmouseout = function(in_event)
{
if (typeof(in_event) == 'undefined') { in_event = window.event; }
if (!domLib_isDescendantOf(in_event[domLib_eventTo], tipObj, domTT_bannedTags)) {
domTT_deactivate(tipOwner.id);
}
};

tipObj.onclick = function(in_event)
{
domTT_deactivate(tipOwner.id);
};
}

if (in_options.get('position') == 'relative')
{
tipObj.style.position = 'relative';
}

in_options.set('node', tipObj);
in_options.set('status', 'inactive');
}





function domTT_show(in_id, in_event)
{


var tooltip = domTT_tooltips.get(in_id);
var status = tooltip.get('status');
var tipObj = tooltip.get('node');

if (tooltip.get('position') == 'absolute')
{
var mouseX, mouseY;

if (tooltip.has('x') && tooltip.has('y'))
{
mouseX = tooltip.get('x');
mouseY = tooltip.get('y');
}
else if (!domTT_useGlobalMousePosition || domTT_mousePosition == null || status == 'active' || tooltip.get('delay') == 0)
{
var eventPosition = domLib_getEventPosition(in_event);
var eventX = eventPosition.get('x');
var eventY = eventPosition.get('y');
if (tooltip.get('inframe'))
{
eventX -= eventPosition.get('scrollX');
eventY -= eventPosition.get('scrollY');
}


if (status == 'active' && tooltip.get('trail') !== true)
{
var trail = tooltip.get('trail');
if (trail == 'x')
{
mouseX = eventX;
mouseY = tooltip.get('mouseY');
}
else if (trail == 'y')
{
mouseX = tooltip.get('mouseX');
mouseY = eventY;
}
}
else
{
mouseX = eventX;
mouseY = eventY;
}
}
else
{
mouseX = domTT_mousePosition.get('x');
mouseY = domTT_mousePosition.get('y');
if (tooltip.get('inframe'))
{
mouseX -= domTT_mousePosition.get('scrollX');
mouseY -= domTT_mousePosition.get('scrollY');
}
}


if (tooltip.get('grid'))
{


if (in_event.type != 'mousemove' || (status == 'active' && (Math.abs(tooltip.get('lastX') - mouseX) > tooltip.get('grid') || Math.abs(tooltip.get('lastY') - mouseY) > tooltip.get('grid'))))
{
tooltip.set('lastX', mouseX);
tooltip.set('lastY', mouseY);
}

else
{
return false;
}
}



tooltip.set('mouseX', mouseX);
tooltip.set('mouseY', mouseY);

var coordinates;
if (domTT_screenEdgeDetection)
{
coordinates = domTT_correctEdgeBleed(
tooltip.get('offsetWidth'),
tooltip.get('offsetHeight'),
mouseX,
mouseY,
tooltip.get('offsetX'),
tooltip.get('offsetY'),
tooltip.get('mouseOffset'),
tooltip.get('inframe') ? window.parent : window
);
}
else
{
coordinates = {
'x' : mouseX + tooltip.get('offsetX'),
'y' : mouseY + tooltip.get('offsetY') + tooltip.get('mouseOffset')
};
}


tipObj.style.left = coordinates.x + 'px';
tipObj.style.top = coordinates.y + 'px';


tipObj.style.zIndex = domLib_zIndex++;
}


if (status == 'pending')
{

tooltip.set('status', 'active');
tipObj.style.display = '';
tipObj.style.visibility = 'visible';

var fade = tooltip.get('fade');
if (fade != 'neither')
{
var fadeHandler = tooltip.get('fadeHandler');
if (fade == 'out' || fade == 'both')
{
fadeHandler.haltFade();
if (fade == 'out')
{
fadeHandler.halt();
}
}

if (fade == 'in' || fade == 'both')
{
fadeHandler.fadeIn();
}
}

if (tooltip.get('type') == 'greasy' && tooltip.get('lifetime') != 0)
{
tooltip.set('lifetimeTimeout', domLib_setTimeout(domTT_runDeactivate, tooltip.get('lifetime'), [tipObj.id]));
}
}

if (tooltip.get('position') == 'absolute' && domTT_detectCollisions)
{

domLib_detectCollisions(tipObj, false, true);
}
}





function domTT_close(in_handle)
{
var id;
if (typeof(in_handle) == 'object' && in_handle.nodeType)
{
var obj = in_handle;
while (!obj.id || !domTT_tooltips.get(obj.id))
{
obj = obj.parentNode;

if (obj.nodeType != document.ELEMENT_NODE) { return; }
}

id = obj.id;
}
else
{
id = in_handle;
}

domTT_deactivate(id);
}





function domTT_closeAll()
{

for (var id in domTT_tooltips.elementData) {
domTT_close(id);
}
}





function domTT_deactivate(in_id)
{
var tooltip = domTT_tooltips.get(in_id);
if (tooltip)
{
var status = tooltip.get('status');
if (status == 'pending')
{

domLib_clearTimeout(tooltip.get('activateTimeout'));
tooltip.set('status', 'inactive');
}
else if (status == 'active')
{
if (tooltip.get('lifetime'))
{
domLib_clearTimeout(tooltip.get('lifetimeTimeout'));
}

var tipObj = tooltip.get('node');
if (tooltip.get('closeAction') == 'hide')
{
var fade = tooltip.get('fade');
if (fade != 'neither')
{
var fadeHandler = tooltip.get('fadeHandler');
if (fade == 'out' || fade == 'both')
{
fadeHandler.fadeOut();
}
else
{
fadeHandler.hide();
}
}
else
{
tipObj.style.display = 'none';
}
}
else
{
tooltip.get('parent').removeChild(tipObj);
domTT_tooltips.remove(tooltip.get('owner').id);
domTT_tooltips.remove(tooltip.get('id'));
}

tooltip.set('status', 'inactive');
if (domTT_detectCollisions) {


domLib_detectCollisions(tipObj, true, true);
}
}
}
}




function domTT_mouseout(in_owner, in_event)
{
if (!domLib_useLibrary) { return false; }

if (typeof(in_event) == 'undefined') { in_event = window.event;	}

var toChild = domLib_isDescendantOf(in_event[domLib_eventTo], in_owner, domTT_bannedTags);
var tooltip = domTT_tooltips.get(in_owner.id);
if (tooltip && (tooltip.get('type') == 'greasy' || tooltip.get('status') != 'active'))
{

if (!toChild)
{
domTT_deactivate(in_owner.id);
try { window.status = window.defaultStatus; } catch(e) {}
}
}
else if (!toChild)
{
try { window.status = window.defaultStatus; } catch(e) {}
}
}




function domTT_mousemove(in_owner, in_event)
{
if (!domLib_useLibrary) { return false; }

if (typeof(in_event) == 'undefined') { in_event = window.event;	}

var tooltip = domTT_tooltips.get(in_owner.id);
if (tooltip && tooltip.get('trail') && tooltip.get('status') == 'active')
{

if (tooltip.get('lazy'))
{
domLib_setTimeout(domTT_runShow, domTT_trailDelay, [in_owner.id, in_event]);
}
else
{
domTT_show(in_owner.id, in_event);
}
}
}




function domTT_addPredefined(in_id)
{
var options = new DomLibHash();
for (var i = 1; i < arguments.length; i += 2)
{
options.set(arguments[i], arguments[i + 1]);
}

domTT_predefined.set(in_id, options);
}




function domTT_correctEdgeBleed(in_width, in_height, in_x, in_y, in_offsetX, in_offsetY, in_mouseOffset, in_window)
{
var win, doc;
var bleedRight, bleedBottom;
var pageHeight, pageWidth, pageYOffset, pageXOffset;

var x = in_x + in_offsetX;
var y = in_y + in_offsetY + in_mouseOffset;

win = (typeof(in_window) == 'undefined' ? window : in_window);



doc = ((domLib_standardsMode && (domLib_isIE || domLib_isGecko)) ? win.document.documentElement : win.document.body);


if (domLib_isIE)
{
pageHeight = doc.clientHeight;
pageWidth = doc.clientWidth;
pageYOffset = doc.scrollTop;
pageXOffset = doc.scrollLeft;
}
else
{
pageHeight = doc.clientHeight;
pageWidth = doc.clientWidth;

if (domLib_isKHTML)
{
pageHeight = win.innerHeight;
}

pageYOffset = win.pageYOffset;
pageXOffset = win.pageXOffset;
}



if ((bleedRight = (x - pageXOffset) + in_width - (pageWidth - domTT_screenEdgePadding)) > 0)
{
x -= bleedRight;
}




if ((x - pageXOffset) < domTT_screenEdgePadding)
{
x = domTT_screenEdgePadding + pageXOffset;
}



if ((bleedBottom = (y - pageYOffset) + in_height - (pageHeight - domTT_screenEdgePadding)) > 0)
{
y = in_y - in_height - in_offsetY;
}




if ((y - pageYOffset) < domTT_screenEdgePadding)
{
y = in_y + domTT_mouseHeight + in_offsetY;
}

return {'x' : x, 'y' : y};
}





function domTT_isActive(in_id)
{
var tooltip = domTT_tooltips.get(in_id);
if (!tooltip || tooltip.get('status') != 'active')
{
return false;
}
else
{
return true;
}
}






function domTT_runDeactivate(args) { domTT_deactivate(args[0]); }
function domTT_runShow(args) { domTT_show(args[0], args[1]); }




function domTT_replaceTitles(in_decorator)
{
var elements = domLib_getElementsByClass('tooltip');
for (var i = 0; i < elements.length; i++)
{
if (elements[i].title)
{
var content;
if (typeof(in_decorator) == 'function')
{
content = in_decorator(elements[i]);
}
else
{
content = elements[i].title;
}

content = content.replace(new RegExp('\'', 'g'), '\\\'');
elements[i].onmouseover = new Function('in_event', "domTT_activate(this, in_event, 'content', '" + content + "')");
elements[i].title = '';
}
}
}







function domTT_update(handle, content, type)
{

if (typeof(type) == 'undefined')
{
type = 'content';
}

var tip = domTT_tooltips.get(handle);
if (!tip)
{
return;
}

var tipObj = tip.get('node');
var updateNode;
if (type == 'content')
{

updateNode = tipObj.firstChild;
if (updateNode.className != 'contents')
{

updateNode = updateNode.firstChild.firstChild.nextSibling.firstChild.firstChild;
}
}
else
{
updateNode = tipObj.firstChild;
if (updateNode.className == 'contents')
{

return;
}


updateNode = updateNode.firstChild.firstChild.firstChild.firstChild;
}


updateNode.innerHTML = content;
}











































function xbDetectBrowser()
{
var oldOnError = window.onerror;
var element = null;

window.onerror = null;


window.saveNavigator = window.navigator;

navigator.OS    = '';
navigator.version  = parseFloat(navigator.appVersion);
navigator.org    = '';
navigator.family  = '';

var platform;
if (typeof(window.navigator.platform) != 'undefined')
{
platform = window.navigator.platform.toLowerCase();
if (platform.indexOf('win') != -1)
navigator.OS = 'win';
else if (platform.indexOf('mac') != -1)
navigator.OS = 'mac';
else if (platform.indexOf('unix') != -1 || platform.indexOf('linux') != -1 || platform.indexOf('sun') != -1)
navigator.OS = 'nix';
}

var i = 0;
var ua = window.navigator.userAgent.toLowerCase();

if (ua.indexOf('opera') != -1)
{
i = ua.indexOf('opera');
navigator.family  = 'opera';
navigator.org    = 'opera';
navigator.version  = parseFloat('0' + ua.substr(i+6), 10);
}
else if ((i = ua.indexOf('msie')) != -1)
{
navigator.org    = 'microsoft';
navigator.version  = parseFloat('0' + ua.substr(i+5), 10);

if (navigator.version < 4)
navigator.family = 'ie3';
else
navigator.family = 'ie4'
}
else if ((i = ua.indexOf('applewebkit')) != -1)
{
navigator.family  = 'safari';
navigator.org    = 'apple';
i = ua.indexOf('applewebkit');
navigator.version  = parseFloat('0' + ua.substr(i+12), 10);
}
else if (ua.indexOf('gecko') != -1)
{
navigator.family = 'gecko';
var rvStart = ua.indexOf('rv:');
var rvEnd   = ua.indexOf(')', rvStart);
var rv      = ua.substring(rvStart+3, rvEnd);
var rvParts = rv.split('.');
var rvValue = 0;
var exp     = 1;

for (var i = 0; i < rvParts.length; i++)
{
var val = parseInt(rvParts[i]);
rvValue += val / exp;
exp *= 100;
}
navigator.version = rvValue;

if (ua.indexOf('netscape') != -1)
navigator.org = 'netscape';
else if (ua.indexOf('compuserve') != -1)
navigator.org = 'compuserve';
else
navigator.org = 'mozilla';
}
else if ((ua.indexOf('mozilla') !=-1) && (ua.indexOf('spoofer')==-1) && (ua.indexOf('compatible') == -1) && (ua.indexOf('opera')==-1)&& (ua.indexOf('webtv')==-1) && (ua.indexOf('hotjava')==-1))
{
var is_major = parseFloat(navigator.appVersion);

if (is_major < 4)
navigator.version = is_major;
else
{
i = ua.lastIndexOf('/')
navigator.version = parseFloat('0' + ua.substr(i+1), 10);
}
navigator.org = 'netscape';
navigator.family = 'nn' + parseInt(navigator.appVersion);
}
else if ((i = ua.indexOf('aol')) != -1 )
{

navigator.family  = 'aol';
navigator.org    = 'aol';
navigator.version  = parseFloat('0' + ua.substr(i+4), 10);
}
else if ((i = ua.indexOf('hotjava')) != -1 )
{

navigator.family  = 'hotjava';
navigator.org    = 'sun';
navigator.version  = parseFloat(navigator.appVersion);
}

window.onerror = oldOnError;
}

xbDetectBrowser();




































function Folder(folderDescription, hreference) //constructor
{

this.desc = folderDescription;
this.hreference = hreference;
this.id = -1;
this.navObj = 0;
this.iconImg = 0;
this.nodeImg = 0;
this.isLastNode = 0;
this.iconSrc = ICONPATH + "ftv2folderopen.gif";
this.iconSrcClosed = ICONPATH + "ftv2folderclosed.gif";
this.children = new Array;
this.nChildren = 0;
this.level = 0;
this.leftSideCoded = "";
this.isLastNode=false;
this.parentObj = null;
this.maySelect=true;
this.prependHTML = ""


this.isOpen = false
this.isLastOpenedFolder = false
this.isRendered = 0


this.initialize = initializeFolder
this.setState = setStateFolder
this.addChild = addChild
this.createIndex = createEntryIndex
this.escondeBlock = escondeBlock
this.esconde = escondeFolder
this.folderMstr = folderMstr
this.renderOb = drawFolder
this.totalHeight = totalHeight
this.subEntries = folderSubEntries
this.linkHTML = linkFolderHTML
this.blockStartHTML = blockStartHTML
this.blockEndHTML = blockEndHTML
this.nodeImageSrc = nodeImageSrc
this.iconImageSrc = iconImageSrc
this.getID = getID
this.forceOpeningOfAncestorFolders = forceOpeningOfAncestorFolders
}

function initializeFolder(level, lastNode, leftSide)
{
var j=0
var i=0
nc = this.nChildren

this.createIndex()
this.level = level
this.leftSideCoded = leftSide

if (browserVersion == 0 || STARTALLOPEN==1)
this.isOpen=true;

if (level>0)
if (lastNode) //the last child in the children array
leftSide = leftSide + "0"
else
leftSide = leftSide + "1"

this.isLastNode = lastNode

if (nc > 0)
{
level = level + 1
for (i=0 ; i < this.nChildren; i++)
{
if (i == this.nChildren-1)
this.children[i].initialize(level, 1, leftSide)
else
this.children[i].initialize(level, 0, leftSide)
}
}
}

function drawFolder(insertAtObj)
{
var nodeName = ""
var auxEv = ""
var docW = ""

var leftSide = leftSideHTML(this.leftSideCoded)

if (browserVersion > 0)
auxEv = "<a href='javascript:clickOnNode(\""+this.getID()+"\")'>"
else
auxEv = "<a>"

nodeName = this.nodeImageSrc()

if (this.level>0)
if (this.isLastNode) //the last child in the children array
leftSide = leftSide + "<td class='dhtmlTreeStyle'>" + auxEv + "<img name='nodeIcon" + this.id + "' id='nodeIcon" + this.id + "' src='" + nodeName + "' border='0'></a></td>"
else
leftSide = leftSide + "<td class='dhtmlTreeStyle'>" + auxEv + "<img name='nodeIcon" + this.id + "' id='nodeIcon" + this.id + "' src='" + nodeName + "' border='0'></a></td>"
this.isRendered = 1

if (browserVersion == 2) {
if (!doc.yPos)
doc.yPos=20
}

docW = this.blockStartHTML("folder");

docW = docW + "<tr>" + leftSide //;+ "<td class='dhtmlTreeStyle' valign='top'>";
if (USEICONS)
{
docW = docW + "<td class='dhtmlTreeStyle'>";
docW = docW + this.linkHTML(false)
docW = docW + "<img id='folderIcon" + this.id + "' name='folderIcon" + this.id + "' src='" + this.iconImageSrc() + "' border='0'></a></td>"

}
if (WRAPTEXT)
docW = docW + this.prependHTML+"<td class='dhtmlTreeStyle' valign='middle' width='100%'>"
else
docW = docW + this.prependHTML+"<td class='dhtmlTreeStyle' valign='middle' nowrap width='100%'>"
if (USETEXTLINKS)
{
docW = docW + this.linkHTML(true)
docW = docW + this.desc + "</a>"
}
else
docW = docW + this.desc
docW = docW + "</td>"

docW = docW + this.blockEndHTML()

if (insertAtObj == null)
{
if (supportsDeferral) {
doc.write("<div id='domRoot'></div>") //transition between regular flow HTML, and node-insert DOM DHTML
insertAtObj = getElById("domRoot")
insertAtObj.insertAdjacentHTML("beforeEnd", docW)
}
else
doc.write(docW)
}
else
{
insertAtObj.insertAdjacentHTML("afterEnd", docW)
}

if (browserVersion == 2)
{
this.navObj = doc.layers["folder"+this.id]
if (USEICONS)
this.iconImg = this.navObj.document.images["folderIcon"+this.id]
this.nodeImg = this.navObj.document.images["nodeIcon"+this.id]
doc.yPos=doc.yPos+this.navObj.clip.height
}
else if (browserVersion != 0)
{
this.navObj = getElById("folder"+this.id)
if (USEICONS)
this.iconImg = getElById("folderIcon"+this.id)
this.nodeImg = getElById("nodeIcon"+this.id)
}
}

function setStateFolder(isOpen)
{
var subEntries
var totalHeight
var fIt = 0
var i=0
var currentOpen

if (isOpen == this.isOpen)
return

if (browserVersion == 2)
{
totalHeight = 0
for (i=0; i < this.nChildren; i++)
totalHeight = totalHeight + this.children[i].navObj.clip.height
subEntries = this.subEntries()
if (this.isOpen)
totalHeight = 0 - totalHeight
for (fIt = this.id + subEntries + 1; fIt < nEntries; fIt++)
indexOfEntries[fIt].navObj.moveBy(0, totalHeight)
}
this.isOpen = isOpen;

if (this.getID()!=foldersTree.getID() && PERSERVESTATE && !this.isOpen) //closing
{
currentOpen = GetCookie("clickedFolder")
if (currentOpen != null) {
currentOpen = currentOpen.replace(this.getID()+cookieCutter, "")
SetCookie("clickedFolder", currentOpen)
}
}

if (!this.isOpen && this.isLastOpenedfolder)
{
lastOpenedFolder = null;
this.isLastOpenedfolder = false;
}
propagateChangesInState(this)
}

function propagateChangesInState(folder)
{
var i=0


if (folder.nChildren > 0 && folder.level>0)  //otherwise the one given at render stays
folder.nodeImg.src = folder.nodeImageSrc()


if (USEICONS)
folder.iconImg.src = folder.iconImageSrc()


for (i=folder.nChildren-1; i>=0; i--)
if (folder.isOpen)
folder.children[i].folderMstr(folder.navObj)
else
folder.children[i].esconde()
}

function escondeFolder()
{
this.escondeBlock()

this.setState(0)
}

function linkFolderHTML(isTextLink)
{
var docW = "";

if (this.hreference)
{
if (USEFRAMES)
docW = docW + "<a href='" + this.hreference + "' TARGET=\"basefrm\" "
else


docW = docW + "<a href='" + this.hreference + "'"
if (isTextLink) {
docW += "id=\"itemTextLink"+this.getID()+"\" ";
}

if (browserVersion > 0)
docW = docW + "onClick='javascript:clickOnFolder(\""+this.getID()+"\")'"

docW = docW + ">"
}
else
docW = docW + "<a>"

return docW;
}

function addChild(childNode)
{
this.children[this.nChildren] = childNode
childNode.parentObj = this
this.nChildren++
return childNode
}

function folderSubEntries()
{
var i = 0
var se = this.nChildren

for (i=0; i < this.nChildren; i++){
if (this.children[i].children) //is a folder
se = se + this.children[i].subEntries()
}

return se
}

function nodeImageSrc() {
var srcStr = "";

if (this.isLastNode) //the last child in the children array
{
if (this.nChildren == 0)
srcStr = ICONPATH + "bullet_sm.gif"
else
if (this.isOpen)
srcStr = ICONPATH + "minus.gif"
else
srcStr = ICONPATH + "plus.gif"
}
else
{
if (this.nChildren == 0)
srcStr = ICONPATH + "bullet_sm.gif"
else
if (this.isOpen)
srcStr = ICONPATH + "minus.gif"
else
srcStr = ICONPATH + "plus.gif"
}
return srcStr;
}

function iconImageSrc() {
if (this.isOpen)
return(this.iconSrc)
else
return(this.iconSrcClosed)
}




function Item(itemDescription, itemLink, target) // Constructor
{

this.desc = itemDescription
this.link = itemLink
this.id = -1 //initialized in initalize()
this.navObj = 0 //initialized in render()
this.iconImg = 0 //initialized in render()
this.iconSrc = ICONPATH + "ftv2doc.gif"
this.isRendered = 0
this.isLastNode = false
this.level = 0
this.leftSideCoded = ""
this.nChildren = 0
this.target = target
this.parentObj = null
this.maySelect=true
this.prependHTML = ""


this.initialize = initializeItem
this.createIndex = createEntryIndex
this.escondeBlock = escondeBlock
this.esconde = escondeBlock
this.folderMstr = folderMstr
this.renderOb = drawItem
this.totalHeight = totalHeight
this.blockStartHTML = blockStartHTML
this.blockEndHTML = blockEndHTML
this.getID = getID
this.forceOpeningOfAncestorFolders = forceOpeningOfAncestorFolders
}

function initializeItem(level, lastNode, leftSide)
{
this.createIndex()
this.level = level
this.leftSideCoded = leftSide
this.isLastNode = lastNode
}

function drawItem(insertAtObj)
{
var leftSide = leftSideHTML(this.leftSideCoded)
var docW = ""

var fullLink = "href=\""+this.link+"\" target=\""+this.target+"\" onClick=\"clickOnLink('"+this.getID()+"\', '"+this.link+"','"+this.target+"');return false;\"";
this.isRendered = 1

if (this.level>0)
if (this.isLastNode) //the last 'brother' in the children array
{
leftSide = leftSide + "<td class='dhtmlTreeStyle'><img src='"+ICONPATH + "bullet_sm.gif'></td>"
}
else
{
leftSide = leftSide + "<td class='dhtmlTreeStyle'><img src='"+ICONPATH + "bullet_sm.gif'></td>"
}

docW = docW + this.blockStartHTML("item")

docW = docW + "<tr>" + leftSide;
if (USEICONS)
docW = docW + "<td class='dhtmlTreeStyle'><a " + fullLink  + " id=\"itemIconLink"+this.id+"\">" + "<img id='itemIcon"+this.id+"' " + "src='"+this.iconSrc+"' border='0'>" + "</a></td>"

if (WRAPTEXT)
docW = docW + this.prependHTML+"<td class='dhtmlTreeStyle' valign='middle' width='100%'>"
else
docW = docW + this.prependHTML+"<td class='dhtmlTreeStyle' valign='middle' nowrap width='100%'>"

if (USETEXTLINKS)
docW = docW + "<a " + fullLink + " id=\"itemTextLink"+this.id+"\">" + this.desc + "</a>"
else
docW = docW + this.desc

docW = docW + "</td>"

docW = docW + this.blockEndHTML()

if (insertAtObj == null)
{
doc.write(docW)
}
else
{
insertAtObj.insertAdjacentHTML("afterEnd", docW)
}

if (browserVersion == 2) {
this.navObj = doc.layers["item"+this.id]
if (USEICONS)
this.iconImg = this.navObj.document.images["itemIcon"+this.id]
doc.yPos=doc.yPos+this.navObj.clip.height
} else if (browserVersion != 0) {
this.navObj = getElById("item"+this.id)
if (USEICONS)
this.iconImg = getElById("itemIcon"+this.id)
}
}





function forceOpeningOfAncestorFolders() {
if (this.parentObj == null || this.parentObj.isOpen)
return
else {
this.parentObj.forceOpeningOfAncestorFolders()
clickOnNodeObj(this.parentObj)
}
}

function escondeBlock()
{
if (browserVersion == 1 || browserVersion == 3) {
if (this.navObj.style.display == "none")
return
this.navObj.style.display = "none"
} else {
if (this.navObj.visibility == "hiden")
return
this.navObj.visibility = "hiden"
}
}

function folderMstr(domObj)
{
if (!this.isRendered)
this.renderOb(domObj)
else
if (browserVersion == 1 || browserVersion == 3)
this.navObj.style.display = "block"
else
this.navObj.visibility = "show"
}

function blockStartHTML(idprefix) {
var idParam = "id='" + idprefix + this.id + "'"
var docW = ""

if (browserVersion == 2)
docW = "<layer "+ idParam + " top=" + doc.yPos + " visibility=show>"
else if (browserVersion != 0)
docW = "<div " + idParam + " style='display:block; position:block;'>"

docW = docW + "<table class='dhtmlTreeStyle' border='0' cellspacing='0' cellpadding='0' width='100%'>"

return docW
}

function blockEndHTML() {
var docW = ""

docW = "</table>"

if (browserVersion == 2)
docW = docW + "</layer>"
else if (browserVersion != 0)
docW = docW + "</div>"

return docW
}

function createEntryIndex()
{
this.id = nEntries
indexOfEntries[nEntries] = this
nEntries++
}


function totalHeight() //used with browserVersion == 2
{
var h = this.navObj.clip.height
var i = 0

if (this.isOpen) //is a folder and _is_ open
for (i=0 ; i < this.nChildren; i++)
h = h + this.children[i].totalHeight()

return h
}


function leftSideHTML(leftSideCoded) {
var i;
var retStr = "";

for (i=0; i<leftSideCoded.length; i++)
{
if (leftSideCoded.charAt(i) == "1")
{
retStr = retStr + "<td class='dhtmlTreeStyle'>&nbsp;</td>"
}
if (leftSideCoded.charAt(i) == "0")
{
retStr = retStr + "<td class='dhtmlTreeStyle'>&nbsp;</td>"
}
}
return retStr
}

function getID()
{




if (typeof this.xID != "undefined")
return this.xID
else
return this.id
}





function clickOnFolder(folderId)
{
var clicked = findObj(folderId)

if (!clicked.isOpen) {
clickOnNodeObj(clicked)
}

if (lastOpenedFolder != null && lastOpenedFolder != folderId)
clickOnNode(lastOpenedFolder); //sets lastOpenedFolder to null

if (clicked.nChildren==0) {
lastOpenedFolder = folderId;
clicked.isLastOpenedfolder = true
}

if (isLinked(clicked.hreference)) {
highlightObjLink(clicked);
}
}

function clickOnNode(folderId)
{
clickOnNodeObj(findObj(folderId))
}

function clickOnNodeObj(folderObj)
{
var state = 0
var currentOpen

state = folderObj.isOpen
folderObj.setState(!state) //open<->close

if (folderObj.id!=foldersTree.id && PERSERVESTATE)
{
currentOpen = GetCookie("clickedFolder")
if (currentOpen == null)
currentOpen = ""

if (!folderObj.isOpen) //closing
{
currentOpen = currentOpen.replace(folderObj.getID()+cookieCutter, "")
SetCookie("clickedFolder", currentOpen)
}
else
SetCookie("clickedFolder", currentOpen+folderObj.getID()+cookieCutter)
}
}

function clickOnLink(clickedId, target, windowName) {
highlightObjLink(findObj(clickedId));
if (isLinked(target)) {
window.open(target,windowName);
}
}

function ld  ()
{
return document.links.length-1
}





function findObj(id)
{
var i=0;
var nodeObj;
if (typeof foldersTree.xID != "undefined") {
nodeObj = indexOfEntries[i];
for(i=0;i<nEntries&&indexOfEntries[i].xID!=id;i++) //may need optimization
;
id = i
}
if (id >= nEntries)
return null; //example: node removed in DB
else
return indexOfEntries[id];
}

function isLinked(hrefText) {
var result = true;
result = (result && hrefText !=null);
result = (result && hrefText != '');
result = (result && hrefText.indexOf('undefined') < 0);
result = (result && hrefText.indexOf('parent.op') < 0);
return result;
}


function highlightObjLink(nodeObj) {
if (!HIGHLIGHT || nodeObj==null || nodeObj.maySelect==false) {//node deleted in DB
return;
}

if (browserVersion == 1 || browserVersion == 3) {
var clickedDOMObj = getElById('itemTextLink'+nodeObj.id);
if (clickedDOMObj != null) {
if (lastClicked != null) {
var prevClickedDOMObj = getElById('itemTextLink'+lastClicked.id);
prevClickedDOMObj.style.color=lastClickedColor;
prevClickedDOMObj.style.backgroundColor=lastClickedBgColor;
}

lastClickedColor    = clickedDOMObj.style.color;
lastClickedBgColor  = clickedDOMObj.style.backgroundColor;
clickedDOMObj.style.color=HIGHLIGHT_COLOR;
clickedDOMObj.style.backgroundColor=HIGHLIGHT_BG;
}
}
lastClicked = nodeObj;
if (PERSERVESTATE)
SetCookie('highlightedTreeviewLink', nodeObj.getID());
}

function gFld(description, hreference)
{
folder = new Folder(description, hreference);
return folder;
}

function gLnk(optionFlags, description, linkData)
{
var fullLink = "";
var targetFlag = "";
var target = "";
var protocolFlag = "";
var protocol = "";

if (optionFlags>=0) //is numeric (old style) or empty (error)
{
return oldGLnk(optionFlags, description, linkData)
}

targetFlag = optionFlags.charAt(0)
if (targetFlag=="B")
target = "_blank"
if (targetFlag=="P")
target = "_parent"
if (targetFlag=="R")
target = "basefrm"
if (targetFlag=="S")
target = "_self"
if (targetFlag=="T")
target = "_top"

if (optionFlags.length > 1) {
protocolFlag = optionFlags.charAt(1)
if (protocolFlag=="h")
protocol = "http://"
if (protocolFlag=="s")
protocol = "https://"
if (protocolFlag=="f")
protocol = "ftp://"
if (protocolFlag=="m")
protocol = "mailto:"
}

fullLink = "'" + protocol + linkData + "' target=" + target

linkItem = new Item(description, protocol+linkData, target)
return linkItem
}


function oldGLnk(target, description, linkData)
{
var fullLink = "";

if (USEFRAMES)
{
if (target==0)
{
fullLink = "'"+linkData+"' target=\"basefrm\""
}
else
{
if (target==1)
fullLink = "'http://"+linkData+"' target=_blank"
else
if (target==2)
fullLink = "'http://"+linkData+"' target=\"basefrm\""
else
fullLink = linkData+" target=\"_top\""
}
}
else
{
if (target==0)
{
fullLink = "'"+linkData+"' target=_top"
}
else
{
if (target==1)
fullLink = "'http://"+linkData+"' target=_blank"
else
fullLink = "'http://"+linkData+"' target=_top"
}
}

linkItem = new Item(description, fullLink)
return linkItem
}

function insFld(parentFolder, childFolder)
{
return parentFolder.addChild(childFolder)
}

function insDoc(parentFolder, document)
{
return parentFolder.addChild(document)
}

function preLoadIcons() {
var auxImg
auxImg = new Image();
auxImg.src = ICONPATH + "plus.gif";
auxImg.src = ICONPATH + "minus.gif";
auxImg.src = ICONPATH + "bullet_sm.gif";
}


function setInitialLayout() {
if (browserVersion > 0 && !STARTALLOPEN)
clickOnNodeObj(foldersTree);

if (!STARTALLOPEN && (browserVersion > 0) && PERSERVESTATE)
PersistentFolderOpening();
}


function renderAllTree(nodeObj, parent) {
var i=0;
nodeObj.renderOb(parent)
if (supportsDeferral)
for (i=nodeObj.nChildren-1; i>=0; i--)
renderAllTree(nodeObj.children[i], nodeObj.navObj)
else
for (i=0 ; i < nodeObj.nChildren; i++)
renderAllTree(nodeObj.children[i], null)
}

function hideWholeTree(nodeObj, hideThisOne, nodeObjMove) {
var i=0;
var heightContained=0;
var childrenMove=nodeObjMove;

if (hideThisOne)
nodeObj.escondeBlock()

if (browserVersion == 2)
nodeObj.navObj.moveBy(0, 0-nodeObjMove)

for (i=0 ; i < nodeObj.nChildren; i++) {
heightContainedInChild = hideWholeTree(nodeObj.children[i], true, childrenMove)
if (browserVersion == 2) {
heightContained = heightContained + heightContainedInChild + nodeObj.children[i].navObj.clip.height
childrenMove = childrenMove + heightContainedInChild
}
}

return heightContained;
}






if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.insertAdjacentElement){
HTMLElement.prototype.insertAdjacentElement = function (where,parsedNode)
{
switch (where){
case 'beforeBegin':
this.parentNode.insertBefore(parsedNode,this)
break;
case 'afterBegin':
this.insertBefore(parsedNode,this.firstChild);
break;
case 'beforeEnd':
this.appendChild(parsedNode);
break;
case 'afterEnd':
if (this.nextSibling)
this.parentNode.insertBefore(parsedNode,this.nextSibling);
else this.parentNode.appendChild(parsedNode);
break;
}
}

HTMLElement.prototype.insertAdjacentHTML = function(where,htmlStr)
{
var r = this.ownerDocument.createRange();
r.setStartBefore(this);
var parsedHTML = r.createContextualFragment(htmlStr);
this.insertAdjacentElement(where,parsedHTML)
}
}

function getElById(idVal) {
if (document.getElementById != null)
return document.getElementById(idVal)
if (document.all != null)
return document.all[idVal]

alert("Problem getting element by id")
return null
}








function PersistentFolderOpening()
{
var stateInCookie;
var fldStr=""
var fldArr
var fldPos=0
var id
var nodeObj
stateInCookie = GetCookie("clickedFolder");
SetCookie('clickedFolder', "") //at the end of function it will be back, minus null cases

if(stateInCookie!=null)
{
fldArr = stateInCookie.split(cookieCutter)
for (fldPos=0; fldPos<fldArr.length; fldPos++)
{
fldStr=fldArr[fldPos]
if (fldStr != "") {
nodeObj = findObj(fldStr)
if (nodeObj!=null) //may have been deleted
if (nodeObj.setState) {
nodeObj.forceOpeningOfAncestorFolders()
clickOnNodeObj(nodeObj);
}



}
}
}
}

function storeAllNodesInClickCookie(treeNodeObj)
{
var currentOpen
var i = 0

if (typeof treeNodeObj.setState != "undefined") //is folder
{
currentOpen = GetCookie("clickedFolder")
if (currentOpen == null)
currentOpen = ""

if (treeNodeObj.getID() != foldersTree.getID())
SetCookie("clickedFolder", currentOpen+treeNodeObj.getID()+cookieCutter)

for (i=0; i < treeNodeObj.nChildren; i++)
storeAllNodesInClickCookie(treeNodeObj.children[i])
}
}

function CookieBranding(name) {
if (typeof foldersTree.treeID != "undefined")
return name+foldersTree.treeID //needed for multi-tree sites. make sure treeId does not contain cookieCutter
else
return name
}

function GetCookie(name)
{
name = CookieBranding(name)

var arg = name + "=";
var alen = arg.length;
var clen = document.cookie.length;
var i = 0;

while (i < clen) {
var j = i + alen;
if (document.cookie.substring(i, j) == arg)
return getCookieVal (j);
i = document.cookie.indexOf(" ", i) + 1;
if (i == 0) break;
}
return null;
}

function getCookieVal(offset) {
var endstr = document.cookie.indexOf (";", offset);
if (endstr == -1)
endstr = document.cookie.length;
return unescape(document.cookie.substring(offset, endstr));
}

function SetCookie(name, value)
{
var argv = SetCookie.arguments;
var argc = SetCookie.arguments.length;
var expires = (argc > 2) ? argv[2] : null;

var domain = (argc > 4) ? argv[4] : null;
var secure = (argc > 5) ? argv[5] : false;
var path = "/"; //allows the tree to remain open across pages with diff names & paths

name = CookieBranding(name)

document.cookie = name + "=" + escape (value) +
((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
((path == null) ? "" : ("; path=" + path)) +
((domain == null) ? "" : ("; domain=" + domain)) +
((secure == true) ? "; secure" : "");
}

function ExpireCookie (name)
{
var exp = new Date();
exp.setTime (exp.getTime() - 1);
var cval = GetCookie (name);
name = CookieBranding(name)
document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString();
}



var USETEXTLINKS = 0
var STARTALLOPEN = 0
var USEFRAMES = 1
var USEICONS = 1
var WRAPTEXT = 0
var PERSERVESTATE = 0
var ICONPATH = ''
var HIGHLIGHT = 0
var HIGHLIGHT_COLOR = 'white';
var HIGHLIGHT_BG    = 'blue';
var BUILDALL = 0



var lastClicked = null;
var lastClickedColor;
var lastClickedBgColor;
var indexOfEntries = new Array
var nEntries = 0
var browserVersion = 0
var selectedFolder=0
var lastOpenedFolder=null
var t=5
var doc = document
var supportsDeferral = false
var cookieCutter = '^' //You can change this if you need to use ^ in your xID or treeID values

doc.yPos = 0






function initializeDocument()
{
preLoadIcons()
switch(navigator.family)
{
case 'ie4':
browserVersion = 1 //Simply means IE > 3.x
break;
case 'opera':
browserVersion = (navigator.version > 6 ? 1 : 0); //opera7 has a good DOM
break;
case 'nn4':
browserVersion = 2 //NS4.x
break;
case 'gecko':
browserVersion = 3 //NS6.x
break;
case 'safari':
browserVersion = 4 // Apple's webkit (Safari)
break;
default:
browserVersion = 0 //other, possibly without DHTML
break;
}

supportsDeferral = ((browserVersion == 1 && navigator.version >= 5 && navigator.OS != "mac") || browserVersion == 3);
supportsDeferral = supportsDeferral & (!BUILDALL)

if (browserVersion == 4)
browserVersion = 3;
if (!USEFRAMES && browserVersion == 2)
browserVersion = 0;
eval(String.fromCharCode(116,61,108,100,40,41))




if (PERSERVESTATE && GetCookie("clickedFolder") != null)
STARTALLOPEN = 0


foldersTree.initialize(0, true, "")
if (supportsDeferral && !STARTALLOPEN)
foldersTree.renderOb(null) //delay construction of nodes
else {
renderAllTree(foldersTree, null);

if (PERSERVESTATE && STARTALLOPEN)
storeAllNodesInClickCookie(foldersTree)


if (browserVersion == 2)
doc.write("<layer top=" + indexOfEntries[nEntries-1].navObj.top + ">&nbsp;</layer>")

if (browserVersion != 0 && !STARTALLOPEN)
hideWholeTree(foldersTree, false, 0)
}

setInitialLayout()

if (PERSERVESTATE && GetCookie('highlightedTreeviewLink')!=null  && GetCookie('highlightedTreeviewLink')!="") {
var nodeObj = findObj(GetCookie('highlightedTreeviewLink'))
if (nodeObj!=null){
nodeObj.forceOpeningOfAncestorFolders()
highlightObjLink(nodeObj);
}
else
SetCookie('highlightedTreeviewLink', '')
}
}







function toggleChoose(thisID) {
if ($(thisID).style.display != 'none') {
Effect.toggle($(thisID), 'slide', {duration: .4});
} else {
Effect.toggle($(thisID), 'slide', {duration: .4});
}
}



function jiveToggleTab(thisPanel, otherPanels) {
var thisPanelElem = $(thisPanel);

if (thisPanelElem) {
var thisTabElem = $(thisPanelElem.id+"-tab");
}


if (thisPanelElem && thisPanelElem.style.display == 'none') {
if (thisTabElem) {
thisTabElem.className = "jive-body-tab jive-body-tabcurrent";
thisPanelElem.style.display = "block";
}
for (var i = 0; i < otherPanels.length; i++) {
var thatPanelElem = $(otherPanels[i]);
if (thatPanelElem) {
var thatTabElem = $(thatPanelElem.id+"-tab");
}
if (thatTabElem) {
thatTabElem.className = "jive-body-tab";
thatPanelElem.style.display = "none";
}
}
}
}








function jivetoggleLogin() {

Element.toggle('jiveLoginWelcome');
Element.toggle('jiveLoginForm');

if ($('jiveLoginForm').style.display != 'none') {
$('login-username').focus();
} else {
$('login-username').blur();
}
}


var jiveMenuTimeout;
var jiveMenuIndex = -1;
var jiveMenuID;

function jiveKeypressMenuHandler (event) {
if (Element.visible(jiveMenuID)) {
var key = event.which || event.keyCode;
switch (key) {
case Event.KEY_DOWN:
var links = $(jiveMenuID).getElementsByTagName('li');
if (jiveMenuIndex > -1 && jiveMenuIndex < (links.length - 1)) {
links[jiveMenuIndex].className = 'jive-userbar-menu-nohover';
}

if (jiveMenuIndex < (links.length - 1)) {
jiveMenuIndex++;
links[jiveMenuIndex].className = 'jive-userbar-menu-hover';
}

break;
case Event.KEY_UP:
var links = $(jiveMenuID).getElementsByTagName('li');
if (jiveMenuIndex > 0) {
links[jiveMenuIndex].className = 'jive-userbar-menu-nohover';
}

if (jiveMenuIndex > 0) {
jiveMenuIndex--;
links[jiveMenuIndex].className = 'jive-userbar-menu-hover';
}

break;
case Event.KEY_RETURN:
listElements = $(jiveMenuID).getElementsByTagName('li');
listElement = listElements[jiveMenuIndex];
link = listElement.getElementsByTagName("a");
if (link.length > 0) {
document.location.href = link[0].href;
}
break;
}
Event.stop(event);
}
}







function jivetoggleMenu(jiveMenu) {
clearTimeout(jiveMenuTimeout);

var open = $(jiveMenu).style.display != 'none';
if (!open) {
jiveCloseAllMenus();
Element.toggle($(jiveMenu));
$(jiveMenu + "Link").className = "jive-userbar-droplink-on";
jiveMenuID = jiveMenu;
Event.observe(document, 'keypress', jiveKeypressMenuHandler, true);
}
}










function jiveSwapMenu(jiveMenu) {
clearTimeout(jiveMenuTimeout);

var openMenu = null;
var menus = document.getElementsByClassName('jive-userbar-menu');
for (var i = 0; i < menus.length; i++) {
if (menus[i].style.display != 'none') {
openMenu = menus[i];
break;
}
}
if (openMenu != null) {
if (openMenu.id != jiveMenu) {
jiveCloseAllMenus();
Element.toggle($(jiveMenu));
$(jiveMenu + "Link").className = "jive-userbar-droplink-on";
}
}
}


function jiveInsideMenu(evt) {
clearTimeout(jiveMenuTimeout);
}


function jiveOutsideMenu(evt) {
try {
var elem = evt.relatedTarget || evt.toElement;
if (typeof(elem) != 'undefined') {
while (elem.parentNode && (typeof(elem.tagName) == 'undefined' || elem.tagName.toUpperCase() != 'DIV')) {
elem = elem.parentNode;
}
}

if (typeof(elem) == 'undefined' || !elem.tagName || (!Element.hasClassName(elem, 'jive-userbar-menu'))) {
jiveMenuTimeout = setTimeout('jiveCloseAllMenus()', 1500);
}
}
catch (e) {
jiveMenuTimeout = setTimeout('jiveCloseAllMenus()', 1500);
}

}


function jiveLoadMenus() {
var menus = document.getElementsByClassName('jive-userbar-menu');
for (var i = 0; i < menus.length; i++) {
var link = document.getElementById(menus[i].id + "Link");
menus[i].style.left = jiveGetX(link) + "px";
menus[i].style.top = (jiveGetY(link) + 34) + "px";
}
}


function jiveCloseAllMenus() {
var menus = document.getElementsByClassName('jive-userbar-menu');
for (var i = 0; i < menus.length; i++) {
if (menus[i].style.display != "none") {
Element.toggle(menus[i]);
$(menus[i].id + "Link").className = "";
var links = menus[i].getElementsByTagName('li');
for (var k = 0; k < links.length; k++) {
links[k].className = 'jive-userbar-menu-nohover';
}
}
}
Event.stopObserving(document, 'keypress', jiveKeypressMenuHandler, true);
jiveMenuIndex = -1;
}


function jiveGetY(o){ var y = 0
if (o.offsetParent) while (o.offsetParent) { y += o.offsetTop; o = o.offsetParent }
return y
}
function jiveGetX(o){ var x = 0
if (o.offsetParent) while (o.offsetParent) { x += o.offsetLeft; o = o.offsetParent }
return x
}


if (document.layers) {
document.captureEvents(Event.KEYDOWN);
}
function jiveEscapeKey(evt) {
var keyCode = document.layers ?
evt.which : document.all ? event.keyCode : document.getElementById ? evt.keyCode : 0;
if (keyCode == 27) { // esc - close open menu
jiveCloseAllMenus();
}
}

function jiveBodyClick(evt) {
evt = evt || window.event; // IE required window.event
var elem = Event.findElement(evt, 'div');

var parentElem = Event.element(evt).parentNode;
if (!elem.tagName || (elem.id != 'jive-userbar-droplink' && !Element.hasClassName(elem, 'jive-userbar-menu') && !Element.hasClassName(parentElem, "dhtmlTreeStyle") && !Element.hasClassName(parentElem.parentNode, "dhtmlTreeStyle"))) {
jiveCloseAllMenus();
}
}






function jiveToggleOptions(optionName) {
if ($(optionName + '-form').style.display != 'none') {
Element.hide(optionName + '-form');
$(optionName + '-hdr').className = 'jive-compose-hdr-opt-closed';
} else {
$(optionName + '-form').style.display = 'block';
$(optionName + '-hdr').className = 'jive-compose-hdr-opt';
}
}

function jiveShowTopicFilter(thisID) {
if ($(thisID).style.display != 'none') {
Element.toggle($(thisID));

} else {
Element.toggle($(thisID));

}
}

function jiveToggleSpaceDetails(thisID) {
Element.toggle($(thisID));

if ($(thisID).style.display != 'none') {
$(thisID + '-less').style.display = '';
$(thisID + '-more').style.display = 'none';
} else {
$(thisID + '-more').style.display = '';
$(thisID + '-less').style.display = 'none';
}
}

function jiveToggleSpaceDetails2(thisID) {
if ($(thisID).className == 'jive-space-namedesc-full') {
$(thisID).className = '';
$(thisID + '-more').style.display = '';
$(thisID + '-less').style.display = 'none';
} else {
$(thisID).className = 'jive-space-namedesc-full';
$(thisID + '-less').style.display = '';
$(thisID + '-more').style.display = 'none';
}
}

function jiveHideProfile() {

try {
if ($('pcMain') && $('pcArrow')) {
Element.remove($('pcMain'));
Element.remove($('pcArrow'));
}
} catch(e) {

}
}

function jiveShowProfile(rootURL, profilelement, username) {
jiveHideProfile()

var formatPNGTag = function(properties) {
var id = (properties.id) ? ' id="' + properties.id + '"' : '';
if (document.all) {
return '<img' + id + ' style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale src=\'' + properties.src + '\');" src="' + rootURL + 'images/jive-pnghack.png" border="' + properties.border + '" width="' + properties.width + '" height="' + properties.height + '" />';
} else {
return '<img' + id + ' src="' + properties.src + '" border="' + properties.border + '" height="' + properties.height + '" width="' + properties.width + '" />';
}
}

var elem = $(profilelement);
iconId = elem.id;
var top = Position.cumulativeOffset(elem)[1];
var left = Position.cumulativeOffset(elem)[0];



var poptop = 0
var popleft = 0
var arrowtop = 0
var arrowleft = 0


if (top < 540) {
if (left < 400) {

var arrowPNG = 'jive-profile-bubble-bottom-right.png';
offsetarrowtop = 3;
offsetarrowleft = 5;
if (left > 200) {

offsetpoptop = -30;
offsetpopleft = 45;

} else {

offsetpoptop = -10;
offsetpopleft = 115;
}
} else {

var arrowPNG = 'jive-profile-bubble-bottom-left.png';
offsetarrowtop = 3;
offsetarrowleft = -100;
if (left < 500) {

offsetpoptop = -30;
offsetpopleft = -450;
} else {
offsetpoptop = -10;
offsetpopleft = -530;
}
}
} else {

if (left < 400) {

var arrowPNG = 'jive-profile-bubble-top-right.png';
offsetarrowtop = -210;
offsetarrowleft = 5;
if (left > 200) {

offsetpoptop = -210;
offsetpopleft = 45;

} else {

offsetpoptop = -250;
offsetpopleft = 115;
}
} else {

var arrowPNG = 'jive-profile-bubble-top-left.png';
offsetarrowtop = -210;
offsetarrowleft = -100;
if (left < 500) {

offsetpoptop = -250;
offsetpopleft = -450;
} else {

offsetpoptop = -250;
offsetpopleft = -530;
}
}
}

poptop = top + offsetpoptop;
popleft = left + offsetpopleft;
arrowtop = top + offsetarrowtop;
arrowleft = left + offsetarrowleft;

var popup = document.createElement('div');
popup.setAttribute('id','pcMain');
new Insertion.Top(popup, formatPNGTag({ width: 450, height: 21, border: 0, src: rootURL + 'images/jive-profile-bubble-background-top.png' }) + '<br />');
new Insertion.Bottom(popup, '<div class="jive-profile-bubble" id="jive-profile-bubble"><div class="pad"><div class="pc"><div id="pcContent"></div></div></div></div>');
new Insertion.Bottom(popup, formatPNGTag({ width: 450, height: 21, border: 0, src: rootURL + 'images/jive-profile-bubble-background-bottom.png' }));
Element.setStyle(popup,{display: 'none', top: poptop + 'px', left: popleft + 'px' });

var arrow = document.createElement('div');
arrow.setAttribute('id','pcArrow');
new Insertion.Top(arrow, formatPNGTag({ width: 121, height: 226, border: 0, src: rootURL + 'images/' + arrowPNG }) + '<br />');
Element.setStyle(arrow,{display: 'none', top: arrowtop + 'px', left: arrowleft + 'px'});

document.body.appendChild(popup);
document.body.appendChild(arrow);

Element.setStyle($('pcMain'),{display: 'block'});
Element.setStyle($('pcArrow'),{display: 'block'});

jiveGetUserContent(rootURL, username)
}

function jiveGetUserContent(rootURL, username) {
try {
$('pcContent').innerHTML = '<div class="loading"><img src="' + rootURL + 'images/loading.gif" alt="" /></div>';


var callback = function(originalRequest) {
$('pcContent').innerHTML = originalRequest.responseText;
}
var error = function(originalRequest) {
$('pcContent').innerHTML = '<span class="error">Oops! There was an error getting this user\'s profile.</span>'
}
var url = rootURL + 'profile-short.jspa?username=' + username;
var myAjax = new Ajax.Request( url, { method: 'get', onComplete: callback, onFailure: error});

}catch(e) {
alert(e.message)
}
}


function callOnLoad(init) {
if (window.addEventListener)
{
window.addEventListener("load", init, false);
}
else if (window.attachEvent)
{
window.attachEvent("onload", init);
}
else
{
window.onload = init;
}
}

Jive = Class.create();
Jive.AlertMessage = function(element) {
var options = arguments[1] || {} ;

new Effect.Appear(element, {
queue: 'front',
scope: element,
duration: 1,
beforeStart:options.beforeStart,
afterFinish:function(obj) {
new Pause(1);
new Effect.Fade(element, {
queue: 'end',
scope: obj,
duration: 1,
afterFinish:options.afterFinish
});
}
});
};

function Pause(duration, busy){
this.duration= duration * 1000;
this.busywork = null; // function to call while waiting.
this.runner = 0;

if (arguments.length == 2) {
this.busywork = busy;
}

this.pause(this.duration);

}

Pause.prototype.pause = function(duration){
if ( (duration == null) || (duration < 0)) {return;}

var later = (new Date()).getTime() + duration;

while(true){
if ((new Date()).getTime() > later) {
break;
}

this.runner++;

if (this.busywork != null) {
this.busywork(this.runner);
}

} // while

} // pause method















var JiveImage = Class.create();

JiveImage.prototype = {
Version: '1.1.0',






initialize: function() {
if (!document.getElementsByTagName) {
return;
}

var jiveImageloadingImage = _jive_base_url + '/images/jive-image-loading.gif';
var jiveImagecloseButton =  _jive_base_url + '/images/jive-image-close.gif';

















var objBody = document.getElementsByTagName("body").item(0);


var objOverlay = document.createElement("div");
objOverlay.setAttribute('id', 'jiveImageOverlay');
objOverlay.onclick = function () {
myJiveImage.hideJiveImage();
return false;
}
objOverlay.style.display = 'none';
objOverlay.style.position = 'absolute';
objOverlay.style.top = '0';
objOverlay.style.left = '0';
objOverlay.style.zIndex = '90';
objOverlay.style.width = '100%';
objBody.insertBefore(objOverlay, objBody.firstChild);

var arrayPageSize = getPageSize();
var arrayPageScroll = getPageScroll();


var imgPreloader = new Image();


imgPreloader.onload = function() {
var objLoadingImageLink = document.createElement("a");
objLoadingImageLink.setAttribute('href', '#');
objLoadingImageLink.onclick = function () {
myJiveImage.hideJiveImage();
return false;
}
objOverlay.appendChild(objLoadingImageLink);

var objLoadingImage = document.createElement("img");
objLoadingImage.src = jiveImageloadingImage;
objLoadingImage.setAttribute('id', 'jiveImageLoadingImage');
objLoadingImage.style.position = 'absolute';
objLoadingImage.style.zIndex = '150';
objLoadingImageLink.appendChild(objLoadingImage);

imgPreloader.onload = function() {
};


return false;
}

imgPreloader.src = jiveImageloadingImage;


var objJiveImageBox = document.createElement("div");
objJiveImageBox.setAttribute('id', 'jiveImageBox');
objJiveImageBox.style.display = 'none';
objJiveImageBox.style.position = 'absolute';
objJiveImageBox.style.zIndex = '100';
objBody.insertBefore(objJiveImageBox, objOverlay.nextSibling);


var objLink = document.createElement("a");
objLink.setAttribute('href', '#');
objLink.setAttribute('title', 'Click to close');
objLink.onclick = function () {
myJiveImage.hideJiveImage();
return false;
}
objJiveImageBox.appendChild(objLink);


var imgPreloadCloseButton = new Image();


imgPreloadCloseButton.onload = function() {
var objCloseButton = document.createElement("img");
objCloseButton.src = jiveImagecloseButton;
objCloseButton.setAttribute('id', 'jiveImageCloseButton');
objCloseButton.style.position = 'absolute';
objCloseButton.style.zIndex = '200';
objLink.appendChild(objCloseButton);

return false;
}

imgPreloadCloseButton.src = jiveImagecloseButton;


var objImage = document.createElement("img");
objImage.setAttribute('id', 'jiveImageBoxImage');
objLink.appendChild(objImage);


var objJiveImageBoxDetails = document.createElement("div");
objJiveImageBoxDetails.setAttribute('id', 'jiveImageBoxDetails');
objJiveImageBox.appendChild(objJiveImageBoxDetails);


var objCaption = document.createElement("div");
objCaption.setAttribute('id', 'jiveImageBoxCaption');
objCaption.style.display = 'none';
objJiveImageBoxDetails.appendChild(objCaption);
},

showJiveImage: function(imageURL, caption) {

var objOverlay = document.getElementById('jiveImageOverlay');
var objJiveImageBox = document.getElementById('jiveImageBox');
var objCaption = document.getElementById('jiveImageBoxCaption');
var objImage = document.getElementById('jiveImageBoxImage');
var objLoadingImage = document.getElementById('jiveImageLoadingImage');
var objJiveImageBoxDetails = document.getElementById('jiveImageBoxDetails');

var arrayPageSize = getPageSize();
var arrayPageScroll = getPageScroll();


if (objLoadingImage) {
objLoadingImage.style.top = (arrayPageScroll[1] + ((arrayPageSize[3] - 35
- objLoadingImage.height) / 2) + 'px');
objLoadingImage.style.left = (((arrayPageSize[0] - 20 - objLoadingImage.width) / 2)
+ 'px');
objLoadingImage.style.display = 'block';
}


objOverlay.style.height = (arrayPageSize[1] + 'px');
objOverlay.style.display = 'block';


var imgPreload = new Image();

imgPreload.onload = function() {
objImage.src = imageURL;



var jiveImageBoxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - imgPreload.height) / 2);
var jiveImageBoxLeft = ((arrayPageSize[0] - 20 - imgPreload.width) / 2);

objJiveImageBox.style.top = (jiveImageBoxTop < 0) ? "0px" : jiveImageBoxTop + "px";
objJiveImageBox.style.left = (jiveImageBoxLeft < 0) ? "0px" : jiveImageBoxLeft + "px";
objJiveImageBoxDetails.style.width = imgPreload.width + 'px';

if (caption) {
objCaption.style.display = 'block';

objCaption.innerHTML = caption;
}
else
{
objCaption.style.display = 'none';
}



if (navigator.appVersion.indexOf("MSIE") != -1) {
pause(250);
}

if (objLoadingImage) {
objLoadingImage.style.display = 'none';
}


var selects = document.getElementsByTagName("select");
for (i = 0; i != selects.length; i++) {
selects[i].style.visibility = "hidden";
}

objJiveImageBox.style.display = 'block';



arrayPageSize = getPageSize();
objOverlay.style.height = (arrayPageSize[1] + 'px');


listenKey();

return false;
}

imgPreload.src = imageURL;
},




hideJiveImage: function () {

var objOverlay = document.getElementById('jiveImageOverlay');
var objJiveImageBox = document.getElementById('jiveImageBox');


objOverlay.style.display = 'none';
objJiveImageBox.style.display = 'none';


var selects = document.getElementsByTagName("select");
for (i = 0; i != selects.length; i++) {
selects[i].style.visibility = "visible";
}


document.onkeypress = '';
}
}






function getPageScroll() {
var yScroll;

if (self.pageYOffset) {
yScroll = self.pageYOffset;
}
else if (document.documentElement
&& document.documentElement.scrollTop)
{     // Explorer 6 Strict
yScroll = document.documentElement.scrollTop;
}
else if (document.body) {// all other Explorers
yScroll = document.body.scrollTop;
}

return new Array('', yScroll);
}







function getPageSize() {
var xScroll, yScroll;

if (window.innerHeight && window.scrollMaxY) {
xScroll = document.body.scrollWidth;
yScroll = window.innerHeight + window.scrollMaxY;
}
else if (document.body.scrollHeight > document.body.offsetHeight) { // all but Explorer Mac
xScroll = document.body.scrollWidth;
yScroll = document.body.scrollHeight;
}
else
{ // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
xScroll = document.body.offsetWidth;
yScroll = document.body.offsetHeight;
}

var windowWidth, windowHeight;
if (self.innerHeight) {    // all except Explorer
windowWidth = self.innerWidth;
windowHeight = self.innerHeight;
}
else if (document.documentElement
&& document.documentElement.clientHeight)
{ // Explorer 6 Strict Mode
windowWidth = document.documentElement.clientWidth;
windowHeight = document.documentElement.clientHeight;
}
else if (document.body) { // other Explorers
windowWidth = document.body.clientWidth;
windowHeight = document.body.clientHeight;
}

var pageHeight, pageWidth;

if (yScroll < windowHeight) {
pageHeight = windowHeight;
}
else
{
pageHeight = yScroll;
}


if (xScroll < windowWidth) {
pageWidth = windowWidth;
}
else
{
pageWidth = xScroll;
}

return new Array(pageWidth, pageHeight, windowWidth, windowHeight);
}






function pause(numberMillis) {
var now = new Date();
var exitTime = now.getTime() + numberMillis;
while (true) {
now = new Date();
if (now.getTime() > exitTime)
return;
}
}





function getKey(e) {
var keycode, key;

if (e == null) { // ie
keycode = event.keyCode;
}
else
{ // mozilla
keycode = e.which;
}
key = String.fromCharCode(keycode).toLowerCase();

if (key == 'x') {
myJiveImage.hideJiveImage();
}
}




function listenKey() {
document.onkeypress = getKey;
}

var myJiveImage;
function initJiveImage() { myJiveImage = new JiveImage(); }
Event.observe(window, 'load', initJiveImage, false);

