if (window.tString != undefined) {
	tString += " aStartExecute:" + ((new Date()).getTime() - tHead);
}
//==============================
//BEGIN ./prototype/1.5.1.1/prototype.js
//==============================
/*  Prototype JavaScript framework, version 1.5.1.1
*  (c) 2005-2007 Sam Stephenson
*
*  Prototype is freely distributable under the terms of an MIT-style license.
*  For details, see the Prototype web site: http://www.prototypejs.org/
*
/*--------------------------------------------------------------------------*/

var Prototype = {
Version: '1.5.1.1',

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

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

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

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

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;
 }
},

toJSON: function(object) {
 var type = typeof object;
 switch(type) {
   case 'undefined':
   case 'function':
   case 'unknown': return;
   case 'boolean': return object.toString();
 }
 if (object === null) return 'null';
 if (object.toJSON) return object.toJSON();
 if (object.ownerDocument === document) return;
 var results = [];
 for (var property in object) {
   var value = Object.toJSON(object[property]);
   if (value !== undefined)
     results.push(property.toJSON() + ': ' + value);
 }
 return '{' + results.join(', ') + '}';
},

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));
}
}

Object.extend(Number.prototype, {
toColorPart: function() {
 return this.toPaddedString(2, 16);
},

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

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

toPaddedString: function(length, radix) {
 var string = this.toString(radix || 10);
 return '0'.times(length - string.length) + string;
},

toJSON: function() {
 return isFinite(this) ? this.toString() : 'null';
}
});

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

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;
   }
 }
}
}
Object.extend(String, {
interpret: function(value) {
 return value == null ? '' : String(value);
},
specialChar: {
 '\b': '\\b',
 '\t': '\\t',
 '\n': '\\n',
 '\f': '\\f',
 '\r': '\\r',
 '\\': '\\\\'
}
});

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

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

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 self = arguments.callee;
 self.text.data = this;
 return self.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 key = decodeURIComponent(pair.shift());
     var value = pair.length > 1 ? pair.join('=') : pair[0];
     if (value != undefined) value = decodeURIComponent(value);

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

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

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

times: function(count) {
 var result = '';
 for (var i = 0; i < count; i++) result += this;
 return result;
},

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

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

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

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

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

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

startsWith: function(pattern) {
 return this.indexOf(pattern) === 0;
},

endsWith: function(pattern) {
 var d = this.length - pattern.length;
 return d >= 0 && this.lastIndexOf(pattern) === d;
},

empty: function() {
 return this == '';
},

blank: function() {
 return /^\s*$/.test(this);
}
});

if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
escapeHTML: function() {
 return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
},
unescapeHTML: function() {
 return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/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;

Object.extend(String.prototype.escapeHTML, {
div:  document.createElement('div'),
text: document.createTextNode('')
});

with (String.prototype.escapeHTML) div.appendChild(text);

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 = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead');

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

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;
}
}

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

Object.extend(Array.prototype, Enumerable);

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

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

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

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

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

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

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(sorted) {
 return this.inject([], function(array, value, index) {
   if (0 == index || (sorted ? array.last() != value : !array.include(value)))
     array.push(value);
   return array;
 });
},

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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(', ') + '}>';
},

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

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

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

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

 this.parameters = params;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ajax.Updater = Class.create();

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

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

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

 this.request(url);
},

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

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

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

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

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) {
 var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
 return document._getElementsByXPath(q, parentElement);
}

} else document.getElementsByClassName = function(className, parentElement) {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
var elements = [], child, pattern = new RegExp("(^|\\s)" + className + "(\\s|$)");
for (var i = 0, length = children.length; i < length; i++) {
 child = children[i];
 var elementClassName = child.className;
 if (elementClassName.length == 0) continue;
 if (elementClassName == className || elementClassName.match(pattern))
   elements.push(Element.extend(child));
}
return elements;
};

/*--------------------------------------------------------------------------*/

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

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

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

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

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

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

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

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

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

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

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

show: function(element) {
 $(element).style.display = '';
 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('*')).each(Element.extend);
},

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

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

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

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

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

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

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

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

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

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

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

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

readAttribute: function(element, name) {
 element = $(element);
 if (Prototype.Browser.IE) {
   if (!element.attributes) return null;
   var t = Element._attributeTranslations;
   if (t.values[name]) return t.values[name](element, name);
   if (t.names[name])  name = t.names[name];
   var attribute = element.attributes[name];
   return attribute ? attribute.nodeValue : null;
 }
 return element.getAttribute(name);
},

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();
},

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

empty: function(element) {
 return $(element).innerHTML.blank();
},

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);
 style = style == 'float' ? 'cssFloat' : style.camelize();
 var value = element.style[style];
 if (!value) {
   var css = document.defaultView.getComputedStyle(element, null);
   value = css ? css[style] : null;
 }
 if (style == 'opacity') return value ? parseFloat(value) : 1.0;
 return value == 'auto' ? null : value;
},

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

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

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

 return element;
},

setOpacity: function(element, value) {
 element = $(element);
 element.style.opacity = (value == 1 || value === '') ? '' :
   (value < 0.00001) ? 0 : value;
 return element;
},

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

 // All *Width and *Height properties give 0 on elements with display none,
 // so enable the element temporarily
 var els = element.style;
 var originalVisibility = els.visibility;
 var originalPosition = els.position;
 var originalDisplay = els.display;
 els.visibility = 'hidden';
 els.position = 'absolute';
 els.display = 'block';
 var originalWidth = element.clientWidth;
 var originalHeight = element.clientHeight;
 els.display = originalDisplay;
 els.position = originalPosition;
 els.visibility = originalVisibility;
 return {width: originalWidth, height: originalHeight};
},

makePositioned: function(element) {
 element = $(element);
 var pos = Element.getStyle(element, 'position');
 if (pos == 'static' || !pos) {
   element._madePositioned = true;
   element.style.position = 'relative';
   // Opera returns the offset relative to the positioning context, when an
   // element is position relative but top and left have not been defined
   if (window.opera) {
     element.style.top = 0;
     element.style.left = 0;
   }
 }
 return element;
},

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

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

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

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

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

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

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

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

// IE is missing .innerHTML support for TABLE-related elements
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;
}
}
else if (Prototype.Browser.Gecko) {
Element.Methods.setOpacity = function(element, value) {
 element = $(element);
 element.style.opacity = (value == 1) ? 0.999999 :
   (value === '') ? '' : (value < 0.00001) ? 0 : value;
 return element;
};
}

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

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

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

Element.Methods.ByTag = {};

Object.extend(Element, Element.Methods);

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

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

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

if (!methods) {
 Object.extend(Form, Form.Methods);
 Object.extend(Form.Element, Form.Element.Methods);
 Object.extend(Element.Methods.ByTag, {
   "FORM":     Object.clone(Form.Methods),
   "INPUT":    Object.clone(Form.Element.Methods),
   "SELECT":   Object.clone(Form.Element.Methods),
   "TEXTAREA": Object.clone(Form.Element.Methods)
 });
}

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

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

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

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

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

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

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

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

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

var 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);
/* Portions of the Selector class are derived from Jack Slocum�s DomQuery,
* part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
* license.  Please see http://www.yui-ext.com/ for more information. */

var Selector = Class.create();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

function $$() {
return Selector.findChildElements(document, $A(arguments));
}
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 != null) {
         if (key in result) {
         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(form).invoke('disable');
 return form;
},

enable: function(form) {
 form = $(form);
 Form.getElements(form).invoke('enable');
 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;
},

request: function(form, options) {
 form = $(form), options = Object.clone(options || {});

 var params = options.parameters;
 options.parameters = form.serialize(true);

 if (params) {
   if (typeof params == 'string') params = params.toQueryParams();
   Object.extend(options.parameters, params);
 }

 if (form.hasAttribute('method') && !options.method)
   options.method = form.method;

 return new Ajax.Request(form.readAttribute('action'), options);
}
}

/*--------------------------------------------------------------------------*/

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);
 try {
   element.focus();
   if (element.select && (element.tagName.toLowerCase() != 'input' ||
     !['button', 'reset', 'submit'].include(element.type)))
     element.select();
 } catch (e) {}
 return element;
},

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

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

/*--------------------------------------------------------------------------*/

var Field = Form.Element;
var $F = Form.Element.Methods.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) {
 // extend element because hasAttribute may not be native
 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;
 }
},

// find the first node with the given tagName, starting from the
// node the event was triggered on; traverses the DOM upwards
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' &&
   (Prototype.Browser.WebKit || element.attachEvent))
   name = 'keydown';

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

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

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

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

/* prevent memory leaks in IE */
if (Prototype.Browser.IE)
Event.observe(window, 'unload', Event.unloadCache, false);
var Position = {
// set to true if needed, warning: firefox performance problems
// NOT neeeded for page scrolling, only if draggable contained in
// scrollable elements
includeScrollOffsets: false,

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

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

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

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

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

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

 return document.body;
},

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

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

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

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

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

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

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

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

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

 } while (element = element.offsetParent);

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

 return [valueL, valueT];
},

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

 // find page position of source
 source = $(source);
 var p = Position.page(source);

 // find coordinate system to use
 target = $(target);
 var delta = [0, 0];
 var parent = null;
 // delta [0,0] will do fine with position: fixed elements,
 // position:absolute needs offsetParent deltas
 if (Element.getStyle(target,'position') == 'absolute') {
   parent = Position.offsetParent(target);
   delta = Position.page(parent);
 }

 // correct by body offsets (fixes Safari)
 if (parent == document.body) {
   delta[0] -= document.body.offsetLeft;
   delta[1] -= document.body.offsetTop;
 }

 // set position
 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;
}
}

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

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

 return [valueL, valueT];
}
}

Element.addMethods();
//==============================
//END ./prototype/1.5.1.1/prototype.js
//==============================
//==============================
//BEGIN ./rico/2.0/rico.js
//==============================
/**
*
*  Copyright 2005 Sabre Airline Solutions
*
*  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
*  file except in compliance with the License. You may obtain a copy of the License at
*
*         http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software distributed under the
*  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
*  either express or implied. See the License for the specific language governing permissions
*  and limitations under the License.
**/


//This module does NOT depend on prototype.js

var Rico = {
Version: '2.0',
loadRequested: 1,
loadComplete: 2,
init : function() {
 this.preloadMsgs='';
 var elements = document.getElementsByTagName('script');
 this.baseHref= location.protocol + "//" + location.host;
 this.loadedFiles={};
 this.loadQueue=[];    
 this.windowIsLoaded=false;
 this.onLoadCallbacks=[];
 for (var i=0; i<elements.length; i++) {
   if (!elements[i].src) continue;
   var src = elements[i].src;
   var slashIdx = src.lastIndexOf('/');
   var path = src.substring(0, slashIdx+1);
   var filename = src.substring(slashIdx+1);
   this.loadedFiles[filename]=this.loadComplete;
   if (filename == 'rico.js') {
     this.jsDir = path;
     this.cssDir= path+'css/';
     this.imgDir= path+'images/';
     this.htmDir= path;
     this.xslDir= path;
   }
 }
 
 if (typeof Prototype=='undefined')
   this.include('prototype.js');
 //this.include('ricoCommon.js');  // commented out since ricoCommon.js is included in this file
 
 var func=function() { Rico.windowLoaded(); };
 if (window.addEventListener)
   window.addEventListener('load', func, false);
 else if (window.attachEvent)
   window.attachEvent('onload', func);
 this.onLoad(function() { Rico.writeDebugMsg('Pre-load messages:\n'+Rico.preloadMsgs); });
},

// Array entries can reference a javascript file or css stylesheet
// A dependency on another module can be indicated with a plus-sign prefix: '+DependsOnModule'
moduleDependencies : {
 Accordion  : ['ricoBehaviors.js','ricoEffects.js','ricoComponents.js'],
 Color      : ['ricoColor.js'],
 Corner     : ['ricoStyles.js'],
 DragAndDrop: ['ricoDragDrop.js'],
 Effect     : ['ricoEffects.js'],
 Calendar   : ['ricoCalendar.js', 'ricoCalendar.css'],
 Tree       : ['ricoTree.js', 'ricoTree.css'],
 ColorPicker: ['ricoColorPicker.js', 'ricoStyles.js'],
 SimpleGrid : ['ricoCommon.js', 'ricoGridCommon.js', 'ricoGrid.css', 'ricoSimpleGrid.js'],
 LiveGrid   : ['ricoCommon.js', 'ricoGridCommon.js', 'ricoGrid.css', 'ricoBehaviors.js', 'ricoLiveGrid.js'],
 CustomMenu : ['ricoMenu.css'],
 LiveGridMenu : ['ricoLiveGridMenu.js', 'ricoMenu.css'],
 LiveGridAjax : ['+LiveGrid', 'ricoLiveGridAjax.js'],
 LiveGridForms: ['+LiveGridAjax', '+LiveGridMenu', '+Accordion', '+Corner', 'ricoLiveGridForms.js', 'ricoLiveGridForms.css'],
 SpreadSheet  : ['+SimpleGrid', 'ricoSheet.js']
},

// not reliable when used with XSLT
loadModule : function(name) {
 var dep=this.moduleDependencies[name];
 if (!dep) return;
 for (var i=0; i<dep.length; i++)
   if (dep[i].substring(0,1)=='+')
     this.loadModule(dep[i].slice(1));
   else
     this.include(dep[i]);
},

// not reliable when used with XSLT
include : function(filename) {
 if (this.loadedFiles[filename]) return;
 this.addPreloadMsg('include: '+filename);
 var ext = filename.substr(filename.lastIndexOf('.')+1);
 switch (ext.toLowerCase()) {
   case 'js':
     this.loadQueue.push(filename);
     this.loadedFiles[filename]=this.loadRequested;
     this.checkLoadQueue();
     return;
   case 'css':
     var el = document.createElement('link');
     el.type = 'text/css';
     el.rel = 'stylesheet'
     el.href = this.cssDir+filename;
     this.loadedFiles[filename]=this.loadComplete;
     document.getElementsByTagName('head')[0].appendChild(el);
     return;
 }
},

checkLoadQueue: function() {
 if (this.loadQueue.length==0) return;
 if (this.inProcess) return;  // seems to only be required by IE, but applied to all browsers just to be safe
 this.addScriptToDOM(this.loadQueue.shift());
},

addScriptToDOM: function(filename) {
 this.addPreloadMsg('addScriptToDOM: '+filename);
 var js = document.createElement('script');
 js.type = 'text/javascript';
 js.src = this.jsDir+filename;
 this.loadedFiles[filename]=this.loadRequested;
 this.inProcess=filename;
 var head=document.getElementsByTagName('head')[0];
 if (filename.substring(0,4)=='rico') {
   head.appendChild(js);
 } else if(/WebKit|Khtml/i.test(navigator.userAgent)) {
   head.appendChild(js);
   this.includeLoaded(filename);
 } else {
   js.onload = js.onreadystatechange = function() {
     if (js.readyState && js.readyState != 'loaded' && js.readyState != 'complete') return;
     js.onreadystatechange = js.onload = null;
     Rico.includeLoaded(filename);
   };
   head.appendChild(js);
 }
},

// called after a script file has finished loading
includeLoaded: function(filename) {
 this.addPreloadMsg('loaded: '+filename);
 this.loadedFiles[filename]=this.loadComplete;
 if (filename==this.inProcess) {
   this.inProcess=null;
   this.checkLoadQueue();
   this.checkIfComplete();
 }
},

// called by the document onload event
windowLoaded: function() {
 this.windowIsLoaded=true;
 this.checkIfComplete();
},

checkIfComplete: function() {
 var waitingFor=this.windowIsLoaded ? '' : 'window';
 for(var filename in  this.loadedFiles) {
   if (this.loadedFiles[filename]==this.loadRequested)
     waitingFor+=' '+filename;
 }
 //window.status='waitingFor: '+waitingFor;
 this.addPreloadMsg('waitingFor: '+waitingFor);
 if (waitingFor.length==0) {
   this.addPreloadMsg('Processing callbacks');
   while (this.onLoadCallbacks.length > 0) {
     var callback=this.onLoadCallbacks.pop();
     if (callback) callback();
   }
 }
},

onLoad: function(callback) {
 this.onLoadCallbacks.push(callback);
 this.checkIfComplete();
},

isKonqueror : navigator.userAgent.toLowerCase().indexOf("konqueror") >= 0,

// logging funtions

startTime : new Date(),

timeStamp: function() {
 var stamp = new Date();
 return (stamp.getTime()-this.startTime.getTime())+": ";
},

setDebugArea: function(id, forceit) {
 if (!this.debugArea || forceit) {
   var newarea=document.getElementById(id);
   if (!newarea) return;
   this.debugArea=newarea;
   newarea.value='';
 }
},

addPreloadMsg: function(msg) {
 this.preloadMsgs+=Rico.timeStamp()+msg+"\n";
},

writeDebugMsg: function(msg, resetFlag) {
 if (this.debugArea) {
   if (resetFlag) this.debugArea.value='';
   this.debugArea.value+=this.timeStamp()+msg+"\n";
 }
}

}

Rico.init();
//==============================
//END ./rico/2.0/rico.js
//==============================
//==============================
//BEGIN ./rico/2.0/ricoAjax.js
//==============================
//-------------------- ricoAjaxEngine.js
Rico.AjaxEngine = Class.create();

Rico.AjaxEngine.prototype = {

initialize: function() {
   this.ajaxElements = new Array();
   this.ajaxObjects  = new Array();
   this.requestURLS  = new Array();
   this.options = {};
},

registerAjaxElement: function( anId, anElement ) {
   if ( !anElement )
      anElement = $(anId);
   this.ajaxElements[anId] = anElement;
},

registerAjaxObject: function( anId, anObject ) {
   this.ajaxObjects[anId] = anObject;
},

registerRequest: function (requestLogicalName, requestURL) {
   this.requestURLS[requestLogicalName] = requestURL;
},

sendRequest: function(requestName, options) {
   // Allow for backwards Compatibility
   if ( arguments.length >= 2 )
    if (typeof arguments[1] == 'string')
      options = {parameters: this._createQueryString(arguments, 1)};
   this.sendRequestWithData(requestName, null, options);
},

sendRequestWithData: function(requestName, xmlDocument, options) {
   var requestURL = this.requestURLS[requestName];
   if ( requestURL == null )
      return;

   // Allow for backwards Compatibility
   if ( arguments.length >= 3 )
     if (typeof arguments[2] == 'string')
       options.parameters = this._createQueryString(arguments, 2);

   new Ajax.Request(requestURL, this._requestOptions(options,xmlDocument));
},

sendRequestAndUpdate: function(requestName,container,options) {
   // Allow for backwards Compatibility
   if ( arguments.length >= 3 )
     if (typeof arguments[2] == 'string')
       options.parameters = this._createQueryString(arguments, 2);

   this.sendRequestWithDataAndUpdate(requestName, null, container, options);
},

sendRequestWithDataAndUpdate: function(requestName,xmlDocument,container,options) {
   var requestURL = this.requestURLS[requestName];
   if ( requestURL == null )
      return;

   // Allow for backwards Compatibility
   if ( arguments.length >= 4 )
     if (typeof arguments[3] == 'string')
       options.parameters = this._createQueryString(arguments, 3);

   var updaterOptions = this._requestOptions(options,xmlDocument);

   new Ajax.Updater(container, requestURL, updaterOptions);
},

// Private -- not part of intended engine API --------------------------------------------------------------------

_requestOptions: function(options,xmlDoc) {
   var requestHeaders = ['X-Rico-Version', Rico.Version ];
   var sendMethod = 'post';
   if ( xmlDoc == null ) {
     if (Rico.prototypeVersion < 1.4)
         requestHeaders.push( 'Content-type', 'text/xml' );
     else
       sendMethod = 'get';
   } else {
      // if postbody is an xml doc, set the content-type to 'text/xml' - mluu
     requestHeaders.push( 'Content-type', 'text/xml;encoding=UTF-8' );
   }
   (!options) ? options = {} : '';

   if (!options._RicoOptionsProcessed){
   // Check and keep any user onComplete functions
     if (options.onComplete)
          options.onRicoComplete = options.onComplete;
     // Fix onComplete
     if (options.overrideOnComplete)
       options.onComplete = options.overrideOnComplete;
     else
       options.onComplete = this._onRequestComplete.bind(this);
     options._RicoOptionsProcessed = true;
   }

  // Set the default options and extend with any user options
  this.options = {
                  requestHeaders: requestHeaders,
                  parameters:     options.parameters,
                  postBody:       xmlDoc,
                  method:         sendMethod,
                  onComplete:     options.onComplete
                 };
  // Set any user options:
  Object.extend(this.options, options);
  return this.options;
},

_createQueryString: function( theArgs, offset ) {
   var queryString = ""
   for ( var i = offset ; i < theArgs.length ; i++ ) {
       if ( i != offset )
         queryString += "&";

       var anArg = theArgs[i];

       if ( anArg.name != undefined && anArg.value != undefined ) {
         queryString += anArg.name +  "=" + escape(anArg.value);
       }
       else {
          var ePos  = anArg.indexOf('=');
          var argName  = anArg.substring( 0, ePos );
          var argValue = anArg.substring( ePos + 1 );
          queryString += argName + "=" + escape(argValue);
       }
   }
   return queryString;
},

_onRequestComplete : function(request) {
   if(!request)
       return;
   // User can set an onFailure option - which will be called by prototype
   if (request.status != 200)
     return;

   var response = request.responseXML.getElementsByTagName("ajax-response");
   if (response == null || response.length != 1)
      return;
   this._processAjaxResponse( response[0].childNodes );
   
   // Check if user has set a onComplete function
   var onRicoComplete = this.options.onRicoComplete;
   if (onRicoComplete != null)
       onRicoComplete();
},

_processAjaxResponse: function( xmlResponseElements ) {
   for ( var i = 0 ; i < xmlResponseElements.length ; i++ ) {
      var responseElement = xmlResponseElements[i];

      // only process nodes of type element.....
      if ( responseElement.nodeType != 1 )
         continue;

      var responseType = responseElement.getAttribute("type");
      var responseId   = responseElement.getAttribute("id");

      if ( responseType == "object" )
         this._processAjaxObjectUpdate( this.ajaxObjects[ responseId ], responseElement );
      else if ( responseType == "element" )
         this._processAjaxElementUpdate( this.ajaxElements[ responseId ], responseElement );
      else
         alert('unrecognized AjaxResponse type : ' + responseType );
   }
},

_processAjaxObjectUpdate: function( ajaxObject, responseElement ) {
   ajaxObject.ajaxUpdate( responseElement );
},

_processAjaxElementUpdate: function( ajaxElement, responseElement ) {
   ajaxElement.innerHTML = RicoUtil.getContentAsString(responseElement);
}

}

var ajaxEngine = new Rico.AjaxEngine();
//==============================
//END ./rico/2.0/ricoAjax.js
//==============================

//==============================
//BEGIN ./rico/2.0/ricoCommon.js
//==============================
/**
*
*  Copyright 2005 Sabre Airline Solutions
*
*  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
*  file except in compliance with the License. You may obtain a copy of the License at
*
*         http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software distributed under the
*  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
*  either express or implied. See the License for the specific language governing permissions
*  and limitations under the License.
**/

if (typeof Rico=='undefined')
throw("Cannot find the Rico object");
if (typeof Prototype=='undefined')
throw("Rico requires the Prototype JavaScript framework");
Rico.prototypeVersion = parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1]);
if (Rico.prototypeVersion < 1.3)
throw("Rico requires Prototype JavaScript framework version 1.3 or greater");

/** @singleton */
var RicoUtil = {

getDirectChildrenByTag: function(e, tagName) {
   var kids = new Array();
   var allKids = e.childNodes;
   tagName=tagName.toLowerCase();
   for( var i = 0 ; i < allKids.length ; i++ )
      if ( allKids[i] && allKids[i].tagName && allKids[i].tagName.toLowerCase() == tagName )
         kids.push(allKids[i]);
   return kids;
},

createXmlDocument : function() {
   if (document.implementation && document.implementation.createDocument) {
      var doc = document.implementation.createDocument("", "", null);

      if (doc.readyState == null) {
         doc.readyState = 1;
         doc.addEventListener("load", function () {
            doc.readyState = 4;
            if (typeof doc.onreadystatechange == "function")
               doc.onreadystatechange();
         }, false);
      }

      return doc;
   }

   if (window.ActiveXObject)
       return Try.these(
         function() { return new ActiveXObject('MSXML2.DomDocument')   },
         function() { return new ActiveXObject('Microsoft.DomDocument')},
         function() { return new ActiveXObject('MSXML.DomDocument')    },
         function() { return new ActiveXObject('MSXML3.DomDocument')   }
       ) || false;

   return null;
},

getInnerText: function(el) {
  if (typeof el == "string") return el;
  if (typeof el == "undefined") { return el };
  var cs = el.childNodes;
  var l = cs.length;
  if (el.innerText) return el.innerText;  //Not needed but it is faster
  var str = "";
  for (var i = 0; i < l; i++) {
    switch (cs[i].nodeType) {
      case 1: //ELEMENT_NODE
        str += (cs[i].tagName.toLowerCase()=='img') ? cs[i].src : ts_getInnerText(cs[i]);
        break;
      case 3: //TEXT_NODE
        str += cs[i].nodeValue;
        break;
    }
  }
  return str;
},

// For Konqueror 3.5, isEncoded must be true
getContentAsString: function( parentNode, isEncoded ) {
   if (isEncoded) return this._getEncodedContent(parentNode);
   if (typeof parentNode.xml != 'undefined') return this._getContentAsStringIE(parentNode);
   return this._getContentAsStringMozilla(parentNode);
},

_getEncodedContent: function(parentNode) {
   if (parentNode.innerHTML) return parentNode.innerHTML;
   switch (parentNode.childNodes.length) {
     case 0:  return "";
     case 1:  return parentNode.firstChild.nodeValue;
     default: return parentNode.childNodes[1].nodeValue;
   }
},

_getContentAsStringIE: function(parentNode) {
  var contentStr = "";
  for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
      var n = parentNode.childNodes[i];
      if (n.nodeType == 4) {
          contentStr += n.nodeValue;
      }
      else {
        contentStr += n.xml;
    }
  }
  return contentStr;
},

_getContentAsStringMozilla: function(parentNode) {
  var xmlSerializer = new XMLSerializer();
  var contentStr = "";
  for ( var i = 0 ; i < parentNode.childNodes.length ; i++ ) {
       var n = parentNode.childNodes[i];
       if (n.nodeType == 4) { // CDATA node
           contentStr += n.nodeValue;
       }
       else {
         contentStr += xmlSerializer.serializeToString(n);
     }
  }
  return contentStr;
},

docElement: function() {
 return (document.compatMode && document.compatMode.indexOf("CSS")!=-1) ? document.documentElement : document.getElementsByTagName("body")[0];
},

/**
* return available height - excludes scrollbar & margin
*/
windowHeight: function() {
 return window.innerHeight? window.innerHeight : this.docElement().clientHeight;
 //return this.docElement().clientHeight;
},

/**
* return available width - excludes scrollbar & margin
*/
windowWidth: function() {
 return this.docElement().clientWidth;
},

docScrollLeft: function() {
  if ( window.pageXOffset )
     return window.pageXOffset;
  else if ( document.documentElement && document.documentElement.scrollLeft )
     return document.documentElement.scrollLeft;
  else if ( document.body )
     return document.body.scrollLeft;
  else
     return 0;
},

docScrollTop: function() {
  if ( window.pageYOffset )
     return window.pageYOffset;
  else if ( document.documentElement && document.documentElement.scrollTop )
     return document.documentElement.scrollTop;
  else if ( document.body )
     return document.body.scrollTop;
  else
     return 0;
},

nan2zero: function(n) {
 if (typeof(n)=='string') n=parseInt(n);
 return isNaN(n) || typeof(n)=='undefined' ? 0 : n;
},

eventKey: function(e) {
 if( typeof( e.keyCode ) == 'number'  ) {
   return e.keyCode; //DOM
 } else if( typeof( e.which ) == 'number' ) {
   return e.which;   //NS 4 compatible
 } else if( typeof( e.charCode ) == 'number'  ) {
   return e.charCode; //also NS 6+, Mozilla 0.9+
 }
 return -1;  //total failure, we have no way of obtaining the key code
},

/**
* Return the previous sibling that has the specified tagName
*/
getPreviosSiblingByTagName: function(el,tagName) {
 var sib=el.previousSibling;
 while (sib) {
     if ((sib.tagName==tagName) && (sib.style.display!='none')) return sib;
     sib=sib.previousSibling;
 }
 return null;
},

/**
* Return the parent HTML element that has the specified tagName.
* @param className optional
*/
getParentByTagName: function(el,tagName,className) {
 var par=el;
 tagName=tagName.toLowerCase();
 while (par) {
     if (par.tagName && par.tagName.toLowerCase()==tagName)
     if (!className || par.className.indexOf(className)>=0) return par;
     par=par.parentNode;
 }
 return null;
},

/**
* Wrap the children of a DOM element in a new element
* @param el the element whose children are to be wrapped
* @param cls class name of the wrapper (optional)
* @param id id of the wrapper (optional)
* @param wrapperTag type of wrapper element to be created (optional, defaults to DIV)
*/
wrapChildren: function(el,cls,id,wrapperTag) {
 var tag=wrapperTag || 'div';
 var wrapper = document.createElement(tag);
 if (id) wrapper.id=id;
 if (cls) wrapper.className=cls;
 while (el.firstChild)
   wrapper.appendChild(el.firstChild);
 el.appendChild(wrapper);
 return wrapper;
},

/**
* Format a positive number
* @param decPlaces the number of digits to display after the decimal point
* @param thouSep the character to use as the thousands separator
* @param decPoint the character to use as the decimal point
*/
formatPosNumber: function(posnum,decPlaces,thouSep,decPoint) {
 var a=posnum.toFixed(decPlaces).split(/\./);
 if (thouSep) {
   var rgx = /(\d+)(\d{3})/;
   while (rgx.test(a[0]))
     a[0]=a[0].replace(rgx, '$1'+thouSep+'$2');
 }
 return a.join(decPoint);
},

/**
* Post condition - if childNodes[n] is refChild, than childNodes[n+1] is newChild.
*/
DOMNode_insertAfter: function(newChild,refChild) {
 var parentx=refChild.parentNode;
 if(parentx.lastChild==refChild) { return parentx.appendChild(newChild);}
 else {return parentx.insertBefore(newChild,refChild.nextSibling);}
},

positionCtlOverIcon: function(ctl,icon) {
 if (ctl.style.display=='none') ctl.style.display='block';
 var offsets=Position.page(icon);
 var correction=Prototype.Browser.IE ? 1 : 2;  // based on a 1px border
 var lpad=this.nan2zero(Element.getStyle(icon,'padding-left'))
 ctl.style.left = (offsets[0]+lpad+correction)+'px';
 var scrTop=this.docScrollTop();
 var newTop=offsets[1] + correction + scrTop;
 var ctlht=ctl.offsetHeight;
 var iconht=icon.offsetHeight;
 if (newTop+iconht+ctlht < this.windowHeight()+scrTop)
   newTop+=iconht;  // display below icon
 else
   newTop=Math.max(newTop-ctlht,scrTop);  // display above icon
 ctl.style.top = newTop+'px';
},

createFormField: function(parent,elemTag,elemType,id,name) {
 if (typeof name!='string') name=id;
 if (Prototype.Browser.IE) {
   // IE cannot set NAME attribute on dynamically created elements
   var s=elemTag+' id="'+id+'"';
   if (elemType) s+=' type="'+elemType+'"';
   if (elemTag.match(/^(form|input|select|textarea|object|button|img)$/)) s+=' name="'+name+'"';
   var field=document.createElement('<'+s+' />');
 } else {
   var field=document.createElement(elemTag);
   if (elemType) field.type=elemType;
   field.id=id;
   if (typeof field.name=='string') field.name=name;
 }
 parent.appendChild(field);
 return field;
},

/**
* Gets the value of the specified cookie
*/
getCookie: function(itemName) {
 var arg = itemName+'=';
 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) {
     var endstr = document.cookie.indexOf (';', j);
     if (endstr == -1) endstr=document.cookie.length;
     return unescape(document.cookie.substring(j, endstr));
   }
   i = document.cookie.indexOf(' ', i) + 1;
   if (i == 0) break;
 }
 return null;
},

/**
* Write information to cookie.
* For cookies to be retained for the current session only, set daysToKeep=null.
* To erase a cookie, pass a negative daysToKeep value.
*/
setCookie: function(itemName,itemValue,daysToKeep,cookiePath,cookieDomain) {
 var c = itemName+"="+escape(itemValue);
 if (typeof(daysToKeep)=='number') {
     var date = new Date();
     date.setTime(date.getTime()+(daysToKeep*24*60*60*1000));
     c+="; expires="+date.toGMTString();
 }
 if (typeof(cookiePath)=='string') c+="; path="+cookiePath;
 if (typeof(cookieDomain)=='string') c+="; domain="+cookieDomain;
 document.cookie = c;
}

};


//Translation helper object
/** @singleton */
var RicoTranslate = {
phrases : {},
thouSep : ",",
decPoint: ".",
langCode: "en",
re      : /^(\W*)\b(.*)\b(\W*)$/,
dateFmt : "mm/dd/yyyy",
timeFmt : "hh:mm:ss a/pm",
monthNames: ['January','February','March','April','May','June',
            'July','August','September','October','November','December'],
dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],

addPhrase: function(fromPhrase, toPhrase) {
 this.phrases[fromPhrase]=toPhrase;
},

/**
* fromPhrase may contain multiple words/phrases separated by tabs
* and each portion will be looked up separately.
* Punctuation & spaces at the beginning or
* ending of a phrase are ignored.
*/
getPhrase: function(fromPhrase) {
 var words=fromPhrase.split(/\t/);
 var transWord,translated = '';
 for (var i=0; i<words.length; i++) {
   if (this.re.exec(words[i])) {
     transWord=this.phrases[RegExp.$2];
     translated += (typeof transWord=='string') ? RegExp.$1+transWord+RegExp.$3 : words[i];
   } else {
     translated += words[i];
   }
 }
 return translated;
}
}


if (!Date.prototype.formatDate) {
Date.prototype.formatDate = function(fmt) {
 var d=this;
 var datefmt=(typeof fmt=='string') ? datefmt=fmt : 'translateDate';
 switch (datefmt) {
   case 'locale':
   case 'localeDateTime':
     return d.toLocaleString();
   case 'localeDate':
     return d.toLocaleDateString();
   case 'translate':
   case 'translateDateTime':
     datefmt=RicoTranslate.dateFmt+' '+RicoTranslate.timeFmt;
     break;
   case 'translateDate':
     datefmt=RicoTranslate.dateFmt;
     break;
 }
 return datefmt.replace(/(yyyy|mmmm|mmm|mm|dddd|ddd|dd|hh|nn|ss|a\/p)/gi,
   function($1) {
     switch ($1.toLowerCase()) {
     case 'yyyy': return d.getFullYear();
     case 'mmmm': return RicoTranslate.monthNames[d.getMonth()];
     case 'mmm':  return RicoTranslate.monthNames[d.getMonth()].substr(0, 3);
     case 'mm':   return (d.getMonth() + 1).toPaddedString(2);
     case 'm':    return (d.getMonth() + 1);
     case 'dddd': return RicoTranslate.dayNames[d.getDay()];
     case 'ddd':  return RicoTranslate.dayNames[d.getDay()].substr(0, 3);
     case 'dd':   return d.getDate().toPaddedString(2);
     case 'd':    return d.getDate();
     case 'hh':   return ((h = d.getHours() % 12) ? h : 12).toPaddedString(2);
     case 'h':    return ((h = d.getHours() % 12) ? h : 12);
     case 'HH':   return d.getHours().toPaddedString(2);
     case 'H':    return d.getHours();
     case 'nn':   return d.getMinutes().toPaddedString(2);
     case 'ss':   return d.getSeconds().toPaddedString(2);
     case 'a/p':  return d.getHours() < 12 ? 'a' : 'p';
     }
   }
 );
}
}

if (!Date.prototype.setISO8601) {
/**
* Converts a string in ISO 8601 format to a date object.
* Returns true if string is a valid date or date-time.
* Based on info at http://delete.me.uk/2005/03/iso8601.html
*/
Date.prototype.setISO8601 = function (string) {
 if (!string) return false;
 var d = string.match(/(\d\d\d\d)(?:-?(\d\d)(?:-?(\d\d)(?:[T ](\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|(?:([-+])(\d\d)(?::?(\d\d))?)?)?)?)?)?/);
 if (!d) return false;
 var offset = 0;
 var date = new Date(d[1], 0, 1);

 if (d[2]) { date.setMonth(d[2] - 1); }
 if (d[3]) { date.setDate(d[3]); }
 if (d[4]) { date.setHours(d[4]); }
 if (d[5]) { date.setMinutes(d[5]); }
 if (d[6]) { date.setSeconds(d[6]); }
 if (d[7]) { date.setMilliseconds(Number("0." + d[7]) * 1000); }
 if (d[8]) {
     if (d[10] && d[11]) offset = (Number(d[10]) * 60) + Number(d[11]);
     offset *= ((d[9] == '-') ? 1 : -1);
     offset -= date.getTimezoneOffset();
 }
 var time = (Number(date) + (offset * 60 * 1000));
 this.setTime(Number(time));
 return true;
}
}

if (!Date.prototype.toISO8601String) {
/**
* Convert date to an ISO 8601 formatted string.
* <p>format is an integer in the range 1-6:<dl>
* <dt>1 (year)</dt>
*   <dd>YYYY (eg 1997)</dd>
* <dt>2 (year and month)</dt>
*   <dd>YYYY-MM (eg 1997-07)</dd>
* <dt>3 (complete date)</dt>
*   <dd>YYYY-MM-DD (eg 1997-07-16)</dd>
* <dt>4 (complete date plus hours and minutes)</dt>
*   <dd>YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)</dd>
* <dt>5 (complete date plus hours, minutes and seconds)</dt>
*   <dd>YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)</dd>
* <dt>6 (complete date plus hours, minutes, seconds and a decimal
*   fraction of a second)</dt>
*   <dd>YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)</dd>
*</dl>
* Based on: http://www.codeproject.com/jscript/dateformat.asp
*/
Date.prototype.toISO8601String = function (format, offset) {
 if (!format) { var format = 6; }
 if (!offset) {
     var offset = 'Z';
     var date = this;
 } else {
     var d = offset.match(/([-+])([0-9]{2}):([0-9]{2})/);
     var offsetnum = (Number(d[2]) * 60) + Number(d[3]);
     offsetnum *= ((d[1] == '-') ? -1 : 1);
     var date = new Date(Number(Number(this) + (offsetnum * 60000)));
 }

 var zeropad = function (num) { return ((num < 10) ? '0' : '') + num; }

 var str = "";
 str += date.getUTCFullYear();
 if (format > 1) { str += "-" + zeropad(date.getUTCMonth() + 1); }
 if (format > 2) { str += "-" + zeropad(date.getUTCDate()); }
 if (format > 3) {
     str += "T" + zeropad(date.getUTCHours()) +
            ":" + zeropad(date.getUTCMinutes());
 }
 if (format > 5) {
     var secs = Number(date.getUTCSeconds() + "." +
                ((date.getUTCMilliseconds() < 100) ? '0' : '') +
                zeropad(date.getUTCMilliseconds()));
     str += ":" + zeropad(secs);
 } else if (format > 4) { str += ":" + zeropad(date.getUTCSeconds()); }

 if (format > 3) { str += offset; }
 return str;
}
}

if (!String.prototype.formatDate) {
String.prototype.formatDate = function(fmt) {
 var s=this.replace(/-/g,'/');
 var d = new Date(s);
 return isNaN(d) ? this : d.formatDate(fmt);
}
}

if (!Number.prototype.formatNumber) {
/**
* Format a number according to the specs in assoc array 'fmt'.
* Result is a string, wrapped in a span element with a class of: negNumber, zeroNumber, posNumber
* These classes can be set in CSS to display negative numbers in red, for example.
* 
* <p>fmt may contain:<dl>
*   <dt>multiplier </dt><dd> the original number is multiplied by this amount before formatting</dd>
*   <dt>decPlaces  </dt><dd> number of digits to the right of the decimal point</dd>
*   <dt>thouSep    </dt><dd> character to use as the thousands separator</dd>
*   <dt>prefix     </dt><dd> string added to the beginning of the result (e.g. a currency symbol)</dd>
*   <dt>suffix     </dt><dd> string added to the end of the result (e.g. % symbol)</dd>
*   <dt>negSign    </dt><dd> specifies format for negative numbers: L=leading minus, T=trailing minus, P=parens</dd>
*</dl>
*/
Number.prototype.formatNumber = function(fmt) {
 if (isNaN(this)) return 'NaN';
 var n=this;
 if (typeof fmt.multiplier=='number') n*=fmt.multiplier;
 var decPlaces=typeof fmt.decPlaces=='number' ? fmt.decPlaces : 0;
 var thouSep=typeof fmt.thouSep=='string' ? fmt.thouSep : RicoTranslate.thouSep;
 var decPoint=typeof fmt.decPoint=='string' ? fmt.decPoint : RicoTranslate.decPoint;
 var prefix=fmt.prefix || "";
 var suffix=fmt.suffix || "";
 var negSign=typeof fmt.negSign=='string' ? fmt.negSign : "L";
 negSign=negSign.toUpperCase();
 var s,cls;
 if (n<0.0) {
   s=RicoUtil.formatPosNumber(-n,decPlaces,thouSep,decPoint);
   if (negSign=="P") s="("+s+")";
   s=prefix+s;
   if (negSign=="L") s="-"+s;
   if (negSign=="T") s+="-";
   cls='negNumber';
 } else {
   cls=n==0.0 ? 'zeroNumber' : 'posNumber';
   s=prefix+RicoUtil.formatPosNumber(n,decPlaces,thouSep,decPoint);
 }
 return "<span class='"+cls+"'>"+s+suffix+"</span>";
}
}

if (!String.prototype.formatNumber) {
/**
* Take a string that can be converted via parseFloat
* and format it according to the specs in assoc array 'fmt'.
*/
String.prototype.formatNumber = function(fmt) {
 var n=parseFloat(this);
 return isNaN(n) ? this : n.formatNumber(fmt);
}
}

/**
* Fix select control bleed-thru on floating divs in IE.
* Based on technique published by Joe King at:
* http://dotnetjunkies.com/WebLog/jking/archive/2003/10/30/2975.aspx
*/
Rico.Shim = Class.create();

if (Prototype.Browser.IE) {
Rico.Shim.prototype = {

 initialize: function() {
   this.ifr = document.createElement('iframe');
   this.ifr.style.position="absolute";
   this.ifr.style.display = "none";
   this.ifr.src="javascript:false;";
   var body = document.getElementsByTagName("body")[0];
   body.appendChild(this.ifr);
 },

 hide: function() {
   this.ifr.style.display = "none";
 },
 
 show: function(DivRef) {
   this.ifr.style.width = DivRef.offsetWidth;
   this.ifr.style.height= DivRef.offsetHeight;
   this.ifr.style.top   = DivRef.style.top;
   this.ifr.style.left  = DivRef.style.left;
   this.ifr.style.zIndex= DivRef.currentStyle.zIndex - 1;
   //this.ifr.style.border = "2px solid green"; // for debugging
   this.ifr.style.display = "block";
 }
}
} else {
Rico.Shim.prototype = {
 initialize: function() {},
 hide: function() {},
 show: function() {}
}
}


/**
* Rico.Shadow is intended for positioned elements.
* Uses blur filter in IE, and alpha-transparent png images for all other browsers.
* Based on: http://www.positioniseverything.net/articles/dropshadows.html
*/
Rico.Shadow = Class.create();

Rico.Shadow.prototype = {

initialize: function(DivRef) {
 this.div = document.createElement('div');
 this.div.style.position="absolute";
 if (typeof this.div.style.filter=='undefined') {
   new Image().src = Rico.imgDir+"shadow.png";
   new Image().src = Rico.imgDir+"shadow_ur.png";
   new Image().src = Rico.imgDir+"shadow_ll.png";
   this.createShadow();
   this.offset=5;
 } else {
   this.div.style.backgroundColor='#888';
   this.div.style.filter='progid:DXImageTransform.Microsoft.Blur(makeShadow=1, shadowOpacity=0.3, pixelRadius=3)';
   this.offset=0; // MS blur filter already does offset
 }
 this.div.style.display = "none";
 DivRef.parentNode.appendChild(this.div);
 this.DivRef=DivRef;
},

createShadow: function() {
 var tab = document.createElement('table');
 tab.style.height='100%';
 tab.style.width='100%';
 tab.cellSpacing=0;
 tab.dir='ltr';

 var tr1=tab.insertRow(-1);
 tr1.style.height='8px';
 var td11=tr1.insertCell(-1);
 td11.style.width='8px';
 var td12=tr1.insertCell(-1);
 td12.style.background="transparent url("+Rico.imgDir+"shadow_ur.png"+") no-repeat right bottom"

 var tr2=tab.insertRow(-1);
 var td21=tr2.insertCell(-1);
 td21.style.background="transparent url("+Rico.imgDir+"shadow_ll.png"+") no-repeat right bottom"
 var td22=tr2.insertCell(-1);
 td22.style.background="transparent url("+Rico.imgDir+"shadow.png"+") no-repeat right bottom"

 this.div.appendChild(tab);
},

hide: function() {
 this.div.style.display = "none";
},

show: function() {
 this.div.style.width = this.DivRef.offsetWidth + 'px';
 this.div.style.height= this.DivRef.offsetHeight + 'px';
 this.div.style.top   = (parseInt(this.DivRef.style.top)+this.offset)+'px';
 this.div.style.left  = (parseInt(this.DivRef.style.left)+this.offset)+'px';
 this.div.style.zIndex= parseInt(Element.getStyle(this.DivRef,'z-index')) - 1;
 this.div.style.display = "block";
}
}

Rico.Menu = Class.create();

Rico.Menu.prototype = {

initialize: function(options) {
 this.options = {
   width        : "15em",
   hideOnEscape : true,
   hideOnClick  : true
 };
 if (typeof options=='string')
   this.options.width=options;
 else
   Object.extend(this.options, options || {});
 this.hideFunc=null;
 this.highlightElem=null;
},

createDiv: function(parentNode) {
 if (this.div) return;
 this.div = document.createElement('div');
 this.div.className = Prototype.Browser.WebKit ? 'ricoMenuSafari' : 'ricoMenu';
 this.div.style.position="absolute";
 this.div.style.width=this.options.width;
 if (!parentNode) {
   parentNode = document.getElementsByTagName("body")[0];
   if (!parentNode) alert('no document body!');
 }
 parentNode.appendChild(this.div);
 this.width=this.div.offsetWidth
 this.shim=new Rico.Shim();
 this.shadow=new Rico.Shadow(this.div);
 this.hidemenu();
 this.itemCount=0;
 this.direction=Element.getStyle(this.div,'direction').toLowerCase();  // ltr or rtl
 if (this.options.hideOnClick)
   Event.observe(document,"click", this.cancelmenu.bindAsEventListener(this), false);
 if (this.options.hideOnEscape)
   Event.observe(document,"keyup", this.checkKey.bindAsEventListener(this), false);
},

ignoreMenuClicks: function() {
 Event.observe(this.div,"click", this.ignoreClick.bindAsEventListener(this), false);
},

ignoreClick: function(e) {
 Event.stop(e);
 return false;
},

// event handler to process keyup events (hide menu on escape key)
checkKey: function(e) {
 if (RicoUtil.eventKey(e)==27) this.cancelmenu(e);
 return true;
},

showmenu: function(e,hideFunc){
 Event.stop(e);
 this.hideFunc=hideFunc;
 if (this.div.childNodes.length==0) {
   this.cancelmenu();
   return false;
 }
 this.openmenu(e.clientX,e.clientY,0,0);
},

openmenu: function(x,y,clickItemWi,clickItemHt) {
 var margin=6; // account for shadow
 var newLeft=RicoUtil.docScrollLeft()+x;
 //window.status='openmenu: newLeft='+newLeft+' width='+this.width+' windowWi='+RicoUtil.windowWidth();
 if (this.direction == 'rtl') {
   if (newLeft > this.width+clickItemWi) newLeft-=this.width+clickItemWi;
 } else {
   if (x+this.width+margin > RicoUtil.windowWidth()) newLeft-=this.width+clickItemWi;
 }
 this.div.style.left=newLeft+"px";
 var newTop=RicoUtil.docScrollTop()+y;
 var contentHt=this.div.offsetHeight;
 if (y+contentHt+margin > RicoUtil.windowHeight())
   newTop=Math.max(newTop-contentHt+clickItemHt,0);
 this.div.style.top=newTop+"px";
 this.div.style.visibility ="visible";
 this.shim.show(this.div);
 this.shadow.show();
 return false;
},

clearMenu: function() {
 this.div.innerHTML="";
 this.defaultAction=null;
 this.itemCount=0;
},

addMenuHeading: function(hdg,translate) {
 var el=document.createElement('div')
 el.innerHTML =(translate==null || translate==true) ? RicoTranslate.getPhrase(hdg) : hdg;
 el.className='ricoMenuHeading';
 this.div.appendChild(el);
},

addMenuBreak: function() {
 var brk=document.createElement('div');
 brk.className="ricoMenuBreak";
 this.div.appendChild(brk);
},

addSubMenuItem: function(menutext, submenu, translate) {
 var dir=this.direction=='rtl' ? 'left' : 'right';
 var a=this.addMenuItem(menutext,null,true,null,translate);
 a.className='ricoSubMenu';
 a.style.backgroundImage='url('+Rico.imgDir+dir+'.gif)';
 a.style.backgroundRepeat='no-repeat';
 a.style.backgroundPosition=dir;
 a.onmouseover=this.showSubMenu.bind(this,a,submenu);
 a.onmouseout=this.subMenuOut.bindAsEventListener(this);
},

showSubMenu: function(a,submenu) {
 if (this.openSubMenu) this.hideSubMenu();
 this.openSubMenu=submenu;
 this.openMenuAnchor=a;
 var pos=Position.page(a);
 if (a.className=='ricoSubMenu') a.className='ricoSubMenuOpen';
 submenu.openmenu(pos[0]+a.offsetWidth, pos[1], a.offsetWidth-2, a.offsetHeight+2);
},

subMenuOut: function(e) {
 if (!this.openSubMenu) return;
 Event.stop(e);
 var elem=Event.element(e);
 var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
 try {
   while (reltg != null && reltg != this.openSubMenu.div)
     reltg=reltg.parentNode;
 } catch(err) {}
 if (reltg == this.openSubMenu.div) return;
 this.hideSubMenu();
},

hideSubMenu: function() {
 if (this.openMenuAnchor) {
   this.openMenuAnchor.className='ricoSubMenu';
   this.openMenuAnchor=null;
 }
 if (this.openSubMenu) {
   this.openSubMenu.hidemenu();
   this.openSubMenu=null;
 }
},

addMenuItem: function(menutext,action,enabled,title,translate,target) {
 this.itemCount++;
 if (translate==null) translate=true;
 var a = document.createElement(typeof action=='string' ? 'a' : 'div');
 if ( arguments.length < 3 || enabled ) {
   switch (typeof action) {
     case 'function': 
       a.onclick = action; 
       break;
     case 'string'  : 
       a.href = action; 
       if (target) a.target = target; 
       break
   }
   a.className = 'enabled';
   if (this.defaultAction==null) this.defaultAction=action;
 } else {
   a.disabled = true;
   a.className = 'disabled';
 }
 a.innerHTML = translate ? RicoTranslate.getPhrase(menutext) : menutext;
 if (typeof title=='string')
   a.title = translate ? RicoTranslate.getPhrase(title) : title;
 a=this.div.appendChild(a);
 Event.observe(a,"mouseover", this.mouseOver.bindAsEventListener(this), false);
 Event.observe(a,"mouseout", this.mouseOut.bindAsEventListener(this), false);
 return a;
},

mouseOver: function(e) {
 if (this.highlightElem && this.highlightElem.className=='enabled-hover') {
   // required for Safari
   this.highlightElem.className='enabled';
   this.highlightElem=null;
 }
 var elem=Event.element(e);
 if (this.openMenuAnchor && this.openMenuAnchor!=elem)
   this.hideSubMenu();
 if (elem.className=='enabled') {
   elem.className='enabled-hover';
   this.highlightElem=elem;
 }
},

mouseOut: function(e) {
 var elem=Event.element(e);
 if (elem.className=='enabled-hover') elem.className='enabled';
 if (this.highlightElem==elem) this.highlightElem=null;
},

isVisible: function() {
 return this.div && this.div.style.visibility!="hidden";
},

cancelmenu: function() {
 if (this.hideFunc) this.hideFunc();
 this.hideFunc=null;
 this.hidemenu();
},

hidemenu: function() {
 if (!this.div) return;
 this.shim.hide();
 this.shadow.hide();
 if (this.openSubMenu) this.openSubMenu.hidemenu();
 this.div.style.visibility="hidden";
 // make sure it stays out of the way and doesn't cause a scrollbar to appear
 this.div.style.top = '0px';
 this.div.style.left= '0px';
}

};

Rico.includeLoaded('ricoCommon.js');
//==============================
//END ./rico/2.0/ricoCommon.js
//==============================
//==============================
//BEGIN ./scriptaculous/1.7.1_beta2/effects.js
//==============================
//script.aculo.us effects.js v1.7.1_beta2, Sat Apr 28 15:20:12 CEST 2007

//Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//Contributors:
//Justin Palmer (http://encytemedia.com/)
//Mark Pilgrim (http://diveintomark.org/)
//Martin Bialasinki
//
//script.aculo.us is freely distributable under the terms of an MIT-style license.
//For details, see the script.aculo.us web site: http://script.aculo.us/ 

//converts rgb() and #xxx to #xxxxxx format,  
//returns self (or first argument) if not convertable  
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(Prototype.Browser.WebKit) window.scrollBy(0,0);
return element;
}

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(Prototype.Browser.IE) 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

/* ------------- transitions ------------- */

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) {
 var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
 return (pos > 1 ? 1 : pos);
},
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;
}
};

/* ------------- core effects ------------- */

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

 if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
   this.effects.push(effect);
 
 if(!this.interval)
   this.interval = setInterval(this.loop.bind(this), 15);
},
remove: function(effect) {
 this.effects = this.effects.reject(function(e) { return e==effect });
 if(this.effects.length == 0) {
   clearInterval(this.interval);
   this.interval = null;
 }
},
loop: function() {
 var timePos = new Date().getTime();
 for(var i=0, len=this.effects.length;i<len;i++) 
   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:        100,   // 100= assume 66fps max.
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) {
 function codeForEvent(options,eventName){
   return (
     (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
     (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
   );
 }
 if(options.transition === false) options.transition = Effect.Transitions.linear;
 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.fromToDelta  = this.options.to-this.options.from;
 this.totalTime    = this.finishOn-this.startOn;
 this.totalFrames  = this.options.fps*this.options.duration;
 
 eval('this.render = function(pos){ '+
   'if(this.state=="idle"){this.state="running";'+
   codeForEvent(options,'beforeSetup')+
   (this.setup ? 'this.setup();':'')+ 
   codeForEvent(options,'afterSetup')+
   '};if(this.state=="running"){'+
   'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
   'this.position=pos;'+
   codeForEvent(options,'beforeUpdate')+
   (this.update ? 'this.update(pos);':'')+
   codeForEvent(options,'afterUpdate')+
   '}}');
 
 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.totalTime,
       frame = Math.round(pos * this.totalFrames);
   if(frame > this.currentFrame) {
     this.render(pos);
     this.currentFrame = frame;
   }
 }
},
cancel: function() {
 if(!this.options.sync)
   Effect.Queues.get(typeof this.options.queue == 'string' ? 
     'global' : this.options.queue.scope).remove(this);
 this.state = 'finished';
},
event: function(eventName) {
 if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
 if(this.options[eventName]) this.options[eventName](this);
},
inspect: function() {
 var data = $H();
 for(property in this)
   if(typeof this[property] != 'function') data[property] = this[property];
 return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
}
}

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

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

Effect.Opacity = Class.create();
Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
initialize: function(element) {
 this.element = $(element);
 if(!this.element) throw(Effect._elementDoesNotExistError);
 // make this work on IE on elements without 'layout'
 if(Prototype.Browser.IE && (!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() {
 // Bug in Opera: Opera returns the "real" position of a static element or
 // relative element that does not have top/left explicitly set.
 // ==> Always set top and left for position relative elements in your stylesheets 
 // (to 0 if you do not need them) 
 this.element.makePositioned();
 this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
 this.originalTop  = parseFloat(this.element.getStyle('top')  || '0');
 if(this.options.mode == 'absolute') {
   // absolute movement, so we need to calc deltaX and deltaY
   this.options.x = this.options.x - this.originalLeft;
   this.options.y = this.options.y - this.originalTop;
 }
},
update: function(position) {
 this.element.setStyle({
   left: Math.round(this.options.x  * position + this.originalLeft) + 'px',
   top:  Math.round(this.options.y  * position + this.originalTop)  + 'px'
 });
}
});

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

Effect.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() {
 // Prevent executing on elements not in the layout flow
 if(this.element.getStyle('display')=='none') { this.cancel(); return; }
 // Disable background image during the effect
 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');
 // init color calculations
 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));
}
});

/* ------------- combination effects ------------- */

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,
// force Safari to render floated elements properly
afterFinishInternal: function(effect) {
 effect.element.forceRerendering();
},
beforeSetup: function(effect) {
 effect.element.setOpacity(effect.options.from).show(); 
}}, arguments[1] || {});
return new Effect.Opacity(element,options);
}

Effect.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();
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
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] || {})
);
}

//Bug in opera makes the TD containing this element expand for a instance after finish 
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] = '';
       });
     }
   } 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], value = pair[1], unit = null;

   if(value.parseColor('#zzzzzz') != '#zzzzzz') {
     value = value.parseColor();
     unit  = 'color';
   } else if(property == 'opacity') {
     value = parseFloat(value);
     if(Prototype.Browser.IE && (!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 { 
     style: property.camelize(), 
     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 = {}, transform, i = this.transforms.length;
 while(i--)
   style[(transform = this.transforms[i]).style] = 
     transform.unit=='color' ? '#'+
       (Math.round(transform.originalValue[0]+
         (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
       (Math.round(transform.originalValue[1]+
         (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
       (Math.round(transform.originalValue[2]+
         (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
     transform.originalValue + Math.round(
       ((transform.targetValue - transform.originalValue) * position) * 1000)/1000 + transform.unit;
 this.element.setStyle(style, true);
}
});

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 = document.createElement('div');
element.innerHTML = '<div style="' + this + '"></div>';
var style = element.childNodes[0].style, styleRules = $H();

Element.CSS_PROPERTIES.each(function(property){
 if(style[property]) styleRules[property] = style[property]; 
});
if(Prototype.Browser.IE && 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;
};

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

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

Element.addMethods();
//==============================
//END ./scriptaculous/1.7.1_beta2/effects.js
//==============================
//==============================
//BEGIN ./scriptaculous/1.7.1_beta2/scriptaculous.js
//==============================
//script.aculo.us scriptaculous.js v1.7.1_beta2, Sat Apr 28 15:20:12 CEST 2007

//Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//
//Permission is hereby granted, free of charge, to any person obtaining
//a copy of this software and associated documentation files (the
//"Software"), to deal in the Software without restriction, including
//without limitation the rights to use, copy, modify, merge, publish,
//distribute, sublicense, and/or sell copies of the Software, and to
//permit persons to whom the Software is furnished to do so, subject to
//the following conditions:
//
//The above copyright notice and this permission notice shall be
//included in all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
//MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
//LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
//OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
//WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//For details, see the script.aculo.us web site: http://script.aculo.us/

var Scriptaculous = {
Version: '1.7.1_beta2',
require: function(libraryName) {
 // inserting via DOM fails in Safari 2.0, so brute force approach
 document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
},
REQUIRED_PROTOTYPE: '1.5.1',
load: function() {
 function convertVersionString(versionString){
   var r = versionString.split('.');
   return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
 }

 if((typeof Prototype=='undefined') || 
    (typeof Element == 'undefined') || 
    (typeof Element.Methods=='undefined') ||
    (convertVersionString(Prototype.Version) < 
     convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
    throw("script.aculo.us requires the Prototype JavaScript framework >= " +
     Scriptaculous.REQUIRED_PROTOTYPE);
 
 $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,sound').split(',').each(
    function(include) { Scriptaculous.require(path+include+'.js') });
 });
}
}

Scriptaculous.load();
//==============================
//END ./scriptaculous/1.7.1_beta2/scriptaculous.js
//==============================
//==============================
//BEGIN ./scriptaculous/1.7.1_beta2/slider.js
//==============================
//script.aculo.us slider.js v1.7.1_beta2, Sat Apr 28 15:20:12 CEST 2007

//Copyright (c) 2005-2007 Marty Haught, Thomas Fuchs 
//
//script.aculo.us is freely distributable under the terms of an MIT-style license.
//For details, see the script.aculo.us web site: http://script.aculo.us/

if(!Control) var Control = {};
Control.Slider = Class.create();

//options:
//axis: 'vertical', or 'horizontal' (default)
//
//callbacks:
//onChange(value)
//onSlide(value)
Control.Slider.prototype = {
initialize: function(handle, track, options) {
 var slider = this;
 
 if(handle instanceof Array) {
   this.handles = handle.collect( function(e) { return $(e) });
 } else {
   this.handles = [$(handle)];
 }
 
 this.track   = $(track);
 this.options = options || {};

 this.axis      = this.options.axis || 'horizontal';
 this.increment = this.options.increment || 1;
 this.step      = parseInt(this.options.step || '1');
 this.range     = this.options.range || $R(0,1);
 
 this.value     = 0; // assure backwards compat
 this.values    = this.handles.map( function() { return 0 });
 this.spans     = this.options.spans ? this.options.spans.map(function(s){ return $(s) }) : false;
 this.options.startSpan = $(this.options.startSpan || null);
 this.options.endSpan   = $(this.options.endSpan || null);

 this.restricted = this.options.restricted || false;

 this.maximum   = this.options.maximum || this.range.end;
 this.minimum   = this.options.minimum || this.range.start;

 // Will be used to align the handle onto the track, if necessary
 this.alignX = parseInt(this.options.alignX || '0');
 this.alignY = parseInt(this.options.alignY || '0');
 
 this.trackLength = this.maximumOffset() - this.minimumOffset();

 this.handleLength = this.isVertical() ? 
   (this.handles[0].offsetHeight != 0 ? 
     this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : 
   (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : 
     this.handles[0].style.width.replace(/px$/,""));

 this.active   = false;
 this.dragging = false;
 this.disabled = false;

 if(this.options.disabled) this.setDisabled();

 // Allowed values array
 this.allowedValues = this.options.values ? this.options.values.sortBy(Prototype.K) : false;
 if(this.allowedValues) {
   this.minimum = this.allowedValues.min();
   this.maximum = this.allowedValues.max();
 }

 this.eventMouseDown = this.startDrag.bindAsEventListener(this);
 this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
 this.eventMouseMove = this.update.bindAsEventListener(this);

 // Initialize handles in reverse (make sure first handle is active)
 this.handles.each( function(h,i) {
   i = slider.handles.length-1-i;
   slider.setValue(parseFloat(
     (slider.options.sliderValue instanceof Array ? 
       slider.options.sliderValue[i] : slider.options.sliderValue) || 
      slider.range.start), i);
   Element.makePositioned(h); // fix IE
   Event.observe(h, "mousedown", slider.eventMouseDown);
 });
 
 Event.observe(this.track, "mousedown", this.eventMouseDown);
 Event.observe(document, "mouseup", this.eventMouseUp);
 Event.observe(document, "mousemove", this.eventMouseMove);
 
 this.initialized = true;
},
dispose: function() {
 var slider = this;    
 Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
 Event.stopObserving(document, "mouseup", this.eventMouseUp);
 Event.stopObserving(document, "mousemove", this.eventMouseMove);
 this.handles.each( function(h) {
   Event.stopObserving(h, "mousedown", slider.eventMouseDown);
 });
},
setDisabled: function(){
 this.disabled = true;
},
setEnabled: function(){
 this.disabled = false;
},  
getNearestValue: function(value){
 if(this.allowedValues){
   if(value >= this.allowedValues.max()) return(this.allowedValues.max());
   if(value <= this.allowedValues.min()) return(this.allowedValues.min());
   
   var offset = Math.abs(this.allowedValues[0] - value);
   var newValue = this.allowedValues[0];
   this.allowedValues.each( function(v) {
     var currentOffset = Math.abs(v - value);
     if(currentOffset <= offset){
       newValue = v;
       offset = currentOffset;
     } 
   });
   return newValue;
 }
 if(value > this.range.end) return this.range.end;
 if(value < this.range.start) return this.range.start;
 return value;
},
setValue: function(sliderValue, handleIdx){
 if(!this.active) {
   this.activeHandleIdx = handleIdx || 0;
   this.activeHandle    = this.handles[this.activeHandleIdx];
   this.updateStyles();
 }
 handleIdx = handleIdx || this.activeHandleIdx || 0;
 if(this.initialized && this.restricted) {
   if((handleIdx>0) && (sliderValue<this.values[handleIdx-1]))
     sliderValue = this.values[handleIdx-1];
   if((handleIdx < (this.handles.length-1)) && (sliderValue>this.values[handleIdx+1]))
     sliderValue = this.values[handleIdx+1];
 }
 sliderValue = this.getNearestValue(sliderValue);
 this.values[handleIdx] = sliderValue;
 this.value = this.values[0]; // assure backwards compat
 
 this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = 
   this.translateToPx(sliderValue);
 
 this.drawSpans();
 if(!this.dragging || !this.event) this.updateFinished();
},
setValueBy: function(delta, handleIdx) {
 this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, 
   handleIdx || this.activeHandleIdx || 0);
},
translateToPx: function(value) {
 return Math.round(
   ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * 
   (value - this.range.start)) + "px";
},
translateToValue: function(offset) {
 return ((offset/(this.trackLength-this.handleLength) * 
   (this.range.end-this.range.start)) + this.range.start);
},
getRange: function(range) {
 var v = this.values.sortBy(Prototype.K); 
 range = range || 0;
 return $R(v[range],v[range+1]);
},
minimumOffset: function(){
 return(this.isVertical() ? this.alignY : this.alignX);
},
maximumOffset: function(){
 return(this.isVertical() ? 
   (this.track.offsetHeight != 0 ? this.track.offsetHeight :
     this.track.style.height.replace(/px$/,"")) - this.alignY : 
   (this.track.offsetWidth != 0 ? this.track.offsetWidth : 
     this.track.style.width.replace(/px$/,"")) - this.alignY);
},  
isVertical:  function(){
 return (this.axis == 'vertical');
},
drawSpans: function() {
 var slider = this;
 if(this.spans)
   $R(0, this.spans.length-1).each(function(r) { slider.setSpan(slider.spans[r], slider.getRange(r)) });
 if(this.options.startSpan)
   this.setSpan(this.options.startSpan,
     $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
 if(this.options.endSpan)
   this.setSpan(this.options.endSpan, 
     $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
},
setSpan: function(span, range) {
 if(this.isVertical()) {
   span.style.top = this.translateToPx(range.start);
   span.style.height = this.translateToPx(range.end - range.start + this.range.start);
 } else {
   span.style.left = this.translateToPx(range.start);
   span.style.width = this.translateToPx(range.end - range.start + this.range.start);
 }
},
updateStyles: function() {
 this.handles.each( function(h){ Element.removeClassName(h, 'selected') });
 Element.addClassName(this.activeHandle, 'selected');
},
startDrag: function(event) {
 if(Event.isLeftClick(event)) {
   if(!this.disabled){
     this.active = true;
     
     var handle = Event.element(event);
     var pointer  = [Event.pointerX(event), Event.pointerY(event)];
     var track = handle;
     if(track==this.track) {
       var offsets  = Position.cumulativeOffset(this.track); 
       this.event = event;
       this.setValue(this.translateToValue( 
        (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
       ));
       var offsets  = Position.cumulativeOffset(this.activeHandle);
       this.offsetX = (pointer[0] - offsets[0]);
       this.offsetY = (pointer[1] - offsets[1]);
     } else {
       // find the handle (prevents issues with Safari)
       while((this.handles.indexOf(handle) == -1) && handle.parentNode) 
         handle = handle.parentNode;
         
       if(this.handles.indexOf(handle)!=-1) {
         this.activeHandle    = handle;
         this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
         this.updateStyles();
         
         var offsets  = Position.cumulativeOffset(this.activeHandle);
         this.offsetX = (pointer[0] - offsets[0]);
         this.offsetY = (pointer[1] - offsets[1]);
       }
     }
   }
   Event.stop(event);
 }
},
update: function(event) {
if(this.active) {
   if(!this.dragging) this.dragging = true;
   this.draw(event);
   if(Prototype.Browser.WebKit) window.scrollBy(0,0);
   Event.stop(event);
}
},
draw: function(event) {
 var pointer = [Event.pointerX(event), Event.pointerY(event)];
 var offsets = Position.cumulativeOffset(this.track);
 pointer[0] -= this.offsetX + offsets[0];
 pointer[1] -= this.offsetY + offsets[1];
 this.event = event;
 this.setValue(this.translateToValue( this.isVertical() ? pointer[1] : pointer[0] ));
 if(this.initialized && this.options.onSlide)
   this.options.onSlide(this.values.length>1 ? this.values : this.value, this);
},
endDrag: function(event) {
 if(this.active && this.dragging) {
   this.finishDrag(event, true);
   Event.stop(event);
 }
 this.active = false;
 this.dragging = false;
},  
finishDrag: function(event, success) {
 this.active = false;
 this.dragging = false;
 this.updateFinished();
},
updateFinished: function() {
 if(this.initialized && this.options.onChange) 
   this.options.onChange(this.values.length>1 ? this.values : this.value, this);
 this.event = null;
}
}
//==============================
//END ./scriptaculous/1.7.1_beta2/slider.js
//==============================

//==============================
//BEGIN ./scriptaculous/plugin/lightWindow.js
//==============================

//lightwindow.js v2.0
//
//Copyright (c) 2007 stickmanlabs
//Author: Kevin P Miller | http://www.stickmanlabs.com
//
//LightWindow is freely distributable under the terms of an MIT-style license.
//
//I don't care what you think about the file size...
//Be a pro: 
//   http://www.thinkvitamin.com/features/webapps/serving-javascript-fast
//   http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files
//
//NOTE: This is slightly modified to allow modality.  Specifically, the setModal method and
//the options.isModal flag were added.  The loading div was slightly modified by removing
//the "Cancel" link.
/*-----------------------------------------------------------------------------------------------*/

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

//This will stop image flickering in IE6 when elements with images are moved
try {
 document.execCommand("BackgroundImageCache", false, true);
} catch(e) {}

var lightwindow = Class.create();   
lightwindow.prototype = {
 //
 //  Setup Variables
 //
 element : null,
 contentToFetch : null,
 windowActive : false,
 dataEffects : [],
 dimensions : {
     cruft : null,
     container : null,
     viewport : {
         height : null,
         width : null,
         offsetTop : null,
         offsetLeft : null
     }
 },
 pagePosition : {
     x : 0,
     y : 0
 },
 pageDimensions : {
     width : null,
     height : null
 },
 preloadImage : [],
 preloadedImage : [],
 galleries : [],
 resizeTo : {
     height : null,
     heightPercent : null,
     width : null,
     widthPercent : null,
     fixedTop : null,
     fixedLeft : null
 },
 scrollbarOffset : 18,
 navigationObservers : {
     previous : null,
     next : null
 },
 containerChange : {
     height : 0,
     width : 0
 },
 activeGallery : false,
 galleryLocation : {
     current : 0,
     total : 0
 },
 deactivateHandler : null,
 //
 //  Initialize the lightwindow.
 //
 initialize : function(options) {
     this.options = Object.extend({
         resizeSpeed : 10,
         contentOffset : {
             height : 20,
             width : 20
         },
         dimensions : {
             image : {height : 450, width : 650},
             page : {height : 250, width : 500},
             inline : {height : 0, width : 500}, // set height to 0 to force the height to resize based on content -MQL
             media : {height : 250, width : 250},
             external : {height : 250, width : 250},
             titleHeight : 25
         },
         classNames : {  
             standard : 'lightwindow',
             action : 'lightwindow_action'
         },
         fileTypes : {
             page : ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'pl', 'php4', 'php3', 'php', 'php5', 'phtml', 'rhtml', 'shtml', 'txt', 'vbs', 'rb'],
             media : ['aif', 'aiff', 'asf', 'avi', 'divx', 'm1v', 'm2a', 'm2v', 'm3u', 'mid', 'midi', 'mov', 'moov', 'movie', 'mp2', 'mp3', 'mpa', 'mpa', 'mpe', 'mpeg', 'mpg', 'mpg', 'mpga', 'pps', 'qt', 'rm', 'ram', 'swf', 'viv', 'vivo', 'wav'],
             image : ['bmp', 'gif', 'jpg', 'png', 'tiff']
         },
         mimeTypes : {
             avi : 'video/avi',
             aif : 'audio/aiff',
             aiff : 'audio/aiff',
             gif : 'image/gif',
             bmp : 'image/bmp',
             jpeg : 'image/jpeg',
             m1v : 'video/mpeg',
             m2a : 'audio/mpeg',
             m2v : 'video/mpeg',
             m3u : 'audio/x-mpequrl',
             mid : 'audio/x-midi',
             midi : 'audio/x-midi',
             mjpg : 'video/x-motion-jpeg',
             moov : 'video/quicktime',
             mov : 'video/quicktime',
             movie : 'video/x-sgi-movie',
             mp2 : 'audio/mpeg',
             mp3 : 'audio/mpeg3',
             mpa : 'audio/mpeg',
             mpa : 'video/mpeg',
             mpe : 'video/mpeg',
             mpeg : 'video/mpeg',
             mpg : 'audio/mpeg',
             mpg : 'video/mpeg',
             mpga : 'audio/mpeg',
             pdf : 'application/pdf',
             png : 'image/png',
             pps : 'application/mspowerpoint',
             qt : 'video/quicktime',
             ram : 'audio/x-pn-realaudio-plugin',
             rm : 'application/vnd.rn-realmedia',
             swf : 'application/x-shockwave-flash',
             tiff : 'image/tiff',
             viv : 'video/vivo',
             vivo : 'video/vivo',
             wav : 'audio/wav',
             wmv : 'application/x-mplayer2'          
         },  
         classids : {
             mov : 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B',
             swf : 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000',
             wmv : 'clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6'
         },
         codebases : {
             mov : 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0',
             swf : 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0',
             wmv : 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715'
         },  
         viewportPadding : 10,
         EOLASFix : 'swf,wmv,fla,flv',
         overlay : {
             opacity : 0.7,
             image : '/beta/style/shun/base/base/en/graphic/lightbox/black-70.png',
             presetImage : '/beta/style/shun/base/base/en/graphic/lightbox/black-70.png'
         },
         skin :  {
             main :  '<div id="lightwindow_container" >'+
                         '<div id="lightwindow_title_bar" >'+
                             '<div id="lightwindow_title_bar_inner" >'+
                                 '<span id="lightwindow_title_bar_title"></span>'+
                                 '<a id="lightwindow_title_bar_close_link" >close</a>'+
                             '</div>'+
                         '</div>'+
                         '<div id="lightwindow_stage" >'+
                             '<div id="lightwindow_contents" >'+
                             '</div>'+
                             '<div id="lightwindow_navigation" >'+
                                 '<a href="#" id="lightwindow_previous" >'+
                                     '<span id="lightwindow_previous_title"></span>'+
                                 '</a>'+
                                 '<a href="#" id="lightwindow_next" >'+
                                     '<span id="lightwindow_next_title"></span>'+
                                 '</a>'+
                                 '<iframe name="lightwindow_navigation_shim" id="lightwindow_navigation_shim" src="javascript:false;" frameBorder="0" scrolling="no"></iframe>'+
                             '</div>'+                               
                             '<div id="lightwindow_galleries">'+
                                 '<div id="lightwindow_galleries_tab_container" >'+
                                     '<a href="#" id="lightwindow_galleries_tab" >'+
                                         '<span id="lightwindow_galleries_tab_span" class="up" >Galleries</span>'+
                                     '</a>'+
                                 '</div>'+
                                 '<div id="lightwindow_galleries_list" >'+
                                 '</div>'+
                             '</div>'+
                         '</div>'+
                         '<div id="lightwindow_data_slide" >'+
                             '<div id="lightwindow_data_slide_inner" >'+
                                 '<div id="lightwindow_data_details" >'+
                                     '<div id="lightwindow_data_gallery_container" >'+
                                         '<span id="lightwindow_data_gallery_current"></span>'+
                                         ' of '+
                                         '<span id="lightwindow_data_gallery_total"></span>'+
                                     '</div>'+
                                     '<div id="lightwindow_data_author_container" >'+
                                         'by <span id="lightwindow_data_author"></span>'+
                                     '</div>'+
                                 '</div>'+
                                 '<div id="lightwindow_data_caption" >'+
                                 '</div>'+
                             '</div>'+
                         '</div>'+
                     '</div>',   
             loading :   '<div id="lightwindow_loading" >'+
                             '<img src="/beta/style/shun/base/base/en/graphic/lightbox/ajax-loading.gif" alt="loading" />'+
                             '<span>Loading.....</span>'+
                             '<iframe name="lightwindow_loading_shim" id="lightwindow_loading_shim" src="javascript:false;" frameBorder="0" scrolling="no"></iframe>'+
                         '</div>',
             iframe :    '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'+
                         '<html xmlns="http://www.w3.org/1999/xhtml">'+
                             '<body>'+
                                 '{body_replace}'+
                             '</body>'+
                         '</html>',
             gallery : {
                 top :       '<div class="lightwindow_galleries_list">'+
                                 '<h1>{gallery_title_replace}</h1>'+
                                 '<ul>',
                 middle :            '<li>'+
                                         '{gallery_link_replace}'+
                                     '</li>',
                 bottom :        '</ul>'+
                             '</div>'
             }
         },
         formMethod : 'get',
         hideFlash : false,
         hideGalleryTab : true,
         showTitleBar : true,
         animationHandler : false,
         navigationHandler : false,
         transitionHandler : false,
         finalAnimationHandler : false,
         formHandler : false,
         galleryAnimationHandler : false,
         showGalleryCount : true,
         isModal : false,
         overlayId : 'lightwindow_overlay'
     }, options || {});
     this.duration = ((11-this.options.resizeSpeed)*0.15);
     this._setupLinks();
     this._getScroll();
     this._getPageDimensions();
     this._browserDimensions();
     this._addLightWindowMarkup(false);
     this._setupDimensions(); 
     this.buildGalleryList();
 },
 //
 //  Activate the lightwindow.
 //
 activate : function(e, link){       
     // Clear out the window Contents
     this._clearWindowContents(true);
         
     // Add back in out loading panel
     this._addLoadingWindowMarkup();

     // Setup the element properties
     this._setupWindowElements(link);
     
     // Setup everything
     this._getScroll();
     this._browserDimensions();
     this._setupDimensions();
     this._toggleTroubleElements('hidden', false);
     this._displayLightWindow('block', 'hidden');
     this._setStatus(true);
     this._monitorKeyboard(true);
     this._prepareIE(true);
     this._loadWindow();
 },
 //
 //  Turn off the window
 //
 deactivate : function(){
     // The window is not active
     this.windowActive = false;
     
     // There is no longer a gallery active
     this.activeGallery = false;
     if (!this.options.hideGalleryTab) {
         this._handleGalleryAnimation(false);
     }
     
     // Kill the animation
     this.animating = false;
     
     // Clear our element
     this.element = null;
     
     // hide the window.
     this._displayLightWindow('none', 'visible');
     
     // Clear out the window Contents
     this._clearWindowContents(false);
     
     // Stop all animation
     var queue = Effect.Queues.get('lightwindowAnimation').each(function(e){e.cancel();});
     
     // Undo the setup
     this._prepareIE(false);
     this._setupDimensions();
     this._toggleTroubleElements('visible', false);  
     this._monitorKeyboard(false);   
 },
 //
 //  Initialize specific window
 //
 createWindow : function(element, attributes) {
     this._processLink($(element));
 },
 //
 //  Open a Window from a hash of attributes
 //
 activateWindow : function(options) {
     this.element = Object.extend({
         href : null,
         title : null,
         author : null,
         caption : null,
         rel : null,
         top : null,
         left : null,
         type : null,
         showImages : null,
         height : null,
         width : null,
         loadingAnimation : null,
         iframeEmbed : null,
         form : null
     }, options || {});
     
     // Set the window type
     this.contentToFetch = this.element.href;
     this.windowType = this.element.type ? this.element.type : this._fileType(this.element.href);    
     
     // Clear out the window Contents
     this._clearWindowContents(true);
         
     // Add back in out loading panel
     this._addLoadingWindowMarkup();
     
     // Setup everything
     this._getScroll();
     this._browserDimensions();
     this._setupDimensions();
     this._toggleTroubleElements('hidden', false);
     this._displayLightWindow('block', 'hidden');
     this._setStatus(true);
     this._monitorKeyboard(true);
     this._prepareIE(true);
     this._loadWindow();
 },
 //
 //  Fire off our Form handler
 //
 submitForm : function(e) {
     if (this.options.formHandler) {
         this.options.formHandler(e);
     } else {
         this._defaultFormHandler(e);
     }
 },
 //
 //  Reload the window with another location
 //
 openWindow : function(element) {
     var element = $(element);

     // The window is active
     this.windowActive = true;
     
     // Clear out the window Contents
     this._clearWindowContents(true);
     
     // Add back in out loading panel
     this._addLoadingWindowMarkup();
     
     // Setup the element properties
     this._setupWindowElements(element);

     this._setStatus(true);
     this._handleTransition();
 },
 //
 //  Navigate the window
 //
 navigateWindow : function(direction) {
     this._handleNavigation(false);
     if (direction == 'previous') {
         this.openWindow(this.navigationObservers.previous);
     } else if (direction == 'next'){ 
         this.openWindow(this.navigationObservers.next);
     }
 },
 //
 //  Build the Gallery List and Load it
 //
 buildGalleryList : function() {
     var output = '';
     var galleryLink;
     for (i in this.galleries) {
         if (typeof this.galleries[i] == 'object') {
             output += (this.options.skin.gallery.top).replace('{gallery_title_replace}', unescape(i));
             for (j in this.galleries[i]) {
                 if (typeof this.galleries[i][j] == 'object') {                      
                     galleryLink = '<a href="#" id="lightwindow_gallery_'+i+'_'+j+'" >'+unescape(j)+'</a>';
                     output += (this.options.skin.gallery.middle).replace('{gallery_link_replace}', galleryLink);
                 }
             }
             output += this.options.skin.gallery.bottom;
         }
     }
     new Insertion.Top('lightwindow_galleries_list', output);
     
     // Attach Events
     for (i in this.galleries) {
         if (typeof this.galleries[i] == 'object') {
             for (j in this.galleries[i]) {
                 if (typeof this.galleries[i][j] == 'object') {
                     Event.observe($('lightwindow_gallery_'+i+'_'+j), 'click', this.openWindow.bind(this, this.galleries[i][j][0]), false);
                     $('lightwindow_gallery_'+i+'_'+j).onclick = function() {return false;}; 
                 }
             }
         }
     }
 },
 setModal : function(isModal) {
 	 // ADDED - to disable overlay deactivation
 	 var overlay = $(this.options.overlayId);
 	 if(isModal) {
 	    if(!this.options.isModal) {
		        overlay.stopObserving('click', this.deactivateHandler, false);
	    	    overlay.onclick = function() {return false;};
	    	    this.options.isModal = true;
 	    }
 	    // do nothing if the window is already modal
 	 } else if(this.options.isModal) {
 	 	this.deactivateHandler = this.deactivate.bindAsEventListener(this); 
 	   	overlay.observe('click', this.deactivateHandler, false);
 	    overlay.onclick = function() {return false;};
 	    this.options.isModal = false;
 	 }
 	 // do nothing modal=false and isModal is false
 },
 // 
 //  Set Links Up
 //
 _setupLinks : function() {
     var links = $$('.'+this.options.classNames.standard);
     links.each(function(link) {
         this._processLink(link);
     }.bind(this));  
 },
 //
 //  Process a Link
 //
 _processLink : function(link) {
     if ((this._fileType(link.getAttribute('href')) == 'image' || this._fileType(link.getAttribute('href')) == 'media')) {
         if (gallery = this._getGalleryInfo(link.rel)) {
             if (!this.galleries[gallery[0]]) {
                 this.galleries[gallery[0]] = new Array();
             }
             if (!this.galleries[gallery[0]][gallery[1]]) {
                 this.galleries[gallery[0]][gallery[1]] = new Array();
             }
             this.galleries[gallery[0]][gallery[1]].push(link);
         }
     }
     
     // Take care of our inline content
     var url = link.getAttribute('href');
     if (url.indexOf('?') > -1) {
         url = url.substring(0, url.indexOf('?'));
     }
     
     var container = url.substring(url.indexOf('#')+1);
     if($(container)) {
         $(container).setStyle({
             display : 'none'
         });
     }
     
     Event.observe(link, 'click', this.activate.bindAsEventListener(this, link), false);
     link.onclick = function() {return false;};      
 },
 //
 //  Setup our actions
 //
 _setupActions : function() {
     var links = $$('#lightwindow_container .'+this.options.classNames.action);
     links.each(function(link) {
         Event.observe(link, 'click', this[link.getAttribute('rel')].bindAsEventListener(this, link), false);
         link.onclick = function() {return false;};
     }.bind(this));
 },
 //
 //  Add the markup to the page.
 //
 _addLightWindowMarkup : function(rebuild) {
     var overlay = Element.extend(document.createElement('div'));
     overlay.setAttribute('id', this.options.overlayId);      
     // FF Mac has a problem with putting Flash above a layer without a 100% opacity background, so we need to use a pre-made
     if (Prototype.Browser.Gecko) {
         overlay.setStyle({
             backgroundImage: 'url('+this.options.overlay.presetImage+')',
             backgroundRepeat: 'repeat',
             height: this.pageDimensions.height+'px'
         });         
     } else {
         overlay.setStyle({
             opacity: this.options.overlay.opacity,
             backgroundImage: 'url('+this.options.overlay.image+')',
             backgroundRepeat: 'repeat',
             height: this.pageDimensions.height+'px'
         });
     }
     
     var lw = document.createElement('div');
     lw.setAttribute('id', 'lightwindow');
     lw.innerHTML = this.options.skin.main;
     
     var body = document.getElementsByTagName('body')[0];
     body.appendChild(overlay);
     body.appendChild(lw);   
             
     if ($('lightwindow_title_bar_close_link')) {
         Event.observe('lightwindow_title_bar_close_link', 'click', this.deactivate.bindAsEventListener(this));
         $('lightwindow_title_bar_close_link').onclick = function() {return false;};
     }
         
     Event.observe($('lightwindow_previous'), 'click', this.navigateWindow.bind(this, 'previous'), false);
     $('lightwindow_previous').onclick = function() {return false;};     
     Event.observe($('lightwindow_next'), 'click', this.navigateWindow.bind(this, 'next'), false);
     $('lightwindow_next').onclick = function() {return false;};

     if (!this.options.hideGalleryTab) {
         Event.observe($('lightwindow_galleries_tab'), 'click', this._handleGalleryAnimation.bind(this, true), false);
         $('lightwindow_galleries_tab').onclick = function() {return false;};
     }
     
     // Because we use position absolute, kill the scroll Wheel on animations
     if (Prototype.Browser.IE) {
         Event.observe(document, 'mousewheel', this._stopScrolling.bindAsEventListener(this), false);
     } else {
         Event.observe(window, 'DOMMouseScroll', this._stopScrolling.bindAsEventListener(this), false);
     }
     // ADDED - to disable overlay deactivation
		if (!this.options.isModal) { 
			this.deactivateHandler = this.deactivate.bindAsEventListener(this);               
	        Event.observe(overlay, 'click', this.deactivateHandler, false);
 	    overlay.onclick = function() {return false;};
 	}
 },
 //
 //  Add loading window markup
 //
 _addLoadingWindowMarkup : function() {
     $('lightwindow_contents').innerHTML += this.options.skin.loading;
 },
 //
 //  Setup the window elements
 //
 _setupWindowElements : function(link) {
     this.element = link;
     this.element.title = null ? '' : link.getAttribute('title');
     this.element.author = null ? '' : link.getAttribute('author');
     this.element.caption = null ? '' : link.getAttribute('caption');
     this.element.rel = null ? '' : link.getAttribute('rel');
     this.element.params = null ? '' : link.getAttribute('params');

     // Set the window type
     this.contentToFetch = this.element.href;
     this.windowType = this._getParameter('lightwindow_type') ? this._getParameter('lightwindow_type') : this._fileType(this.contentToFetch);    
 },
 //
 //  Clear the window contents out
 //
 _clearWindowContents : function(contents) {
     // If there is an iframe, its got to go
     if ($('lightwindow_iframe')) {
         Element.remove($('lightwindow_iframe'));
     }

     // Stop playing an object if its still around
     if ($('lightwindow_media_primary')) {
         try {
             $('lightwindow_media_primary').Stop();
         } catch(e) {}
         Element.remove($('lightwindow_media_primary'));
     }

     // Stop playing an object if its still around       
     if ($('lightwindow_media_secondary')) {
         try {
             $('lightwindow_media_secondary').Stop();
         } catch(e) {}
         Element.remove($('lightwindow_media_secondary'));
     }
     
     this.activeGallery = false;
     this._handleNavigation(this.activeGallery);
     
     if (contents) {
         // Empty the contents
         $('lightwindow_contents').innerHTML = '';
         
         // Reset the scroll bars
         $('lightwindow_contents').setStyle({
             overflow: 'hidden'
         });     
         
         if (!this.windowActive) {
             $('lightwindow_data_slide_inner').setStyle({
                 display: 'none'
             });

             $('lightwindow_title_bar_title').innerHTML = '';
         }

         // Because of browser differences and to maintain flexible captions we need to reset this height at close
         $('lightwindow_data_slide').setStyle({
             height: 'auto'
         });
     }
     
     this.resizeTo.height = null;
     this.resizeTo.width = null;
 },
 //
 //  Set the status of our animation to keep things from getting clunky
 //
 _setStatus : function(status) {
     this.animating = status;
     if (status) {
         Element.show('lightwindow_loading');
     }
     if (!(/MSIE 6./i.test(navigator.userAgent))) {
         this._fixedWindow(status);
     }
 },
 //
 //  Make this window Fixed
 //
 _fixedWindow : function(status) {
     if (status) {
         if (this.windowActive) {
             this._getScroll();
             $('lightwindow').setStyle({
                 position: 'absolute',
                 top: parseFloat($('lightwindow').getStyle('top'))+this.pagePosition.y+'px',
                 left: parseFloat($('lightwindow').getStyle('left'))+this.pagePosition.x+'px'
             });     
         } else {
             $('lightwindow').setStyle({
                 position: 'absolute'
             });                     
         }
     } else {
         if (this.windowActive) {
             this._getScroll();
             $('lightwindow').setStyle({
                 position: 'fixed',
                 top: parseFloat($('lightwindow').getStyle('top'))-this.pagePosition.y+'px',
                 left: parseFloat($('lightwindow').getStyle('left'))-this.pagePosition.x+'px'
             });     
         } else {
             if ($('lightwindow_iframe')) {
                 // Ideally here we would set a 50% value for top and left, but Safari rears it ugly head again and we need to do it by pixels
                 this._browserDimensions();
             }
             $('lightwindow').setStyle({
                 position: 'fixed',
                 top: (parseFloat(this._getParameter('lightwindow_top')) ? parseFloat(this._getParameter('lightwindow_top'))+'px' : this.dimensions.viewport.height/2+'px'),
                 left: (parseFloat(this._getParameter('lightwindow_left')) ? parseFloat(this._getParameter('lightwindow_left'))+'px' : this.dimensions.viewport.width/2+'px')
             });
         }
     }
 },
 //
 //  Prepare the window for IE.
 //
 _prepareIE : function(setup) {
     if (Prototype.Browser.IE) {
         var height, overflowX, overflowY;
         if (setup) { 
             var height = '100%';
         } else {
             var height = 'auto';
         }
         var body = document.getElementsByTagName('body')[0];
         var html = document.getElementsByTagName('html')[0];
         html.style.height = body.style.height = height;
     }
 },
 _stopScrolling : function(e) {
     if (this.animating) {
         if (e.preventDefault) {
             e.preventDefault();
         }
         e.returnValue = false;      
     }
 },
 //
 //  Get the scroll for the page.
 //
 _getScroll : function(){
     if(typeof(window.pageYOffset) == 'number') {
         this.pagePosition.x = window.pageXOffset;
         this.pagePosition.y = window.pageYOffset;
     } else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
         this.pagePosition.x = document.body.scrollLeft;
         this.pagePosition.y = document.body.scrollTop;
     } else if(document.documentElement) {
         this.pagePosition.x = document.documentElement.scrollLeft;
         this.pagePosition.y = document.documentElement.scrollTop;
     }
 },
 //
 //  Reset the scroll.
 //
 _setScroll : function(x, y) {
     document.documentElement.scrollLeft = x; 
     document.documentElement.scrollTop = y; 
 },
 //
 //  Hide Selects from the page because of IE.
 //     We could use iframe shims instead here but why add all the extra markup for one browser when this is much easier and cleaner
 //
 _toggleTroubleElements : function(visibility, content){
     
     if (content) {
         var selects = $('lightwindow_contents').getElementsByTagName('select');
     } else {
         var selects = document.getElementsByTagName('select');
     }
     
     for(var i = 0; i < selects.length; i++) {
         selects[i].style.visibility = visibility;
     }
     
     if (!content) {
         if (this.options.hideFlash){
             var objects = document.getElementsByTagName('object');
             for (i = 0; i != objects.length; i++) {
                 objects[i].style.visibility = visibility;
             }
             var embeds = document.getElementsByTagName('embed');
             for (i = 0; i != embeds.length; i++) {
                 embeds[i].style.visibility = visibility;
             }
         }
         var iframes = document.getElementsByTagName('iframe');
         for (i = 0; i != iframes.length; i++) {
             iframes[i].style.visibility = visibility;
         }
     }
 },
 // 
 //  Get the actual page size
 //
 _getPageDimensions : function() {
     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){ 
         xScroll = document.body.scrollWidth;
         yScroll = document.body.scrollHeight;
     } else { 
         xScroll = document.body.offsetWidth;
         yScroll = document.body.offsetHeight;
     }

     var windowWidth, windowHeight;
     if (self.innerHeight) { 
         windowWidth = self.innerWidth;
         windowHeight = self.innerHeight;
     } else if (document.documentElement && document.documentElement.clientHeight) { 
         windowWidth = document.documentElement.clientWidth;
         windowHeight = document.documentElement.clientHeight;
     } else if (document.body) { 
         windowWidth = document.body.clientWidth;
         windowHeight = document.body.clientHeight;
     }   

     if(yScroll < windowHeight){
         this.pageDimensions.height = windowHeight;
     } else { 
         this.pageDimensions.height = yScroll;
     }

     if(xScroll < windowWidth){  
         this.pageDimensions.width = windowWidth;
     } else {
         this.pageDimensions.width = xScroll;
     }
 },
 //
 //  Display the lightWindow.
 //
 _displayLightWindow : function(display, visibility) {
     $(this.options.overlayId).style.display = $('lightwindow').style.display = $('lightwindow_container').style.display = display;   
     $(this.options.overlayId).style.visibility = $('lightwindow').style.visibility = $('lightwindow_container').style.visibility = visibility;
 },
 //
 //  Setup Dimensions of lightwindow.

 //
 _setupDimensions : function() {

     var originalHeight, originalWidth;
     switch (this.windowType) {
         case 'page' :
             originalHeight = this.options.dimensions.page.height;
             originalWidth = this.options.dimensions.page.width;
             break;

         case 'image' :
             originalHeight = this.options.dimensions.image.height;
             originalWidth = this.options.dimensions.image.width;
             break;
             
         case 'media' :
             originalHeight = this.options.dimensions.media.height;
             originalWidth = this.options.dimensions.media.width;
             break;
         
         case 'external' : 
             originalHeight = this.options.dimensions.external.height;
             originalWidth = this.options.dimensions.external.width;
             break;
             
         case 'inline' :
             originalHeight = this.options.dimensions.inline.height;
             originalWidth = this.options.dimensions.inline.width;
             break;
             
         default :
             originalHeight = this.options.dimensions.page.height;
             originalWidth = this.options.dimensions.page.width;
             break;
             
     }

     var offsetHeight = this._getParameter('lightwindow_top') ? parseFloat(this._getParameter('lightwindow_top'))+this.pagePosition.y : this.dimensions.viewport.height/2+this.pagePosition.y;
     var offsetWidth = this._getParameter('lightwindow_left') ? parseFloat(this._getParameter('lightwindow_left'))+this.pagePosition.x : this.dimensions.viewport.width/2+this.pagePosition.x;
     
     // So if a theme has say shadowed edges, they should be consistant and take care of in the contentOffset
     $('lightwindow').setStyle({
         top: offsetHeight+'px',
         left: offsetWidth+'px'
     });
     
     $('lightwindow_container').setStyle({
         height: originalHeight+'px',
         width: originalWidth+'px',
         left: -(originalWidth/2)+'px',
         top: -(originalHeight/2)+'px'
     });

     $('lightwindow_contents').setStyle({
         height: originalHeight+'px',
         width: originalWidth+'px'
     });
 },
 //
 //  Get the type of file.
 //
 _fileType : function(url) {
     var image = new RegExp("[^\.]\.("+this.options.fileTypes.image.join('|')+")\s*$", "i");
     if (image.test(url)) return 'image';
     if (url.indexOf('#') > -1 && (document.domain == this._getDomain(url))) return 'inline';        
     if (url.indexOf('?') > -1) url = url.substring(0, url.indexOf('?'));
     var type = 'unknown';
     var page = new RegExp("[^\.]\.("+this.options.fileTypes.page.join('|')+")\s*$", "i");
     var media = new RegExp("[^\.]\.("+this.options.fileTypes.media.join('|')+")\s*$", "i");
     if (document.domain != this._getDomain(url)) type = 'external';
     if (media.test(url)) type = 'media';
     if (type == 'external' || type == 'media') return type;
     if (page.test(url) || url.substr((url.length-1), url.length) == '/') type = 'page';
     return type;
 },
 //
 //  Get file Extension
 //
 _fileExtension : function(url) {
     if (url.indexOf('?') > -1) {
         url = url.substring(0, url.indexOf('?'));
     }
     var extenstion = '';
     for (var x = (url.length-1); x > -1; x--) {
         if (url.charAt(x) == '.') {
             return extenstion;
         }
         extenstion = url.charAt(x)+extenstion;
     }
 },
 //
 //  Monitor the keyboard while this lightwindow is up
 //
 _monitorKeyboard : function(status) {
     if (status) document.onkeydown = this._eventKeypress.bind(this); 
     else document.onkeydown = '';
 },
 //
 //  Perform keyboard actions
 //
 _eventKeypress : function(e) {
     if (e == null) {
         var keycode = event.keyCode;
     } else {
         var keycode = e.which;
     }
     
     switch (keycode) { 
         case 27: 
             this.deactivate(); 
             break;
         
         case 13:
             return;
             
         default:
             break;
     }
 
     // Gotta stop those quick fingers
     if (this.animating) {
         return false;
     }
     
     switch (String.fromCharCode(keycode).toLowerCase()) {
         case 'p':
             if (this.navigationObservers.previous) {
                 this.navigateWindow('previous');
             }
             break;
             
         case 'n':
             if (this.navigationObservers.next) {
                 this.navigateWindow('next');
             }
             break;
             
         default:
             break;
     }
 },
 //
 //  Get Gallery Information
 //
 _getGalleryInfo : function(rel) {
     if (!rel) return false;
     if (rel.indexOf('[') > -1) {
         return new Array(escape(rel.substring(0, rel.indexOf('['))), escape(rel.substring(rel.indexOf('[')+1, rel.indexOf(']'))));
     } else {
         return false;
     }
 },
 //
 //  Get the domain from a string.
 //
 _getDomain : function(url) {    
     var leadSlashes = url.indexOf('//');
     var domainStart = leadSlashes+2;
     var withoutResource = url.substring(domainStart, url.length);
     var nextSlash = withoutResource.indexOf('/');
     var domain = withoutResource.substring(0, nextSlash);
     if (domain.indexOf(':') > -1){
         var portColon = domain.indexOf(':');
         domain = domain.substring(0, portColon);
     }
     return domain;
 },
 //
 //  Get the value from the params attribute string.
 //
 _getParameter : function(parameter, parameters) {
     if (!this.element) return false;
     if (parameter == 'lightwindow_top' && this.element.top) {
         return unescape(this.element.top);
     } else if (parameter == 'lightwindow_left' && this.element.left) {
         return unescape(this.element.left);
     } else if (parameter == 'lightwindow_type' && this.element.type) {
         return unescape(this.element.type);
     } else if (parameter == 'lightwindow_show_images' && this.element.showImages) {
         return unescape(this.element.showImages);
     } else if (parameter == 'lightwindow_height' && this.element.height) {
         return unescape(this.element.height);
     } else if (parameter == 'lightwindow_width' && this.element.width) {
         return unescape(this.element.width);
     } else if (parameter == 'lightwindow_loading_animation' && this.element.loadingAnimation) {
         return unescape(this.element.loadingAnimation);
     } else if (parameter == 'lightwindow_iframe_embed' && this.element.iframeEmbed) {
         return unescape(this.element.iframeEmbed);
     } else if (parameter == 'lightwindow_form' && this.element.form) {
         return unescape(this.element.form);
     } else {
         if (!parameters) {
             if (this.element.params) parameters = this.element.params;
             else return;
         }
         var value;
         var parameterArray = parameters.split(',');
         var compareString = parameter+'=';
         var compareLength = compareString.length;
         for (var i = 0; i < parameterArray.length; i++) {
             if (parameterArray[i].substr(0, compareLength) == compareString) {
                 var currentParameter = parameterArray[i].split('=');
                 value = currentParameter[1];
                 break;
             }
         }
         if (!value) return false;
         else return unescape(value);
     }
 },
 //
 //  Get the Browser Viewport Dimensions
 //
 _browserDimensions : function() {
     if (Prototype.Browser.IE) {
         this.dimensions.viewport.height = document.documentElement.clientHeight;
         this.dimensions.viewport.width = document.documentElement.clientWidth;   
     } else {
         this.dimensions.viewport.height = window.innerHeight;
         this.dimensions.viewport.width = document.width || document.body.offsetWidth;
     }
 },
 //
 //  Get the scrollbar offset, I don't like this method but there is really no other way I can find.
 //
 _getScrollerWidth : function() {
     var scrollDiv = Element.extend(document.createElement('div'));
     scrollDiv.setAttribute('id', 'lightwindow_scroll_div');
     scrollDiv.setStyle({
         position: 'absolute',
         top: '-10000px',
         left: '-10000px',
         width: '100px',
         height: '100px',
         overflow: 'hidden'
     });



     var contentDiv = Element.extend(document.createElement('div'));
     contentDiv.setAttribute('id', 'lightwindow_content_scroll_div');
     contentDiv.setStyle({
         width: '100%',
         height: '200px'
     });

     scrollDiv.appendChild(contentDiv);

     var body = document.getElementsByTagName('body')[0];
     body.appendChild(scrollDiv);

     var noScroll = $('lightwindow_content_scroll_div').offsetWidth;
     scrollDiv.style.overflow = 'auto';
     var withScroll = $('lightwindow_content_scroll_div').offsetWidth;

     Element.remove($('lightwindow_scroll_div'));

     this.scrollbarOffset = noScroll-withScroll;
 },
 

 //
 //  Add a param to an object dynamically created
 //
 _addParamToObject : function(name, value, object, id) {
     var param = document.createElement('param');
     param.setAttribute('value', value);
     param.setAttribute('name', name);
     if (id) {
         param.setAttribute('id', id);
     }
     object.appendChild(param);
     return object;
 },
 //
 //  Get the outer HTML of an object CROSS BROWSER
 //
 _outerHTML : function(object) {
     if (Prototype.Browser.IE) {
         return object.outerHTML;
     } else {
         var clone = object.cloneNode(true);
         var cloneDiv = document.createElement('div');
         cloneDiv.appendChild(clone);
         return cloneDiv.innerHTML;
     }
 },
 //
 //  Convert an object to markup
 //
 _convertToMarkup : function(object, closeTag) {
     var markup = this._outerHTML(object).replace('</'+closeTag+'>', '');
     if (Prototype.Browser.IE) {
         for (var i = 0; i < object.childNodes.length; i++){
             markup += this._outerHTML(object.childNodes[i]);
         }
         markup += '</'+closeTag+'>';
     }
     return markup;
 },
 //
 //  Depending what type of browser it is we have to append the object differently... DAMN YOU IE!!
 //
 _appendObject : function(object, closeTag, appendTo) {
     if (Prototype.Browser.IE) {
         appendTo.innerHTML += this._convertToMarkup(object, closeTag);
         
         // Fix the Eolas activate thing but only for specified media, for example doing this to a quicktime film breaks it.
         if (this.options.EOLASFix.indexOf(this._fileType(this.element.href)) > -1) {
             var objectElements = document.getElementsByTagName('object');
             for (var i = 0; i < objectElements.length; i++) {
                 if (objectElements[i].getAttribute("data")) objectElements[i].removeAttribute('data');
                 objectElements[i].outerHTML = objectElements[i].outerHTML;
                 objectElements[i].style.visibility = "visible";
             }
         }
     } else {
         appendTo.appendChild(object);   
     }   
 },
 //
 //  Add in iframe
 //
 _appendIframe : function(scroll) {
     var iframe = document.createElement('iframe');
     iframe.setAttribute('id', 'lightwindow_iframe');
     iframe.setAttribute('name', 'lightwindow_iframe');
     iframe.setAttribute('src', 'about:blank');
     iframe.setAttribute('height', '100%');
     iframe.setAttribute('width', '100%');
     iframe.setAttribute('frameborder', '0');
     iframe.setAttribute('marginwidth', '0');
     iframe.setAttribute('marginheight', '0');
     iframe.setAttribute('scrolling', scroll);   
     
     this._appendObject(iframe, 'iframe', $('lightwindow_contents'));
 },
 //
 //  Write Content to the iframe using the skin
 //
 _writeToIframe : function(content) {
     var template = this.options.skin.iframe;
     template = template.replace('{body_replace}', content); 
     if ($('lightwindow_iframe').contentWindow){
         $('lightwindow_iframe').contentWindow.document.open();
         $('lightwindow_iframe').contentWindow.document.write(template);
         $('lightwindow_iframe').contentWindow.document.close();
     } else {
         $('lightwindow_iframe').contentDocument.open();
         $('lightwindow_iframe').contentDocument.write(template);
         $('lightwindow_iframe').contentDocument.close();
     }
 },
 //
 //  Load the window Information
 //  
 _loadWindow : function() {
     switch (this.windowType) {
         case 'image' :

             var current = 0;
             var images = [];
             this.checkImage = [];
             this.resizeTo.height = this.resizeTo.width = 0;
             this.imageCount = this._getParameter('lightwindow_show_images') ? parseInt(this._getParameter('lightwindow_show_images')) : 1;

             // If there is a gallery get it
             if (gallery = this._getGalleryInfo(this.element.rel)) { 
                 for (current = 0; current < this.galleries[gallery[0]][gallery[1]].length; current++) {
                     if (this.contentToFetch.indexOf(this.galleries[gallery[0]][gallery[1]][current].href) > -1) {
                         break;
                     }
                 }
                 if (this.galleries[gallery[0]][gallery[1]][current-this.imageCount]) {
                     this.navigationObservers.previous = this.galleries[gallery[0]][gallery[1]][current-this.imageCount];
                 } else {
                     this.navigationObservers.previous = false;
                 }
                 if (this.galleries[gallery[0]][gallery[1]][current+this.imageCount]) {
                     this.navigationObservers.next = this.galleries[gallery[0]][gallery[1]][current+this.imageCount];
                 } else {
                     this.navigationObservers.next = false;
                 }
                 
                 this.activeGallery = true;
             } else {
                 this.navigationObservers.previous = false;
                 this.navigationObservers.next = false;                  

                 this.activeGallery = false;
             }
             
             for (var i = current; i < (current+this.imageCount); i++) {
     
                 if (gallery && this.galleries[gallery[0]][gallery[1]][i]) {
                     this.contentToFetch = this.galleries[gallery[0]][gallery[1]][i].href;
                     
                     this.galleryLocation = {current: (i+1)/this.imageCount, total: (this.galleries[gallery[0]][gallery[1]].length)/this.imageCount};
                                         
                     if (!this.galleries[gallery[0]][gallery[1]][i+this.imageCount]) {
                         $('lightwindow_next').setStyle({
                             display: 'none'
                         });
                     } else {
                         $('lightwindow_next').setStyle({
                             display: 'block'
                         });
                         $('lightwindow_next_title').innerHTML = this.galleries[gallery[0]][gallery[1]][i+this.imageCount].title;
                     }
                     
                     if (!this.galleries[gallery[0]][gallery[1]][i-this.imageCount]) {
                         $('lightwindow_previous').setStyle({
                             display: 'none'
                         });
                     } else {
                         $('lightwindow_previous').setStyle({
                             display: 'block'
                         });
                         $('lightwindow_previous_title').innerHTML = this.galleries[gallery[0]][gallery[1]][i-this.imageCount].title;
                     }
                 }

                 images[i] = document.createElement('img');
                 images[i].setAttribute('id', 'lightwindow_image_'+i);
                 images[i].setAttribute('border', '0');
                 images[i].setAttribute('src', this.contentToFetch);
                 $('lightwindow_contents').appendChild(images[i]);

                 // We have to do this instead of .onload 
                 this.checkImage[i] = new PeriodicalExecuter(function(i) {
                     if (!(typeof $('lightwindow_image_'+i).naturalWidth != "undefined" && $('lightwindow_image_'+i).naturalWidth == 0)) {
 
                         this.checkImage[i].stop();
 
                         var imageHeight = $('lightwindow_image_'+i).getHeight();
                         if (imageHeight > this.resizeTo.height) {
                             this.resizeTo.height = imageHeight;
                         }
                         this.resizeTo.width += $('lightwindow_image_'+i).getWidth();
                         this.imageCount--;
 
                         $('lightwindow_image_'+i).setStyle({
                             height: '100%'
                         });
 
                         if (this.imageCount == 0) {
                             this._processWindow();
                         }
                     }
                 
                 }.bind(this, i), 1);            
             }


         break;
     
     case 'media' :          
     
         var current = 0;
         this.resizeTo.height = this.resizeTo.width = 0;

         // If there is a gallery get it
         if (gallery = this._getGalleryInfo(this.element.rel)) { 
             for (current = 0; current < this.galleries[gallery[0]][gallery[1]].length; current++) {
                 if (this.contentToFetch.indexOf(this.galleries[gallery[0]][gallery[1]][current].href) > -1) {
                     break;
                 }
             }
             
             if (this.galleries[gallery[0]][gallery[1]][current-1]) {
                 this.navigationObservers.previous = this.galleries[gallery[0]][gallery[1]][current-1];
             } else {
                 this.navigationObservers.previous = false;
             }
             if (this.galleries[gallery[0]][gallery[1]][current+1]) {
                 this.navigationObservers.next = this.galleries[gallery[0]][gallery[1]][current+1];
             } else {
                 this.navigationObservers.next = false;
             }
     
             this.activeGallery = true;
         } else {
             this.navigationObservers.previous = false;
             this.navigationObservers.next = false;
             
             this.activeGallery = false;
         }
     

         if (gallery && this.galleries[gallery[0]][gallery[1]][current]) {
             this.contentToFetch = this.galleries[gallery[0]][gallery[1]][current].href;

             this.galleryLocation = {current: current+1, total: this.galleries[gallery[0]][gallery[1]].length};
             
             if (!this.galleries[gallery[0]][gallery[1]][current+1]) {
                 $('lightwindow_next').setStyle({
                     display: 'none'
                 });
             } else {
                 $('lightwindow_next').setStyle({
                     display: 'block'
                 });
                 $('lightwindow_next_title').innerHTML = this.galleries[gallery[0]][gallery[1]][current+1].title;
             }
             
             if (!this.galleries[gallery[0]][gallery[1]][current-1]) {
                 $('lightwindow_previous').setStyle({
                     display: 'none'
                 });
             } else {
                 $('lightwindow_previous').setStyle({
                     display: 'block'
                 });
                 $('lightwindow_previous_title').innerHTML = this.galleries[gallery[0]][gallery[1]][current-1].title;
             }
         }
         
         if (this._getParameter('lightwindow_iframe_embed')) {
             this.resizeTo.height = this.dimensions.viewport.height;
             this.resizeTo.width = this.dimensions.viewport.width;   
         } else {
             this.resizeTo.height = this._getParameter('lightwindow_height');
             this.resizeTo.width = this._getParameter('lightwindow_width');              
         }
         
         this._processWindow();
         
         break;

     case 'external' :       

         this._appendIframe('auto');

         this.resizeTo.height = this.dimensions.viewport.height;
         this.resizeTo.width = this.dimensions.viewport.width;
                     
         this._processWindow();

         break;
             
     case 'page' :   
         
         var newAJAX = new Ajax.Request(
             this.contentToFetch, {
                 method: 'get', 
                 parameters: '', 
                 onComplete: function(response) {
                     $('lightwindow_contents').innerHTML += response.responseText;
                     this.resizeTo.height = $('lightwindow_contents').scrollHeight+(this.options.contentOffset.height);
                     this.resizeTo.width = $('lightwindow_contents').scrollWidth+(this.options.contentOffset.width);
                     this._processWindow();
                 }.bind(this)
             }
         );
         
         break;
         
     case 'inline' : 
     
         var content = this.contentToFetch;
         if (content.indexOf('?') > -1) {
             content = content.substring(0, content.indexOf('?'));
         }
         content = content.substring(content.indexOf('#')+1);
         
         new Insertion.Top($('lightwindow_contents'), $(content).innerHTML);
         
         this.resizeTo.height = $('lightwindow_contents').scrollHeight+(this.options.contentOffset.height);
         this.resizeTo.width = $('lightwindow_contents').scrollWidth+(this.options.contentOffset.width);
         
         this._toggleTroubleElements('hidden', true);            
         this._processWindow();
         
         break;
         
     default : 
         throw("Page Type could not be determined, please amend this lightwindow URL "+this.contentToFetch);
         break;
     }
 },
 //
 //  Resize the Window to fit the viewport if necessary
 //
 _resizeWindowToFit : function() {
     if (this.resizeTo.height+this.dimensions.cruft.height > this.dimensions.viewport.height) {
         var heightRatio = this.resizeTo.height/this.resizeTo.width;
         this.resizeTo.height = this.dimensions.viewport.height-this.dimensions.cruft.height-(2*this.options.viewportPadding);
         // We only care about ratio's with this window type         
         if (this.windowType == 'image' || (this.windowType == 'media' && !this._getParameter('lightwindow_iframe_embed'))) {
             this.resizeTo.width = this.resizeTo.height/heightRatio;
             $('lightwindow_data_slide_inner').setStyle({
                 width: this.resizeTo.width+'px'
             });         
         }
     } 
     if (this.resizeTo.width+this.dimensions.cruft.width > this.dimensions.viewport.width) {
         var widthRatio = this.resizeTo.width/this.resizeTo.height;
         this.resizeTo.width = this.dimensions.viewport.width-2*this.dimensions.cruft.width-(2*this.options.viewportPadding);
         // We only care about ratio's with this window type
         if (this.windowType == 'image' || (this.windowType == 'media' && !this._getParameter('lightwindow_iframe_embed'))) {
             this.resizeTo.height = this.resizeTo.width/widthRatio;
             $('lightwindow_data_slide_inner').setStyle({
                 height: this.resizeTo.height+'px'
             });
         }
     }
         
 },
 //
 //  Set the Window to a preset size
 //
 _presetWindowSize : function() {
     if (this._getParameter('lightwindow_height')) {
         this.resizeTo.height = parseFloat(this._getParameter('lightwindow_height'));
     }
     if (this._getParameter('lightwindow_width')) {
         this.resizeTo.width = parseFloat(this._getParameter('lightwindow_width'));
     }
 },
 //
 //  Process the Window
 //
 _processWindow : function() {
     // Clean out our effects
     this.dimensions.dataEffects = [];

     // Set up the data-slide if we have caption information
     if (this.element.caption || this.element.author || (this.activeGallery && this.options.showGalleryCount)) {
         if (this.element.caption) {
             $('lightwindow_data_caption').innerHTML = this.element.caption;
             $('lightwindow_data_caption').setStyle({
                 display: 'block'
             });
         } else {
             $('lightwindow_data_caption').setStyle({
                 display: 'none'
             });             
         }
         if (this.element.author) {
             $('lightwindow_data_author').innerHTML = this.element.author;
             $('lightwindow_data_author_container').setStyle({
                 display: 'block'
             });
         } else {
             $('lightwindow_data_author_container').setStyle({
                 display: 'none'
             });             
         }
         if (this.activeGallery && this.options.showGalleryCount) {
             $('lightwindow_data_gallery_current').innerHTML = this.galleryLocation.current;
             $('lightwindow_data_gallery_total').innerHTML = this.galleryLocation.total;
             $('lightwindow_data_gallery_container').setStyle({
                 display: 'block'
             });
         } else {
             $('lightwindow_data_gallery_container').setStyle({
                 display: 'none'
             });             
         }

         $('lightwindow_data_slide_inner').setStyle({
             width: this.resizeTo.width+'px',
             height: 'auto',
             visibility: 'visible',
             display: 'block'
         });
         $('lightwindow_data_slide').setStyle({
             height: $('lightwindow_data_slide').getHeight()+'px',
             width: '1px',
             overflow: 'hidden',
             display: 'block'
         });
     } else {
         $('lightwindow_data_slide').setStyle({
             display: 'none',
             width: 'auto'
         });
         $('lightwindow_data_slide_inner').setStyle({
             display: 'none',
             visibility: 'hidden',
             width: this.resizeTo.width+'px',
             height: '0px'
         });
     }
             
     if (this.element.title != 'null') {     
         $('lightwindow_title_bar_title').innerHTML = this.element.title;
     } else {
         $('lightwindow_title_bar_title').innerHTML = '';
     }
     
     var originalContainerDimensions = {height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth()};
     // Position the window
     $('lightwindow_container').setStyle({
         height: 'auto',
         // We need to set the width to a px not auto as opera has problems with it
         width: $('lightwindow_container').getWidth()+this.options.contentOffset.width-(this.windowActive ? this.options.contentOffset.width : 0)+'px'
     });
     var newContainerDimensions = {height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth()};
     
     // We need to record the container dimension changes
     this.containerChange = {height: originalContainerDimensions.height-newContainerDimensions.height, width: originalContainerDimensions.width-newContainerDimensions.width};

     // Get out general dimensions
     this.dimensions.container = {height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth()};
     this.dimensions.cruft = {height: this.dimensions.container.height-$('lightwindow_contents').getHeight()+this.options.contentOffset.height, width: this.dimensions.container.width-$('lightwindow_contents').getWidth()+this.options.contentOffset.width};
     
     // Set Sizes if we need too
     this._presetWindowSize();
     this._resizeWindowToFit(); // Even if the window is preset we still don't want it to go outside of the viewport

     if (!this.windowActive) {
         // Position the window
         $('lightwindow_container').setStyle({
             left: -(this.dimensions.container.width/2)+'px',
             top: -(this.dimensions.container.height/2)+'px'
         });
     }
     $('lightwindow_container').setStyle({
         height: this.dimensions.container.height+'px',
         width: this.dimensions.container.width+'px'
     });
     
     // We are ready, lets show this puppy off!
     this._displayLightWindow('block', 'visible');
     this._animateLightWindow();
 },
 //
 //  Fire off our animation handler
 //
 _animateLightWindow : function() {
     if (this.options.animationHandler) {
         this.options.animationHandler().bind(this);
     } else {
         this._defaultAnimationHandler();
     }
 },
 //
 //  Fire off our transition handler
 //
 _handleNavigation : function(display) {
     if (this.options.navigationHandler) {
         this.options.navigationHandler().bind(this, display);
     } else {
         this._defaultDisplayNavigation(display);
     }
 },
 //
 //  Fire off our transition handler
 //
 _handleTransition : function() {
     if (this.options.transitionHandler) {
         this.options.transitionHandler().bind(this);
     } else {
         this._defaultTransitionHandler();
     }
 },
 //
 //  Handle the finish of the window animation
 // 
 _handleFinalWindowAnimation : function(delay) {
     if (this.options.finalAnimationHandler) {
         this.options.finalAnimationHandler().bind(this, delay);
     } else {
         this._defaultfinalWindowAnimationHandler(delay);
     }       
 },
 //
 //  Handle the gallery Animation
 // 
 _handleGalleryAnimation : function(list) {
     if (this.options.galleryAnimationHandler) {
         this.options.galleryAnimationHandler().bind(this, list);
     } else {
         this._defaultGalleryAnimationHandler(list);
     }       
 },
 //
 //  Display the navigation 
 //
 _defaultDisplayNavigation : function(display) {
     if (display) {
         $('lightwindow_navigation').setStyle({
             display: 'block',
             height: $('lightwindow_contents').getHeight()+'px',
             width: '100%',
             marginTop: this.options.dimensions.titleHeight+'px'
         });         
     } else {
         $('lightwindow_navigation').setStyle({
             display: 'none',
             height: 'auto',
             width: 'auto'
         });         
     }
 },
 //
 //  This is the default animation handler for LightWindow
 //
 _defaultAnimationHandler : function() { 
     // Now that we have figures out the cruft lets make the caption go away and add its effects
     if (this.element.caption || this.element.author || (this.activeGallery && this.options.showGalleryCount)) {
         $('lightwindow_data_slide').setStyle({
             display: 'none',
             width: 'auto'
         });
         this.dimensions.dataEffects.push(
             new Effect.SlideDown('lightwindow_data_slide', {sync: true}),
             new Effect.Appear('lightwindow_data_slide', {sync: true, from: 0.0, to: 1.0})
         );
     }

     // Set up the Title if we have one
     $('lightwindow_title_bar_inner').setStyle({
         height: '0px',
         marginTop: this.options.dimensions.titleHeight+'px'
     });
     
     // We always want the title bar as well
     this.dimensions.dataEffects.push(
         new Effect.Morph('lightwindow_title_bar_inner', {sync: true, style: {height: this.options.dimensions.titleHeight+'px', marginTop: '0px'}}),
         new Effect.Appear('lightwindow_title_bar_inner', {sync: true, from: 0.0, to: 1.0})
     );      
     
     if (!this.options.hideGalleryTab) {
         this._handleGalleryAnimation(false);
         if ($('lightwindow_galleries_tab_container').getHeight() == 0) {
             this.dimensions.dataEffects.push(
                 new Effect.Morph('lightwindow_galleries_tab_container', {sync: true, style: {height: '20px', marginTop: '0px'}})
             );
             $('lightwindow_galleries').setStyle({
                 width: '0px'
             });
         }
     }
     
     var resized = false;
     var ratio = this.dimensions.container.width-$('lightwindow_contents').getWidth()+this.resizeTo.width+this.options.contentOffset.width;
     if (ratio != $('lightwindow_container').getWidth()) {
         new Effect.Parallel([
                 new Effect.Scale('lightwindow_contents', 100*(this.resizeTo.width/$('lightwindow_contents').getWidth()), {scaleFrom: 100*($('lightwindow_contents').getWidth()/($('lightwindow_contents').getWidth()+(this.options.contentOffset.width))), sync: true,  scaleY: false, scaleContent: false}),
                 new Effect.Scale('lightwindow_container', 100*(ratio/(this.dimensions.container.width)), {sync: true, scaleY: false, scaleFromCenter: true, scaleContent: false})
             ], {
                 duration: this.duration, 
                 delay: 0.25,
                 queue: {position: 'end', scope: 'lightwindowAnimation'}
             }
         );      
     }
     
     ratio = this.dimensions.container.height-$('lightwindow_contents').getHeight()+this.resizeTo.height+this.options.contentOffset.height;
     if (ratio != $('lightwindow_container').getHeight()) {
         new Effect.Parallel([
                 new Effect.Scale('lightwindow_contents', 100*(this.resizeTo.height/$('lightwindow_contents').getHeight()), {scaleFrom: 100*($('lightwindow_contents').getHeight()/($('lightwindow_contents').getHeight()+(this.options.contentOffset.height))), sync: true, scaleX: false, scaleContent: false}),
                 new Effect.Scale('lightwindow_container', 100*(ratio/(this.dimensions.container.height)), {sync: true, scaleX: false, scaleFromCenter: true, scaleContent: false})
             ], {
                 duration: this.duration, 
                 afterFinish: function() {               
                     if (this.dimensions.dataEffects.length > 0) {
                         if (!this.options.hideGalleryTab) {
                             $('lightwindow_galleries').setStyle({
                                 width: this.resizeTo.width+'px'
                             });
                         }
                         new Effect.Parallel(this.dimensions.dataEffects, {
                                 duration: this.duration,
                                 afterFinish: function() {
                                     this._finishWindow();
                                 }.bind(this),
                                 queue: {position: 'end', scope: 'lightwindowAnimation'} 
                             }
                         );
                     }
                 }.bind(this), 
                 queue: {position: 'end', scope: 'lightwindowAnimation'} 
             }
         );
         resized = true;
     }
     
     // We need to do our data effect since there was no resizing
     if (!resized && this.dimensions.dataEffects.length > 0) {   
         new Effect.Parallel(this.dimensions.dataEffects, {
                 duration: this.duration,
                 beforeStart: function() {
                     if (!this.options.hideGalleryTab) {
                         $('lightwindow_galleries').setStyle({
                             width: this.resizeTo.width+'px'
                         });
                     }
                     if (this.containerChange.height != 0 || this.containerChange.width != 0) {
                         new Effect.MoveBy('lightwindow_container', this.containerChange.height, this.containerChange.width, {transition: Effect.Transitions.sinoidal});
                     }
                 }.bind(this),           
                 afterFinish: function() {
                     this._finishWindow();
                 }.bind(this),
                 queue: {position: 'end', scope: 'lightwindowAnimation'} 
             }
         );
     }           
     
 },
 //
 //  Finish up Window Animation
 //
 _defaultfinalWindowAnimationHandler : function(delay) {
     if (this.windowType == 'media' || this._getParameter('lightwindow_loading_animation')) {    
         // Because of major flickering with the overlay we just hide it in this case
         Element.hide('lightwindow_loading');
         this._handleNavigation(this.activeGallery);
         this._setStatus(false);
     } else {
         Effect.Fade('lightwindow_loading', {
             duration: 0.75,
             delay: 1.0, 
             afterFinish: function() {
                 // Just in case we need some scroll goodness (this also avoids the swiss cheese effect)
                 if (this.windowType != 'image' && this.windowType != 'media' && this.windowType != 'external') {
                     $('lightwindow_contents').setStyle({
                         overflow: 'auto'
                     });
                 }
                 this._handleNavigation(this.activeGallery);
                 this._defaultGalleryAnimationHandler();
                 this._setStatus(false);
             }.bind(this),
             queue: {position: 'end', scope: 'lightwindowAnimation'}
         });
     }
 },
 //
 //  Handle the gallery Animation
 //
 _defaultGalleryAnimationHandler : function(list) {
     if (this.activeGallery) {
         $('lightwindow_galleries').setStyle({
             display: 'block',
             marginBottom: $('lightwindow_data_slide').getHeight()+this.options.contentOffset.height/2+'px'
         });
         $('lightwindow_navigation').setStyle({
             height: $('lightwindow_contents').getHeight()-20+'px'
         });
     } else {
         $('lightwindow_galleries').setStyle({
             display: 'none'
         }); 
         $('lightwindow_galleries_tab_container').setStyle({
             height: '0px',
             marginTop: '20px'
         });
         $('lightwindow_galleries_list').setStyle({
             height: '0px'
         });
         return false;
     }
     
     if (list) {
         if ($('lightwindow_galleries_list').getHeight() == 0) {
             var height = $('lightwindow_contents').getHeight()*0.80;
             $('lightwindow_galleries_tab_span').className = 'down';
         } else {
             var height = 0;
             $('lightwindow_galleries_tab_span').className = 'up';
         }

         new Effect.Morph('lightwindow_galleries_list', {
             duration: this.duration,
             transition: Effect.Transitions.sinoidal,
             style: {height: height+'px'},
             beforeStart: function() {
                 $('lightwindow_galleries_list').setStyle({
                     overflow: 'hidden'
                 });                 
             },
             afterFinish: function() {
                 $('lightwindow_galleries_list').setStyle({
                     overflow: 'auto'
                 });
             },
             queue: {position: 'end', scope: 'lightwindowAnimation'}
         }); 
     }
     
     
 },
 //
 //  Default Transition Handler
 //
 _defaultTransitionHandler : function() {
     // Clean out our effects
     this.dimensions.dataEffects = [];

     // Now that we have figures out the cruft lets make the caption go away and add its effects
     if ($('lightwindow_data_slide').getStyle('display') != 'none') {
         this.dimensions.dataEffects.push(
             new Effect.SlideUp('lightwindow_data_slide', {sync: true}),
             new Effect.Fade('lightwindow_data_slide', {sync: true, from: 1.0, to: 0.0})
         );
     }
     
     if (!this.options.hideGalleryTab) {
         if ($('lightwindow_galleries').getHeight() != 0 && !this.options.hideGalleryTab) {
             this.dimensions.dataEffects.push(
                 new Effect.Morph('lightwindow_galleries_tab_container', {sync: true, style: {height: '0px', marginTop: '20px'}})
             );
         }
         
         if ($('lightwindow_galleries_list').getHeight() != 0) {
             $('lightwindow_galleries_tab_span').className = 'up';
             this.dimensions.dataEffects.push(
                 new Effect.Morph('lightwindow_galleries_list', {
                     sync: true, 
                     style: {height: '0px'},
                     transition: Effect.Transitions.sinoidal,
                     beforeStart: function() {
                         $('lightwindow_galleries_list').setStyle({
                             overflow: 'hidden'
                         });                 
                     },
                     afterFinish: function() {
                         $('lightwindow_galleries_list').setStyle({
                             overflow: 'auto'
                         });
                     }
                 })
             );
         }
     }
     
     // We always want the title bar as well
     this.dimensions.dataEffects.push(
         new Effect.Morph('lightwindow_title_bar_inner', {sync: true, style: {height: '0px', marginTop: this.options.dimensions.titleHeight+'px'}}),
         new Effect.Fade('lightwindow_title_bar_inner', {sync: true, from: 1.0, to: 0.0})
     );

     new Effect.Parallel(this.dimensions.dataEffects, {
             duration: this.duration,
             afterFinish: function() {
                 this._loadWindow();
             }.bind(this),
             queue: {position: 'end', scope: 'lightwindowAnimation'} 
         }
     );  
 },
 //
 //  Default Form handler for LightWindow
 //
 _defaultFormHandler : function(e) {
     var element = Event.element(e).parentNode;
     var parameterString = Form.serialize(this._getParameter('lightwindow_form', element.getAttribute('params')));
     if (this.options.formMethod == 'post') {
         var newAJAX = new Ajax.Request(element.href, { 
             method: 'post', 
             postBody: parameterString, 
             onComplete: this.openWindow.bind(this, element)
         });
     } else if (this.options.formMethod == 'get') {
         var newAJAX = new Ajax.Request(element.href, { 
             method: 'get', 
             parameters: parameterString, 
             onComplete: this.openWindow.bind(this, element)
         });
     }
 },
 // 
 //  Wrap everything up
 //
 _finishWindow : function() {
     if (this.windowType == 'external') {
         // We set the externals source here because it allows for a much smoother animation
         $('lightwindow_iframe').setAttribute('src', this.element.href);
         this._handleFinalWindowAnimation(1);    
     } else if (this.windowType == 'media') {

         var outerObject = document.createElement('object');
         outerObject.setAttribute('classid', this.options.classids[this._fileExtension(this.contentToFetch)]);
         outerObject.setAttribute('codebase', this.options.codebases[this._fileExtension(this.contentToFetch)]);
         outerObject.setAttribute('id', 'lightwindow_media_primary');
         outerObject.setAttribute('name', 'lightwindow_media_primary');
         outerObject.setAttribute('width', this.resizeTo.width);
         outerObject.setAttribute('height', this.resizeTo.height);
         outerObject = this._addParamToObject('movie', this.contentToFetch, outerObject);
         outerObject = this._addParamToObject('src', this.contentToFetch, outerObject);
         outerObject = this._addParamToObject('controller', 'true', outerObject);
         outerObject = this._addParamToObject('wmode', 'transparent', outerObject);
         outerObject = this._addParamToObject('cache', 'false', outerObject);
         outerObject = this._addParamToObject('quality', 'high', outerObject);

         if (!Prototype.Browser.IE) {
             var innerObject = document.createElement('object');
             innerObject.setAttribute('type', this.options.mimeTypes[this._fileExtension(this.contentToFetch)]);
             innerObject.setAttribute('data', this.contentToFetch);
             innerObject.setAttribute('id', 'lightwindow_media_secondary');
             innerObject.setAttribute('name', 'lightwindow_media_secondary');
             innerObject.setAttribute('width', this.resizeTo.width);
             innerObject.setAttribute('height', this.resizeTo.height);
             innerObject = this._addParamToObject('controller', 'true', innerObject);
             innerObject = this._addParamToObject('wmode', 'transparent', innerObject);
             innerObject = this._addParamToObject('cache', 'false', innerObject);
             innerObject = this._addParamToObject('quality', 'high', innerObject);
         
             outerObject.appendChild(innerObject);
         }   
         
         if (this._getParameter('lightwindow_iframe_embed')) {
             this._appendIframe('no');
             this._writeToIframe(this._convertToMarkup(outerObject, 'object'));
         } else {
             this._appendObject(outerObject, 'object', $('lightwindow_contents'));
         }

         this._handleFinalWindowAnimation(0);
     } else {
         this._handleFinalWindowAnimation(0);
     }

     // Initialize any actions
     this._setupActions();
 }
}

/*-----------------------------------------------------------------------------------------------*/

Event.observe(window, 'load', lightwindowInit, false);

//
//Set up all of our links
//
var myLightWindow = null;
/** added **/
var enableLW = false;
function lightwindowInit() {
	if(enableLW) {
 	myLightWindow = new lightwindow();
 }
}
function enableLightWindow() {
	enableLW = true;
}

//==============================
//END ./scriptaculous/plugin/lightWindow.js
//==============================
//==============================
//depends on thirdparty.js
//==============================
//==============================
//BEGIN css_browser_selector.js
//==============================
//CSS Browser Selector v0.3.1
//Rafael Lima (http://rafael.adm.br)
function css_browser_selector(u){var ua = u.toLowerCase(),is=function(t){return ua.indexOf(t)>-1;},g='gecko',w='webkit',s='safari',h=document.getElementsByTagName('html')[0],b=[(!(/opera|webtv/i.test(ua))&&/msie\s(\d)/.test(ua))?('ie ie'+RegExp.$1):is('firefox/2')?g+' ff2':is('firefox/3')?g+' ff3':is('gecko/')?g:/opera(\s|\/)(\d+)/.test(ua)?'opera opera'+RegExp.$2:is('konqueror')?'konqueror':is('chrome')?w+' '+s+' chrome':is('applewebkit/')?w+' '+s+(/version\/(\d+)/.test(ua)?' '+s+RegExp.$1:''):is('mozilla/')?g:'',is('j2me')?'mobile':is('iphone')?'iphone':is('ipod')?'ipod':is('mac')?'mac':is('darwin')?'mac':is('webtv')?'webtv':is('win')?'win':is('freebsd')?'freebsd':(is('x11')||is('linux'))?'linux':'','js']; c = b.join(' '); h.className += ' '+c; return c;}; css_browser_selector(navigator.userAgent);
//==============================
//END css_browser_selector.js
//==============================
//==============================
//BEGIN ./util/detect.js
//==============================
var sUserAgent = navigator.userAgent;
var fAppVersion = parseFloat(navigator.appVersion);

function compareVersions(sVersion1, sVersion2) {

 var aVersion1 = sVersion1.split(".");
 var aVersion2 = sVersion2.split(".");
 
 if (aVersion1.length > aVersion2.length) {
     for (var i=0; i < aVersion1.length - aVersion2.length; i++) {
         aVersion2.push("0");
     }
 } else if (aVersion1.length < aVersion2.length) {
     for (var i=0; i < aVersion2.length - aVersion1.length; i++) {
         aVersion1.push("0");
     }    
 }
 
 for (var i=0; i < aVersion1.length; i++) {

     if (aVersion1[i] < aVersion2[i]) {
         return -1;
     } else if (aVersion1[i] > aVersion2[i]) {
         return 1;
     }    
 }
 
 return 0;

}

var isOpera = sUserAgent.indexOf("Opera") > -1;
var isMinOpera4 = isMinOpera5 = isMinOpera6 = isMinOpera7 = isMinOpera7_5 = isMinOpera964 = false;

if (isOpera) {
 var fOperaVersion;
 if(navigator.appName == "Opera") {
     fOperaVersion = fAppVersion;
 } else {
     var reOperaVersion = new RegExp("Opera (\\d+\\.\\d+)");
     reOperaVersion.test(sUserAgent);
     fOperaVersion = parseFloat(RegExp["$1"]);
 }

 isMinOpera4 = fOperaVersion >= 4;
 isMinOpera5 = fOperaVersion >= 5;
 isMinOpera6 = fOperaVersion >= 6;
 isMinOpera7 = fOperaVersion >= 7;
 isMinOpera7_5 = fOperaVersion >= 7.5;
 isMinOpera964 = fOperaVersion >= 9.64;
}

var isKHTML = sUserAgent.indexOf("KHTML") > -1 
           || sUserAgent.indexOf("Konqueror") > -1 
           || sUserAgent.indexOf("AppleWebKit") > -1; 
           
var isMinSafari1 = isMinSafari1_2 = false;
var isMinKonq2_2 = isMinKonq3 = isMinKonq3_1 = isMinKonq3_2 = false;

if (isKHTML) {
 isSafari = sUserAgent.indexOf("AppleWebKit") > -1;
 isKonq = sUserAgent.indexOf("Konqueror") > -1;

 if (isSafari) {
     var reAppleWebKit = new RegExp("AppleWebKit\\/(\\d+(?:\\.\\d*)?)");
     reAppleWebKit.test(sUserAgent);
     var fAppleWebKitVersion = parseFloat(RegExp["$1"]);

     isMinSafari1 = fAppleWebKitVersion >= 85;
     isMinSafari1_2 = fAppleWebKitVersion >= 124;
 } else if (isKonq) {

     var reKonq = new RegExp("Konqueror\\/(\\d+(?:\\.\\d+(?:\\.\\d)?)?)");
     reKonq.test(sUserAgent);
     isMinKonq2_2 = compareVersions(RegExp["$1"], "2.2") >= 0;
     isMinKonq3 = compareVersions(RegExp["$1"], "3.0") >= 0;
     isMinKonq3_1 = compareVersions(RegExp["$1"], "3.1") >= 0;
     isMinKonq3_2 = compareVersions(RegExp["$1"], "3.2") >= 0;
 } 
 
}

var isIE = sUserAgent.indexOf("compatible") > -1 
        && sUserAgent.indexOf("MSIE") > -1
        && !isOpera;
        
var isMinIE4 = isMinIE5 = isMinIE5_5 = isMinIE6 = isMinIE7 = isMinIE8 = false;

if (isIE) {
 var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
 reIE.test(sUserAgent);
 var fIEVersion = parseFloat(RegExp["$1"]);

 isMinIE4 = fIEVersion >= 4;
 isMinIE5 = fIEVersion >= 5;
 isMinIE5_5 = fIEVersion >= 5.5;
 isMinIE6 = fIEVersion >= 6.0;
 isMaxIE6 = fIEVersion <= 6.0;
 isMinIE7 = fIEVersion >= 7.0;
	isMinIE8 = fIEVersion >= 8.0
}

var isMoz = sUserAgent.indexOf("Gecko") > -1
         && !isKHTML;

var isMinMoz1 = sMinMoz1_4 = isMinMoz1_5 = isMinMoz2 = false;

if (isMoz) {
 var reMoz = new RegExp("rv:(\\d+\\.\\d+(?:\\.\\d+)?)");
 reMoz.test(sUserAgent);
 isMinMoz1 = compareVersions(RegExp["$1"], "1.0") >= 0;
 isMinMoz1_4 = compareVersions(RegExp["$1"], "1.4") >= 0;
 isMinMoz1_5 = compareVersions(RegExp["$1"], "1.5") >= 0;
	isMinMoz2 = fAppVersion >= 2.0;
}

var isNS4 = !isIE && !isOpera && !isMoz && !isKHTML 
         && (sUserAgent.indexOf("Mozilla") == 0) 
         && (navigator.appName == "Netscape") 
         && (fAppVersion >= 4.0 && fAppVersion < 5.0);

var isMinNS4 = isMinNS4_5 = isMinNS4_7 = isMinNS4_8 = false;

if (isNS4) {
 isMinNS4 = true;
 isMinNS4_5 = fAppVersion >= 4.5;
 isMinNS4_7 = fAppVersion >= 4.7;
 isMinNS4_8 = fAppVersion >= 4.8;
}

var isWin = (navigator.platform == "Win32") || (navigator.platform == "Windows");
var isMac = (navigator.platform == "Mac68K") || (navigator.platform == "MacPPC") 
         || (navigator.platform == "Macintosh");

var isUnix = (navigator.platform == "X11") && !isWin && !isMac;

var isWin95 = isWin98 = isWinNT4 = isWin2K = isWinME = isWinXP = false;
var isMac68K = isMacPPC = false;
var isSunOS = isMinSunOS4 = isMinSunOS5 = isMinSunOS5_5 = false;

if (isWin) {
 isWin95 = sUserAgent.indexOf("Win95") > -1 
           || sUserAgent.indexOf("Windows 95") > -1;
 isWin98 = sUserAgent.indexOf("Win98") > -1 
           || sUserAgent.indexOf("Windows 98") > -1;
 isWinME = sUserAgent.indexOf("Win 9x 4.90") > -1 
           || sUserAgent.indexOf("Windows ME") > -1;
 isWin2K = sUserAgent.indexOf("Windows NT 5.0") > -1 
           || sUserAgent.indexOf("Windows 2000") > -1;
 isWinXP = sUserAgent.indexOf("Windows NT 5.1") > -1 
           || sUserAgent.indexOf("Windows XP") > -1;
 isWinNT4 = sUserAgent.indexOf("WinNT") > -1 
           || sUserAgent.indexOf("Windows NT") > -1 
           || sUserAgent.indexOf("WinNT4.0") > -1 
           || sUserAgent.indexOf("Windows NT 4.0") > -1 
           && (!isWinME && !isWin2K && !isWinXP);
} 

if (isMac) {
 isMac68K = sUserAgent.indexOf("Mac_68000") > -1 
            || sUserAgent.indexOf("68K") > -1;
 isMacPPC = sUserAgent.indexOf("Mac_PowerPC") > -1 
            || sUserAgent.indexOf("PPC") > -1;  
}

if (isUnix) {
 isSunOS = sUserAgent.indexOf("SunOS") > -1;

 if (isSunOS) {
     var reSunOS = new RegExp("SunOS (\\d+\\.\\d+(?:\\.\\d+)?)");
     reSunOS.test(sUserAgent);
     isMinSunOS4 = compareVersions(RegExp["$1"], "4.0") >= 0;
     isMinSunOS5 = compareVersions(RegExp["$1"], "5.0") >= 0;
     isMinSunOS5_5 = compareVersions(RegExp["$1"], "5.5") >= 0;
 }
}
//==============================
//END ./util/detect.js
//==============================
//==============================
//BEGIN ./util/eventutil.js
//==============================
var EventUtil = new Object;
EventUtil.addEventHandler = function (oTarget, sEventType, fnHandler) {
 if (oTarget.addEventListener) {
     oTarget.addEventListener(sEventType, fnHandler, false);
 } else if (oTarget.attachEvent) {
     oTarget.attachEvent("on" + sEventType, fnHandler);
 } else {
     oTarget["on" + sEventType] = fnHandler;
 }
};
     
EventUtil.removeEventHandler = function (oTarget, sEventType, fnHandler) {
 if (oTarget.removeEventListener) {
     oTarget.removeEventListener(sEventType, fnHandler, false);
 } else if (oTarget.detachEvent) {
     oTarget.detachEvent("on" + sEventType, fnHandler);
 } else { 
     oTarget["on" + sEventType] = null;
 }
};

EventUtil.formatEvent = function (oEvent) {
 if (isIE && isWin) {
     oEvent.charCode = (oEvent.type == "keypress") ? oEvent.keyCode : 0;
     oEvent.eventPhase = 2;
     oEvent.isChar = (oEvent.charCode > 0);
     oEvent.pageX = oEvent.clientX + document.body.scrollLeft;
     oEvent.pageY = oEvent.clientY + document.body.scrollTop;
     oEvent.preventDefault = function () {
         this.returnValue = false;
     };

     if (oEvent.type == "mouseout") {
         oEvent.relatedTarget = oEvent.toElement;
     } else if (oEvent.type == "mouseover") {
         oEvent.relatedTarget = oEvent.fromElement;
     }

     oEvent.stopPropagation = function () {
         this.cancelBubble = true;
     };

     oEvent.target = oEvent.srcElement;
     oEvent.time = (new Date).getTime();
 }
 return oEvent;
};

EventUtil.getEvent = function() {
 if (window.event) {
     return this.formatEvent(window.event);
 } else {
     return EventUtil.getEvent.caller.arguments[0];
 }
};
//==============================
//END ./util/eventutil.js
//==============================
//==============================
//BEGIN ./util/misc.js
//==============================
//getViewportHeight = function() {
//var height = 0;
//if( document.documentElement && document.documentElement.clientHeight ) {
//  height = document.documentElement.clientHeight;
//}
//else if( document.body && document.body.clientHeight ) {
//  height = document.body.clientHeight;
//}
//else if( self.innerHeight ) {
// height = self.innerHeight;
//}
//else if( window.innerHeight ) {
//  height = window.innerHeight - 18;
//}
//alert(height);
//return height;
//};

//From dom.js in YUI 2.2.2
function getViewportHeight() {
var height = self.innerHeight; // Safari, Opera
var mode = document.compatMode;

if ( (mode || isIE) && !isOpera ) { // IE, Gecko
 height = (mode == 'CSS1Compat') ?
   document.documentElement.clientHeight : // Standards
   document.body.clientHeight; // Quirks
}
// alert(height);

return height;
}

function setFooterHeight() {
var containerHeight = $('container').getDimensions().height;
var footerHeight = $('footer-wrapper').getDimensions().height;
var viewportHeight = getViewportHeight();
var viewOffset = viewportHeight - containerHeight;
var footerOffset = footerHeight + viewOffset;
if(viewportHeight > containerHeight) {
 $('footer-wrapper').style.height = footerOffset + 'px';
};
return false;
};

function language_change(languages_form){
 var URL = document.languages_form.newlang.options[document.languages_form.newlang.selectedIndex].value;
 window.location.href = URL;
 window.reload;
}

function createCookie(name,value,days) {
     if (days) {
         var date = new Date();
         date.setTime(date.getTime()+(days*24*60*60*1000));
         var expires = "; expires="+date.toGMTString();
     }
     else var expires = "";
     document.cookie = name+"="+value+expires+"; path=/";
 }

function readCookie(name) {
 var nameEQ = name + "=";
 var ca = document.cookie.split(';');
 for(var i=0;i < ca.length;i++) {
     var c = ca[i];
     while (c.charAt(0)==' ') c = c.substring(1,c.length);
     if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
 }
 return null;
}

function eraseCookie(name) {
 createCookie(name,"",-1);
}

function setFlashPlayerVisibility(visibility) {
 var flashContents = $$('.flash_content');
 
 // if flash players exists, we need to hide it because flash is rendered above everything
 if (flashContents!=null) {
     for(var i = 0; i < flashContents.length; i++) {
         flashContents[i].style.visibility = visibility;
     }
 }
}

function browserIsSupported(){
	if(isMinIE6 
		|| isMinMoz2 
		|| BrowserDetect.browser == "Safari" 
		|| BrowserDetect.browser == "Chrome" 
		|| isMinOpera964)
	{
		return true;
	} else {
		return false;
	}
}
//==============================
//END ./util/misc.js
//==============================
//==============================
//BEGIN ./util/textutil.js
//==============================
var TextUtil = new Object;

TextUtil.isNotMax = function(oTextArea, oEvent) {
 var sChar = String.fromCharCode(oEvent.charCode);
 return (oTextArea.value.length <= oTextArea.getAttribute("maxlength") && 
        !(oEvent.ctrlKey && sChar == "v")) || oEvent.charCode == 0;
};

TextUtil.blockChars = function (oTextbox, oEvent, bBlockPaste) {

 oEvent = EventUtil.formatEvent(oEvent);
      
 var sInvalidChars = oTextbox.getAttribute("invalidchars");
 var sChar = String.fromCharCode(oEvent.charCode);
 
 var bIsValidChar = sInvalidChars.indexOf(sChar) == -1;
    
 if (bBlockPaste) {
     return bIsValidChar && !(oEvent.ctrlKey && sChar == "v");
 } else {
     return bIsValidChar || oEvent.ctrlKey;
 }
};

TextUtil.allowChars = function (oTextbox, oEvent, bBlockPaste) {

 oEvent = EventUtil.formatEvent(oEvent);
      
 var sValidChars = oTextbox.getAttribute("validchars");
 var sChar = String.fromCharCode(oEvent.charCode);
 
 var bIsValidChar = sValidChars.indexOf(sChar) > -1;
 
 if (bBlockPaste) {
     return bIsValidChar && !(oEvent.ctrlKey && sChar == "v");
 } else {
     return bIsValidChar || oEvent.ctrlKey;
 }
};

TextUtil.blurBlock = function(oTextbox) {

 //get the invalid characters
 var sInvalidChars = oTextbox.getAttribute("invalidchars");

 //split the invalid characters into a character array
 var arrInvalidChars = sInvalidChars.split("");
 
 //iterate through the characters
 for (var i=0; i< arrInvalidChars.length; i++){
     if (oTextbox.value.indexOf(arrInvalidChars[i]) > -1) {
         alert("Character '" + arrInvalidChars[i] + "' not allowed.");
         oTextbox.focus();
         oTextbox.select();
         return;
     }
 }    
};


TextUtil.blurAllow = function(oTextbox) {
 //get the valid characters
 var sValidChars = oTextbox.getAttribute("validchars");
 
 //split the textbox value string into a character array
 var arrTextChars = oTextbox.value.split("");

 //iterate through the characters
 for (var i=0; i< arrTextChars.length; i++){
     if (sValidChars.indexOf(arrTextChars[i]) == -1) {
          alert("Character '" + arrTextChars[i] + "' not allowed.");
          oTextbox.focus();
          oTextbox.select();
          return;
     }
 }
};    

TextUtil.numericScroll = function (oTextbox, oEvent) {

 oEvent = EventUtil.formatEvent(oEvent);
 var iValue = oTextbox.value.length == 0 ? 0 :parseInt(oTextbox.value);
 
 var iMax = oTextbox.getAttribute("max");
 var iMin = oTextbox.getAttribute("min");

 if (oEvent.keyCode == 38) {
     if (iMax == null || iValue < iMax) {
         oTextbox.value = (iValue + 1);
     }
 } else if (oEvent.keyCode == 40){
     if (iMin == null || iValue > iMin) {
         oTextbox.value = (iValue - 1);
     }
 }
};

TextUtil.autosuggestMatch = function (sText, arrValues) {

 var arrResult = new Array;

 if (sText != "") {
     for (var i=0; i < arrValues.length; i++) {
         if (arrValues[i].indexOf(sText) == 0) {
             arrResult.push(arrValues[i]);
         }
     }
 }

return arrResult;

};

TextUtil.autosuggest = function (oTextbox, arrValues, sListboxId) {
 
 var oListbox = document.getElementById(sListboxId);
 var arrMatches = TextUtil.autosuggestMatch(oTextbox.value, arrValues);
 
 ListUtil.clear(oListbox);
 
 for (var i=0; i < arrMatches.length; i++) {
     ListUtil.add(oListbox, arrMatches[i]);
 }
 
};

TextUtil.allowInput =  function (oTextbox, oEvent, bBlockPaste, bMaxLengthCheck) {
 var validChars = TextUtil.allowChars(oTextbox, oEvent, bBlockPaste);
 var isNotMax = true;
 if(bMaxLengthCheck) {
     isNotMax = TextUtil.isNotMax(oTextbox);
 }
 return validChars && isNotMax;
};

TextUtil.blockInput =  function (oTextbox, oEvent, bBlockPaste, bMaxLengthCheck) {
 var validChars = TextUtil.blockChars(oTextbox, oEvent, bBlockPaste);
 var isNotMax = true;
 if(bMaxLengthCheck) {
     isNotMax = TextUtil.isNotMax(oTextbox);
 }
 return validChars && isNotMax;
};
/*
function hideElement(o) {
 if(typeof o == 'string') {
     o = document.getElementById(o);
 }
 if(o != null) {
     o.style.display = "none";
 }
}
function showElement(o) {
 if(typeof o == 'string') {
     o = document.getElementById(o);
 }
 if(o != null) {
     o.style.display = "block";
 }
}
*/
//==============================
//END ./util/textutil.js
//==============================
//==============================
//BEGIN ./community/comments11.js
//==============================
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ''); };
var commentIdContentIdMap = new Array();
var editspans = new Array();
var observers = new Array();
function addCommentIdContentIdMapping(rId, cId) {
 commentIdContentIdMap[rId] = cId;
}
function getContentId(rId) {
 return commentIdContentIdMap[rId];
}
function addObserver(id, observer) {
 observers[id] = observer;
}
function getObserver(id) {
 return observers[id];
}
function addEditSpan(id, eSpan) {
 editspans[id] = eSpan;
}
function getSessionId() {
 var pathName = location.pathname;
 var delim = pathName.lastIndexOf('*');
 var sessionId = null;
 if(delim != -1) {
     sessionId = pathName.substring(pathName.lastIndexOf('/')+1, delim);
 }
 return sessionId;
}
function getJSessionId() {
 var url = location+"";
 var sessionId = "";
 var i = url.lastIndexOf(';jsessionid=');
 if(i != -1) {
     var j = url.lastIndexOf('?');
     if(j == -1) {
         sessionId = url.substring(i);
     } else {
         sessionId = url.substring(i, j);
     }
 }
 return sessionId;
}

function resetText(oField,sTxt) {
 oField.value = sTxt;
 oField.onfocus = null;
}
function setInnerHTML(o,sHtml) {
 if(o != null) {
     o.innerHTML = sHtml;
 }
}
function hideElement(o) {
 if(typeof o == 'string') {
     o = $(o);
 }
 if(o != null) {
     o.style.display = "none";
 }
}
function showElement(o) {
 if(typeof o == 'string') {
     o = $(o);
 }
 if(o != null) {
     o.style.display = "block";
 }
}
//edit in place
function getEditSpan(id) {
 return editspans[id];
}
function editButtonId(id) {
 return 'ucedit_'+id;
}
function commentId(id) {
 return 'uc_'+id;
}   
function makeEditable(id) {
 var editfunc = function() {edit(id)};
 addObserver(id, editfunc);
 var ebutton = $(editButtonId(id));
 Event.observe(ebutton.id, 'click', editfunc, false);
 addEditSpan(id, ebutton.parentNode);
}
function disableEdit(id) {
 var ebutton = $(editButtonId(id));
 Event.stopObserving(ebutton.id, 'click', getObserver(id), false);
 Element.addClassName(ebutton.parentNode, 'clicked');
 setInnerHTML(ebutton.parentNode, '<span>'+msg_action_editComment+'</span>');
}
function enableEdit(id) {
 var eSpan = getEditSpan(id);
 Element.removeClassName(eSpan, 'clicked');
 var ebId = editButtonId(id);
 setInnerHTML(eSpan, '<a href="javascript:void(0);" id="'+ebId+'"><span>'+msg_action_editComment+'</span></a>');
 Event.observe(ebId, 'click', getObserver(id), false);
}
function edit(id){
 var obj = $('uc_'+id);
 disableEdit(id);
 Element.hide(obj);
 var editarea = '<p class="comment" id="'+obj.id+'_editor"><textarea id="'+obj.id+'_edit" name="'+obj.id+'">'+obj.innerHTML+'</textarea><input id="'+obj.id+'_cancel" value="'+msg_action_cancel+'" type="button" /><input id="'+obj.id+'_save" value="'+msg_action_submitNewComment+'" type="button" /></p>';
 new Insertion.After(obj, editarea);  
 Event.observe(obj.id+'_save', 'click', function(){saveChanges(obj)}, false);
 Event.observe(obj.id+'_cancel', 'click', function(){cleanUp(obj)}, false);
}
function saveChanges(obj){
 var newComment =  $F(obj.id+'_edit');
 var oldComment = obj.innerHTML;
 newComment = newComment.trim();
 oldComment = oldComment.trim();
 if(newComment.length > 1000) {
     alert(msg_partial_commentExceededChars);
     return;
 }
 if(newComment.length != 0 &&
     newComment != msg_partial_newComment) {
     cleanUp(obj, true);
     if(newComment == oldComment) {
         return;
     }
     // do something here
     setInnerHTML(obj, "Saving comment...");
     sendEditCommentReq(getId(obj.parentNode.parentNode.id), getId(obj.id),newComment);
 } else {
     alert(msg_partial_enterComment);
 }
}
function cleanUp(obj, keepEditable){
 var oid = obj.id;
 Element.remove(oid+'_editor');
 Element.show(obj);
 var id = getId(oid);
 enableEdit(id)
}
//end edit in place
function submitComment(oEvent, sId, iNumComments, aSpan) {
 var oComment = $("uctext_"+sId);
 var sComment = oComment.value;
 sComment = sComment.trim();
 if(sComment.length > 1000) {
     setInnerHTML($("ucpubmsg_"+sId), msg_partial_commentExceededChars);
     return;
 }
 if(sComment.length != 0 &&
     sComment != msg_partial_newComment) {
     togglecf(sId);
     hideElement($("ucdiv1_"+sId));
     showElement($("ucvdiv_"+sId));
      var data = {
                     op: 'ac',
                     type: 'object',
                     elementId: 'ucadd_'+sId,
                     eid: 'commentHandler',
                     cid: sId,
                     comment: sComment
                  };
                  
     var commentCount = getCommentCount(sId);
     updateCommentLabel(sId, commentCount+1);
     var commentDiv = $("ucmore_"+sId);
     if(commentCount != 0 && (commentDiv.innerHTML == null || commentDiv.innerHTML == "")) {
         fetchMoreComments(sId, 0, commentCount);
     }
     $("ucdiv_"+sId).show();
     sendRequest(data);
     hideElement('ucvdiv1_'+sId);
     setInnerHTML($("ucpubmsg_"+sId), '');
		setInnerHTML(aSpan, msg_partial_youHavePosted_comment);
 } else {
     setInnerHTML($("ucpubmsg_"+sId), msg_partial_enterComment);
 }
}
function sendEditCommentReq(sId, rId, sComment) {
 sComment = sComment.trim();
 if(sComment.length > 1000) {
     alert(msg_partial_commentExceededChars);
     return;
 }
 if(sComment.length != 0 &&
     sComment != msg_partial_newComment) {
     var data = {
                     op: 'ec',
                     type: 'object',
                     elementId: 'uc_'+rId,
                     eid: 'editCommentHandler',
                     cid: sId,
                     rid: rId,
                     comment: sComment
                 };
     sendRequest(data);
 } else {
     alert(msg_partial_enterComment);
 }
}
function updateCommentLabel(sId, iNumComments) {
     var oLink = $("uclink1_"+sId);
     var label = msg_label_hideMultipleComments;      
     label = label.replace('{0}', iNumComments+'');
     setInnerHTML(oLink, label);
}
function hideCommentForm(oEvent, sId) {
 var oDiv = $("ucdiv1_"+sId);
 oDiv.style.display = "none";
}
function fetchMoreComments(sId, offset, pagesize) {
 var data = {
             op: 'gc',
             type: 'object',
             elementId: 'ucmore_'+sId,
             eid: 'commentHandler',
             cid: sId,
             offset: offset,
             pagesize: (pagesize-offset)
             };
 sendRequest(data);
}
function getCommentCount(sId) {
 var oLink = $("uclink1_"+sId);
 var label = oLink.innerHTML;
 var beginIndex = label.indexOf('(');
 if(beginIndex == -1) {
     beginIndex = label.indexOf('\uff08');
 }
 return parseInt(label.substring(beginIndex+1, label.length), 10);
}
function initialize() {
 // register request handler & add sessionId if cookies are disabled
 var qs = "";
 var sessionId = getSessionId();
 var jsessionId = getJSessionId();
 if(sessionId != null) {
     qs = "?session_id="+sessionId;
 }  
 ajaxEngine.registerRequest("ajaxServlet", "/ajaxservlet"+jsessionId+qs);
}
function registerAjaxElement(element) {
 ajaxEngine.registerAjaxElement(element);
}
function registerAjaxObject(id, object) {
 ajaxEngine.registerAjaxObject(id, object);
}
function togglecv(sId, iNumComments, oLink) {
 //var oImg = $("img1_"+sId);
 var oDiv = $("ucdiv_"+sId);
 var label = oLink.innerHTML;
 var parenIndex = label.indexOf('(');
 if(parenIndex == -1) {
     parenIndex = label.indexOf('\uff08');
 }
 
 if(oDiv.style.display == "none") {
     //oImg.src="images/evn/ic_favmin.gif";
     Element.removeClassName(oLink, "add");
     Element.addClassName(oLink, "remove");
     oDiv.style.display = "block";
     var label = oLink.innerHTML;
     setInnerHTML(oLink, msg_action_hideComments+label.substring(parenIndex-1));
     var commentDiv = $("ucmore_"+sId);
     if(iNumComments != 0 && (commentDiv.innerHTML == null || commentDiv.innerHTML == "")) {
         fetchMoreComments(sId, 0, iNumComments);
     }
 } else {       
     //oImg.src="images/evn/ic_fav.gif";
     Element.removeClassName(oLink, "remove");
     Element.addClassName(oLink, "add");
     oDiv.style.display = "none";
     setInnerHTML(oLink, msg_action_showComments+label.substring(parenIndex-1));
 }
}
function togglecf(sId, oLink) {
   //var oImg = $("img2_"+sId);
   var oDiv = $("ucdiv2_"+sId);      
   var display = oDiv.style.display;
   if(display == "none") {
       oDiv.style.display = "block";
       //oImg.src="images/evn/ic_favmin.gif";
       Element.removeClassName(oLink, "add");
       Element.addClassName(oLink, "remove");
		  setInnerHTML(oLink, msg_partial_comment_hideForm);
   } else {
       oDiv.style.display = "none";
       //oImg.src="images/evn/ic_fav.gif";
       Element.removeClassName(oLink, "remove");
       Element.addClassName(oLink, "add");
		  setInnerHTML(oLink, msg_partial_comment_addYourComment);
   }
}
function checkInput(oTextArea, oEvent) {
 return TextUtil.isNotMax(oTextArea, oEvent) && TextUtil.blockChars(oTextArea, oEvent);
}
function sendContentRatingReq(sId, iRating) {
 var data = {
             op: 'acnr',
             type: 'object',
             elementId: 'conrate_'+sId,
             eid: 'contentRatingHandler',
             cid: sId,
             rating: iRating
             };            
 sendRequest(data);
}
function sendCommentRatingReq(rId, iRating) {
 var data = {
             op: 'acmr',
             type: 'object',
             elementId: 'ucrating_'+rId,
             eid: 'commentRatingHandler',
             rid: rId,
             rating: iRating
             };
sendRequest(data);
}
function sendBlacklistUserReq(sId, uname) {
 var data = {
             op: 'bu',
             type: 'object',
             elementId: 'ucbl_'+sId,
             eid: 'blacklistUserHandler',
             user: uname
             };
sendRequest(data);
}
function sendRemoveCommentReq(rId) {
  var data = {
             op: 'rc',
             type: 'object',
             elementId: 'ucblock_'+rId,
             eid: 'removeCommentHandler',
             rid: rId
             };
sendRequest(data);
}
function sendFavoritesReq(sId, add) {
 var data = {
             op: (add ? 'af' : 'rf'),
             type: 'object',
             elementId: 'favlink_'+sId,
             eid: 'favoritesHandler',
             cid: sId
             };
 sendRequest(data);
}
function sendMFavoritesReq(lId, sId, add) {
 var data = {
             op: (add ? 'af' : 'rf'),
             type: 'object',
             elementId: 'flist_'+lId,
             eid: 'mFavoritesHandler',
             cid: sId,
             lid: lId
             };
 sendRequest(data);
}
function sendFavoriteListReq(cId) {
 var data = {
             op: 'gl',
             type: 'object',
             elementId: 'mfav_popup_list_'+cId,
             eid: 'favoriteListHandler',
             cid: cId
             };
 sendRequest(data);
}
function sendDownloadReq(cId) {
 var data = {
             op: 'lgdl',
             type: 'element',
             elementId: 'download_link_'+cId,
             eid: 'download_link_'+cId,
             cid: cId
             };
 sendRequest(data);
}
function sendContentFilterReq(cId, add) {
 var data = {
             op: (add ? 'acf' : 'rcf'),
             type: 'object',
             elementId: 'filter_'+cId,
             eid: 'contentFilterHandler',
             cid: cId
             };
 sendRequest(data);
}

function sendRequest(data) {
 var options = {};
 var xmlReqData = createXMLRequestData(data);
 ajaxEngine.sendRequestWithData("ajaxServlet",
                                 xmlReqData,
                                options);
}
function createXMLRequestData(data) {
 var op = data.op;
 var reqtxt = '<ajax-request>';
 reqtxt += '<request op="' + op + '" type="' + data.type + '" id="' + data.eid + '">';
 reqtxt += '<elementId>'+data.elementId+'</elementId>';
 if(data.lid) {
     reqtxt += '<lid>';
     reqtxt += data.lid;
     reqtxt += '</lid>';
 }
 if(data.cid) {
     reqtxt += '<cid>';
     reqtxt += data.cid;
     reqtxt += '</cid>';
  }
  if(op == "gc") {
     reqtxt += '<offset>';
     reqtxt += data.offset;
     reqtxt += '</offset>';
     reqtxt += '<pagesize>';
     reqtxt += data.pagesize;
     reqtxt += '</pagesize>';
 } else if(op == "ac" || op == "ec") {
     reqtxt += '<comment>';
     reqtxt += data.comment.escapeHTML();
     reqtxt += '</comment>';
     if(data.rid) {
         reqtxt += '<rid>';
         reqtxt += data.rid;
         reqtxt += '</rid>';
     }
 } else if(op == "acnr") {
     reqtxt += '<rating>';
     reqtxt += data.rating;
     reqtxt += '</rating>';
 } else if(op == "acmr") {
     reqtxt += '<rid>';
     reqtxt += data.rid;
     reqtxt += '</rid>';
     reqtxt += '<rating>';
     reqtxt += data.rating;
     reqtxt += '</rating>';
 } else if(op == "rc") {
     reqtxt += '<rid>';
     reqtxt += data.rid;
     reqtxt += '</rid>';
 } else if(op == "bu") {
     reqtxt += '<user>';
     reqtxt += data.user;
     reqtxt += '</user>';
 }

     reqtxt += '</request>';
     reqtxt += '</ajax-request>';

 // alert(reqtxt);
 var doc;
 if (window.ActiveXObject) {
     doc=new ActiveXObject("Microsoft.XMLDOM");
     doc.async="false";
     doc.loadXML(reqtxt);
 }
 else {
 // code for Mozilla, Firefox, Opera, etc.
     var parser=new DOMParser();
     doc=parser.parseFromString(reqtxt,"text/xml");
 }
 return doc;
}
function getId(oid) {
 return parseInt(oid.substring(oid.indexOf('_')+1, oid.length));
}
function getErrorMsg(node) {
 return getElementValue(node, "errorMsg");
}
function getElement(node, name) {
 return node.getElementsByTagName(name)[0];
}
function getElementValue(node, name) {
 var elm = getElement(node, name);
 if(elm != null) {
     return elm.childNodes[0].nodeValue;
 }
 return null;
}           
function getCommentRatingImg(rating, id) {
 var ratingImg = "";
 if(rating == null) return "";
 if(rating == "0") {
     ratingImg = '<span class="upthumb"><a href="javascript:sendCommentRatingReq('+id+',1);" title="'+msg_label_commentHelpful+'"><span>'+msg_action_thumbsUp+'</span></a></span><span class="downthumb clicked" title="'+msg_label_commentUnhelpful+'"></span>';
 } else if(rating == "1") {
     ratingImg = '<span class="upthumb clicked" title="'+msg_label_commentHelpful+'"></span><span class="downthumb"><a href="javascript:sendCommentRatingReq('+id+',0);" title="'+msg_label_commentUnhelpful+'"><span>'+msg_action_thumbsDown+'</span></a></span>';
 }
 return ratingImg;
}
function createScoreLabel(score) {
 var bangLabel = " "+msg_label_bangs;
 var scoreLabel = "0 "+msg_label_bangs;
 if(score == -1 || score == 1) {
     bangLabel = " "+msg_label_bang;
 }
 if(score < 0) {
     scoreLabel = score+bangLabel;
     
 } else if(score > 0) {
     scoreLabel = "+"+score+bangLabel;
 }
 return scoreLabel;
}
function getScoreColor(score) {
 var colorClass = "";
 if(score < 0) {
     colorClass = "red";
     
 } else if(score > 0) {
     colorClass = "green";
 }
 return colorClass;
}

function hideStars(cid) {
 var stars = $$('.conrate_'+cid);
 for(var i=0; i<stars.length; i++) {
     stars[i].hide();
 }
 return false;
}

function showStars(cid) {
 var stars = $$('.conrate_'+cid);
 for(var i=0; i<stars.length; i++) {
     stars[i].show();
 }
 return false;
}

//MF
function closepopup() {
 $("mfav_popup").style.display='none';
}

function showMFPopup(link, contentId) {
 var mfdiv = $('mfav_popup');
 if(mfdiv.style.display != 'none') {
     mfdiv.style.display = 'none';
     if(link.parentNode == mfdiv.parentNode) {
         return;
     }
 }
 // get list div and set to progress image
 $('mfav_popup_list').innerHTML = '<div style="text-align:center;"><img src="/style/videobox1/default/default/graphic/ajax-loader-blue.gif" alt="Loading...." /></div>';
 // fetch user lists for user w/ contentId
 sendFavoriteListReq(contentId);
 if(link.parentNode != mfdiv.parentNode) {
     mfdiv.parentNode.removeChild(mfdiv);
     link.parentNode.appendChild(mfdiv);
 }
 //Effect.toggle(mfdiv, 'blind', {duration:'.25'});
 mfdiv.style.display = 'block';
}

function getCurrentListCount(link) {
 for(var i=0; i < link.childNodes.length; i++) {
     if(Element.hasClassName(link.childNodes[i], 'name')) {
         var listLabel = link.childNodes[i].innerHTML;
         return parseInt(listLabel.substring(listLabel.lastIndexOf('(')+1,listLabel.lastIndexOf(')')));
     }
 }
 return 0;
}

function getListName(link) {
 for(var i=0; i < link.childNodes.length; i++) {
     if(Element.hasClassName(link.childNodes[i], 'name')) {
         var listLabel = link.childNodes[i].innerHTML;
         return listLabel.substring(0, listLabel.lastIndexOf('(')-1);
     }
 }
 return null;
}

function createListLink(data) {
 return '<a id="flist_'+data.listId+'" class="list-item clearfix '+(data.inFav?'list-item-on':'')+'" title="'+(data.inFav?'remove from list':'add to list')+
 '" href="javascript:void(0);" onclick="sendMFavoritesReq('+data.listId+','+data.contentId+','+!data.inFav+');">'+
 '<span class="toggle"><span>'+(data.inFav?'remove':'add')+'</span></span><span class="name">'+data.listName+' ('+data.favCount+')</span></a>';
}

function setUserRatings(cid, score) {
 var elements = $$('.conrate_'+cid);
 for(var i=0; i<elements.length; i++) {
     
     if(Element.hasClassName(elements[i], 'current-rating')) {
         Element.removeClassName(elements[i], 'current-rating');
         Element.addClassName(elements[i], 'voted-current-rating');
     }
     
     Element.setStyle(elements[i], {width:score+'%'}, false);
 }
}       

function setContentRatings(cid, score) {
 var elements = $$('.conrate_'+cid);
 for(var i=0; i<elements.length; i++) {
     
     if(Element.hasClassName(elements[i], 'voted-current-rating')) {
         Element.removeClassName(elements[i], 'voted-current-rating');
         Element.addClassName(elements[i], 'current-rating');
     }
     
     Element.setStyle(elements[i], {width:score+'%'}, false);
 }
}

function setFilters(cid, add) {
 var elements = $$('.filter_'+cid); 
 for(var i=0; i<elements.length; i++) {
     setInnerHTML(elements[i], '<a class="'+(add ? 'active' : '')+'" href="javascript:void(0);" onclick="sendContentFilterReq('+cid+','+!add+');" title="'+(add ? msg_action_recommend : msg_action_dontRecommend)+'"><span>'+(add ? msg_action_recommend : msg_action_dontRecommend)+'</span></a>');
 }
}

AjaxMFavoritesHandler = Class.create();
AjaxMFavoritesHandler.prototype = {
 initialize : function() {
 },
 ajaxUpdate :  function(responseElement) {
     var errormsg = getErrorMsg(responseElement);
     if(errormsg != null) {
         alert(errormsg);
         return;
     }
     var eid = getElementValue(responseElement, "elementId");
     var fav = getElement(responseElement, "addFavorite");
     var favLabel = $(eid);
     var data = {
         inFav: (fav != null),
         favCount: getCurrentListCount(favLabel),
         listName: getListName(favLabel)
     };
     var newLink = null;
     if(fav != null) {
         // change to remove favorite...
          data.listId = getElementValue(fav, "listId");
          data.contentId = getElementValue(fav, "contentId");
          data.favCount += 1;
     } else {
         fav = getElement(responseElement, "removeFavorite");
         data.listId = getElementValue(fav, "listId");
         data.contentId = getElementValue(fav, "contentId");
         // change to add favorite...
          data.favCount -= 1;
     }
     var div = document.createElement('div');
     div.innerHTML = createListLink(data);
     var oldLink = $(eid);
     oldLink.parentNode.replaceChild(div.childNodes[0], oldLink);
     
 }
}

AjaxFavoriteListHandler = Class.create();
AjaxFavoriteListHandler.prototype = {
 initialize : function() {
 },
 ajaxUpdate :  function(responseElement) {
     var errormsg = getErrorMsg(responseElement);
     if(errormsg != null) {
         alert(errormsg);
         return;
     }
     var lists = responseElement.getElementsByTagName("list");
     var eid = getElementValue(responseElement, "elementId");
     var delim = eid.lastIndexOf('_');
     var divId = eid.substring(0, delim);
     var contentId = parseInt(eid.substring(delim+1));
     var listHTMLStr = '';
     var numList = lists.length;
     for(var i = 0; i < numList; i++) {
         var list = lists[i];
         var data = {
             listId: list.getAttribute('id'),
             contentId: contentId,
             inFav: (getElement(list, 'favorite') != null),
             listName: getElementValue(list, 'name'),
             favCount: list.getAttribute('count')
         };
         listHTMLStr += createListLink(data)+'\n';
     }
     $(divId).innerHTML = listHTMLStr;
 }
}

//// END MF

AjaxRequestHandler = Class.create();
AjaxRequestHandler.prototype = {
 initialize: function(cid, eid) {
     this.contentId = cid;
     this.elementId = eid;
 },
 ajaxUpdate : function(responseElement) {
     var commentBlock = RicoUtil.getContentAsString(responseElement)
     var elm = $(this.elementId);
     setInnerHTML(elm, commentBlock);
 }
};
AjaxContentRatingHandler = Class.create();
AjaxContentRatingHandler.prototype = {
 initialize : function() {
 },
 ajaxUpdate : function(responseElement) {
     var errormsg = getErrorMsg(responseElement);
     if(errormsg != null) {
         alert(errormsg);
         return;
     }
     var contentRating = getElement(responseElement, "contentRating");
     var cid = getElementValue(contentRating, "contentId");
     var user = getElementValue(contentRating, "userId");
     var rating = getElementValue(contentRating, "rating");
     var score = getElementValue(contentRating, "score");
     setUserRatings(cid, score);
     setFilters(cid, false);
 }
};
AjaxCommentRatingHandler = Class.create();
AjaxCommentRatingHandler.prototype = {
 initialize : function() {
 },
 ajaxUpdate : function(responseElement) {
     var errormsg = getErrorMsg(responseElement);
     if(errormsg != null) {
         alert(errormsg);
         return;
     }
     var eid = getElementValue(responseElement, "elementId");
     var commentRating = getElement(responseElement, "commentRating");
     var cid = getElementValue(commentRating, "commentId");
     var uid = getElementValue(commentRating, "userId");
     var rating = getElementValue(commentRating, "rating");
     var elm = getElement(commentRating, "change");
     var change = 0;
     if(elm != null) {
         change = parseInt(elm.childNodes[0].nodeValue);
     } else {
         change = (rating == "0" ? -1 : 1);
     }
     var score = this.calculateScore(cid, change);
     var ratingImg = getCommentRatingImg(rating, cid);
     var elm = $(eid);
     setInnerHTML(elm, ratingImg);
     this.updateRating(score, cid);
 },
 updateRating : function(score, commentId) {
     var colorClass = getScoreColor(score);
     var scoreLabel = createScoreLabel(score);
     var elm = $("ucscore_"+commentId);
     Element.removeClassName(elm, "green");
     Element.removeClassName(elm, "red");
     Element.addClassName(elm, colorClass);
     setInnerHTML(elm, scoreLabel);
 },
 calculateScore : function(id, change) {
     var elm = $("ucscore_"+id);
     return parseInt(elm.innerHTML)+change;
 }
};
AjaxCommentHandler = Class.create();
AjaxCommentHandler.prototype = {
 initialize : function() {
 },
 ajaxUpdate :  function(responseElement) {
     var errormsg = getErrorMsg(responseElement);
     if(errormsg != null) {
         alert(errormsg);
         return;
     }
     var eid = getElementValue(responseElement, "elementId");
     var hasAuth = true;
     var isAdmin = false;
     if(getElement(responseElement, "noauth") != null) {
         hasAuth = false;
     }
     if(getElement(responseElement, "admin") != null) {
         isAdmin = true;
     }
     var comments = responseElement.getElementsByTagName("comment");
     var numComments = comments.length;
     var htmlStr = "";
     var cid = parseInt(eid.substring(eid.indexOf("_")+1, eid.length));
     var editIds = new Array();
     for(var i = 0; i < numComments; i++) {
         var id = comments[i].getAttribute("id");
         var text = getElementValue(comments[i], "text");
         var commenter = getElementValue(comments[i], "commenter");
         var elm = getElement(comments[i], "rating");
         var rating = null;
         if(elm != null) {
             rating = elm.childNodes[0].nodeValue;
         }
         elm = getElement(comments[i], "agree");
         var numAgree = null;
         if(elm != null) {
             numAgree = elm.childNodes[0].nodeValue;
         }
         elm = getElement(comments[i], "disagree");
         var numDisagree = null;
         if(elm != null) {
             numDisagree = elm.childNodes[0].nodeValue;
         }
         var userBlacklisted = false;
         elm = getElement(comments[i], "userBlacklisted");
         if(elm != null) {
             userBlacklisted = true;
         }
         var score = 0;
         elm = getElement(comments[i], "score");
         if(elm != null) {
             score = parseInt(elm.childNodes[0].nodeValue);
         }
         var params = {
             contentId: cid,
             commentId: id,
             commenter: commenter,
             comment: text,
             blacklisted: userBlacklisted,
             rating: rating,
             score: score,
             numAgree: numAgree,
             numDisagree: numDisagree,
             hasAuth: hasAuth,
             isAdmin: isAdmin
         };
         htmlStr += this.createCommentEntry(params);
         addCommentIdContentIdMapping(id, cid);
         if(isAdmin || rating == "-1") {
             editIds.push(id);
         }
     }
     var o = $(eid);
     setInnerHTML(o, htmlStr);
     // register all editable comments
     for(var i = 0; i < editIds.length; i++) {
         makeEditable(editIds[i]);
     }
 },
 createCommentEntry : function(params) {
     var cid = params.contentId;
     var id = params.commentId;
     var text = params.text
     var commenter = params.commenter;
     var text = params.comment;
     var userBlacklisted = params.blacklisted;
     var rating = params.rating;
     var score = params.score;
     var numAgree = params.numAgree;
     var numDisagree = params.numDisagree;
     var hasAuth = params.hasAuth;
     var isAdmin = params.isAdmin;
     
     var commentEntry = '<div class="comment-block" id="ucblock_'+id+'">';
     commentEntry += '<div class="comment-header">';
     commentEntry += '<div class="comment-panel">';
     var colorClass = getScoreColor(score);
     var scoreLabel = createScoreLabel(score);

     commentEntry += '<span class="buttonwrapper" id="ucrating_'+id+'">';
     if(rating != null) {
         commentEntry += getCommentRatingImg(rating, id);
     } else {
         if(!hasAuth) {
             var href='/beta/login.seam?loginMessageCode=acmr&amp;targetUrl=content.seam%3fid%3d'+cid;
             commentEntry += '<span class="upthumb"><a href="'+href+'" title="'+msg_label_commentHelpful+'"><span>'+msg_action_thumbsUp+'</span></a></span>';
             commentEntry += '<span class="downthumb"><a href="'+href+'" title="'+msg_label_commentUnhelpful+'"><span>'+msg_action_thumbsDown+'</span></a></span>';
         } else {
             commentEntry += '<span class="upthumb"><a href="javascript:sendCommentRatingReq('+id+',1);" title="'+msg_label_commentHelpful+'"><span>up</span></a></span>';
             commentEntry += '<span class="downthumb"><a href="javascript:sendCommentRatingReq('+id+',0);" title="'+msg_label_commentUnhelpful+'"><span>down</span></a></span>';
         }
     }
     if(isAdmin) {
         commentEntry += '<span class="editthumb"><a href="javascript:void(0);" id="ucedit_'+id+'" title="'+msg_action_editComment+'"><span>'+msg_action_editComment+'</span></a></span>';
         commentEntry += '<span class="trashthumb"><a href="javascript:sendRemoveCommentReq('+id+');" title="'+msg_action_deleteComment+'"><span>'+msg_action_deleteComment+'</span></a></span>';
         if(userBlacklisted) {
             commentEntry += '<span class="flagthumb clicked" title="'+commenter+' blacklisted."></span>';
         } else {
             commentEntry += '<span class="flagthumb" id="ucbl_'+id+'"><a href="javascript:sendBlacklistUserReq('+id+',\''+commenter+'\');" title="Blacklist User"><span>'+msg_action_flagComment+'</span></a></span>';
         }
     } else if(rating == "-1") {
         commentEntry += '<span class="editthumb"><a href="javascript:void(0);" id="ucedit_'+id+'"><span>'+msg_action_editComment+'</span></a></span>';
         commentEntry += '<span class="trashthumb"><a href="javascript:sendRemoveCommentReq('+id+');"><span>'+msg_action_deleteComment+'</span></a></span>';
     }
     commentEntry += '</span>';
     commentEntry += '<span class="bangwrapper">';
     commentEntry += '<span class="bangs '+colorClass+'" id="ucscore_'+id+'">'+scoreLabel+'</span>';
     if(isAdmin) {
         commentEntry += '(<span class="green">'+numAgree+'</span>/<span class="red">'+numDisagree+'</span>)';
     }
     commentEntry += '</span>';
     commentEntry += '</div>';
     commentEntry += commenter;
     commentEntry += '</div>';
     commentEntry += '<p class="comment" id="uc_'+id+'">'+text+'</p>';
     commentEntry += '</div>\n';     
 
     return commentEntry;
 }
};
AjaxEditCommentHandler = Class.create();
AjaxEditCommentHandler.prototype = {
 initialize: function() {
 },
 ajaxUpdate : function(responseElement) {
     var errormsg = getErrorMsg(responseElement);
     if(errormsg != null) {
         alert(errormsg);
         return;
     }
     var eid = getElementValue(responseElement, "elementId");
     var elm = getElement(responseElement, "comment");
     var commentId = elm.getAttribute("id");
     var text = getElementValue(elm, "text");
     elm = $(eid);
     setInnerHTML(elm, text);
 }
};
AjaxRemoveCommentHandler = Class.create();
AjaxRemoveCommentHandler.prototype = {
 initialize : function() {
 },
 ajaxUpdate :  function(responseElement) {
     var errormsg = getErrorMsg(responseElement);
     if(errormsg != null) {
         alert(errormsg);
         return;
     }
     var eid = getElementValue(responseElement, "elementId");
     var rcElm = getElement(responseElement, "removeComment");
     var commentId = getElementValue(rcElm, "commentId");
     var userId = getElementValue(rcElm, "userId");
     var oComment = $(eid);
     oComment.parentNode.removeChild(oComment);
     var contentId = getContentId(commentId);
     showElement($("ucdiv1_"+contentId));
     updateCommentLabel(contentId, getCommentCount(contentId)-1);
 }
};
AjaxBlacklistUserHandler = Class.create();
AjaxBlacklistUserHandler.prototype = {
 initialize : function() {
 },
 ajaxUpdate :  function(responseElement) {
     var errormsg = getErrorMsg(responseElement);
     if(errormsg != null) {
         alert(errormsg);
         return;
     }
     var eid = getElementValue(responseElement, "elementId");
     var bl = getElement(responseElement, "blacklistUser");
     var userId = getElementValue(bl, "userId");
     var userName = getElementValue(bl, "userName");
     var elm = $(eid);
     setInnerHTML(elm, '');
     Element.addClassName(eid, 'clicked');
     alert('user ' + userName + ' has been blacklisted.');
 }
};
AjaxFavoritesHandler = Class.create();
AjaxFavoritesHandler.prototype = {
 initialize : function() {
 },
 ajaxUpdate :  function(responseElement) {
     var errormsg = getErrorMsg(responseElement);
     if(errormsg != null) {
         alert(errormsg);
         return;
     }
     var eid = getElementValue(responseElement, "elementId");
     var fav = getElement(responseElement, "addFavorite");
     var favLabel = $(eid);
     var contentId = null;
     if(fav != null) {
         // change favLabel to remove favorite...
          contentId = getElementValue(fav, "contentId");
          setInnerHTML(favLabel, '<a class="remove" href="javascript:sendFavoritesReq('+contentId+',false);">Remove from favorites</a>');
     } else {
         fav = getElement(responseElement, "removeFavorite");
         contentId = getElementValue(fav, "contentId");
         // change favLabel to add favorite...
         setInnerHTML(favLabel, '<a class="add" href="javascript:sendFavoritesReq('+contentId+',true);">Add to favorites</a>');
     }
 }
}
AjaxContentFilterHandler = Class.create();
AjaxContentFilterHandler.prototype = {
 initialize : function() {
 },
 ajaxUpdate :  function(responseElement) {
     var errormsg = getErrorMsg(responseElement);
     if(errormsg != null) {
         alert(errormsg);
         return;
     }
     var eid = getElementValue(responseElement, "elementId");
     var filter = getElement(responseElement, "contentFilter");
     var op = filter.getAttribute("op");
     var contentId = getElementValue(filter, "contentId");
     var contentRating = getElementValue(filter, "contentRating");
     if(op == 'add') {
         setContentRatings(contentId, 0);
         setFilters(contentId, true);
     } else {
         setContentRatings(contentId, contentRating);
         setFilters(contentId, false);
     }
 }
}

var commentHandler = new AjaxCommentHandler();
var editCommentHandler = new AjaxEditCommentHandler();
var commentRatingHandler = new AjaxCommentRatingHandler();
var contentRatingHandler = new AjaxContentRatingHandler();
var removeCommentHandler = new AjaxRemoveCommentHandler();
var blacklistUserHandler = new AjaxBlacklistUserHandler();
var favoritesHandler = new AjaxFavoritesHandler();
var mFavoritesHandler = new AjaxMFavoritesHandler();
var favoriteListHandler = new AjaxFavoriteListHandler();
var contentFilterHandler = new AjaxContentFilterHandler();
initialize();
registerAjaxObject("commentHandler", commentHandler);
registerAjaxObject("editCommentHandler", editCommentHandler);
registerAjaxObject("contentRatingHandler", contentRatingHandler);
registerAjaxObject("commentRatingHandler", commentRatingHandler);
registerAjaxObject("removeCommentHandler", removeCommentHandler);
registerAjaxObject("blacklistUserHandler", blacklistUserHandler);
registerAjaxObject("favoritesHandler", favoritesHandler);
registerAjaxObject("mFavoritesHandler", mFavoritesHandler);
registerAjaxObject("favoriteListHandler", favoriteListHandler);
registerAjaxObject("contentFilterHandler", contentFilterHandler);
//==============================
//END ./community/comments11.js
//==============================
//==============================
//BEGIN ./community/search1.js
//==============================
function dateClick(date,input) {
 // parse the plan from the link id
// var date = link;
  $("jform:" + input).value = date;
 // do not use prototype cssSelector here $$('a.plan'), it does not work in firefox
 unselect($(input + '-' + date).parentNode.childNodes);
 $(input + '-' + date).addClassName("selected");
}

function unselect(elms) {
 for(i=0; i<elms.length; i++) {
     // check for undefined is necessary for firefox since there are text nodes w/o id's
     if(elms[i].id != undefined) {
         $(elms[i].id).removeClassName("selected");
     }
 }
}
//==============================
//END ./community/search1.js
//==============================
//==============================
//BEGIN ./filmstrip/evn_scene4.js
//==============================
var auth;
var sessionid;
var scene;
var showId = false;
var host;
var vid_path_dvdc;
var vid_path_bc;
var vid_path_mc;
var brand_id;
var contentArray = new Array();
var show_dvd_res = true;
var show_dvd_upgrade = false;

var numRows;
var thumbLength;
var startRow = -1;
var startCol = -1;
var endRow = -1;
var endCol = -1;
var leftHighlight = false;
var rightHighlight = false;


//distance from top and bottom of page to fix the scroll area
var topPadding = 203; // adjusted to fit new top padding of new layout
var bottomPadding = 0;
var scrollOffBottom = 0;
var minHeight = 250;

var draggingThumb = false;
var isDragging = false;
var dragRow;
var dragCol;
var mouseY = 1; // Mouse Y position onclick
var mouseX = 1; // Mouse X position onclick

var dvdcDirId;
var bcDirId;
var mcDirId;

var startAnim = false;
var isTour = false;

function getContent(row, col)
{
 var content = contentArray[row];
 content = content.children[col];
 return content;
}

function clickThumb(row, col)
{
 if (endAnim)
clickThumbGeneral(row, col, false);
}

function clickThumbGeneral(row, col, isAnim)
{
 e = this.Event;

 draggingThumb = true;
 dragRow = row;
 dragCol = col;
 startDrag(isAnim);

 return true;
}

function mouseOverThumb(cellRef, mouseOver)
{
 if (mouseOver) {
   cellRef.style.cursor = "move";
   window.status = "Click to Drag";
 } else {
   window.status = scene.name;
 }
 return true;
}


function startDrag(isAnim)
{
 // make thumbnail visible and position it
 //   todo -- offset thumbnail to align with original to avoid jump effect
 //           also, maybe some transparency?
 var content = getContent(dragRow, dragCol);

 div = document.getElementById('dragThumb');
 divcss = div.style;
 if (!isAnim) {
    getMouse(null);
 }
 divcss.top = mouseY - 36 + "px";
 divcss.left = mouseX - 49 + "px";
 divcss.visibility = 'visible';

 isDragging = true;

 if (isAnim) {
   // show cursor
   div = document.getElementById('dragCursor');
   divcss = div.style;
   divcss.top = mouseY - 14 + "px";
   divcss.left = mouseX - 12 + "px";
   divcss.visibility = 'visible';
 }
 
 img = document.getElementById('dragThumb_img');
 img.src = content.smallImg.src;
 
 // show instruction image
 div = document.getElementById('midInst');
 divcss = div.style;
 divcss.visibility = 'visible';
 setBackground("startThumbFrame", imageDragStartHover);
 setBackground("endThumbFrame", imageDragEndHover);
}

function moveDrag(isAnim)
{
 // move thumbnail
 div = document.getElementById('dragThumb');
 divcss = div.style;
 divcss.top = mouseY - 36 + "px";
 divcss.left = mouseX - 49 + "px";

 if (isAnim) {
   // show cursor
   div = document.getElementById('dragCursor');
   divcss = div.style;
   divcss.top = mouseY - 14 + "px";
   divcss.left = mouseX - 12 + "px";
 }

 // highlight drop region
 if (overLeftThumb()) {
if (leftHighlight == false) {
   setBackground("startThumbFrame", imageDragStartHover);
   leftHighlight = true;
}
 } else {
if (leftHighlight == true) {
   setBackground("startThumbFrame", imageDragStart);
   leftHighlight = false;
}
 }

 if (overRightThumb()) {
if (rightHighlight == false) {
   setBackground("endThumbFrame", imageDragEndHover);
   rightHighlight = true;
}
 } else {
if (rightHighlight == true) {
   setBackground("endThumbFrame", imageDragEnd);
   rightHighlight = false;
}
 }
}

function overLeftThumb()
{
 var position = Position.cumulativeOffset($('startThumbFrame'));
 var top = position[1]; // changed from 149 to adjust new dropzone for new layout
 var bottom = top+100; // changed from 287 to adjust new dropzone for new layout
 var left = position[0];; // TODO: need this to adjust for centered layout
 var right = left+139;  // TODO: need this to adjust for centered layout
 return ((mouseY <= bottom && mouseY >= top) && (mouseX >= left && mouseX <= right));
}

function overRightThumb()
{
 var position = Position.cumulativeOffset($('endThumbFrame'));
 var top = position[1]; // changed from 149 to adjust new dropzone for new layout
 var bottom = top+100; // changed from 287 to adjust new dropzone for new layout
 var left = position[0]; // TODO: need this to adjust for centered layout
 var right = left+139; // TODO: need this to adjust for centered layout
 return ((mouseY <= bottom && mouseY >= top) && (mouseX >= left && mouseX <= right));
}

function endDrag()
{
 if (isDragging) {
isDragging = false;

// hide drag image
draggingThumb = false;
div = document.getElementById('dragThumb');
divcss = div.style;
divcss.visibility = 'hidden';

div = document.getElementById('dragCursor');
divcss = div.style;
divcss.visibility = 'hidden';

// hide instruction image
div = document.getElementById('midInst');
divcss = div.style;
divcss.visibility = 'hidden';

var didDrop = false;
if (overLeftThumb()) {
   var content = getContent(dragRow, dragCol);
   // change big thumb
   setBackground("startThumbImg", content.bigImageUrl);

   // remove instructional text over big thumb
   if (document.all||document.getElementById) {
 cross_el = document.getElementById ? document.getElementById("startText") : document.all.startText;
 cross_el.innerHTML = " ";
   } else if (document.layers) {
 document.start_d1.document.start_d2.document.write(" ");
 document.start_d1.document.start_d2.document.close();
   }

   // change start/end thumbnail borders
   placeFrame(dragRow, dragCol, endRow, endCol);
   didDrop = true;
} else if (overRightThumb()) {
   var content = getContent(dragRow, dragCol);
   // change big thumb
   setBackground("endThumbImg", content.bigImageUrl);

   // remove instructional text over big thumb
   if (document.all||document.getElementById) {
 cross_el = document.getElementById ? document.getElementById("endText") : document.all.endText;
 cross_el.innerHTML = " ";
   } else if (document.layers) {
 document.end_d1.document.end_d2.document.write(" ");
 document.end_d1.document.end_d2.document.close();
   }

   // change start/end thumbnail borders
   placeFrame(startRow, startCol, dragRow, dragCol);
   didDrop = true;
}

if (didDrop) {
   var dynInfo = computeDynInfo();

   // change middle text
   var text = computeMiddleText(dynInfo);
   //alert(text);
   if (document.all||document.getElementById) {
 cross_el = document.getElementById ? document.getElementById("downloadText") : document.all.downloadText;
     if(cross_el != null) {
         //alert(cross_el.innerHTML);
         cross_el.innerHTML = "";
         cross_el.innerHTML = text;
     }
   } else if (document.layers) {
 document.dl_d1.document.dl_d2.document.write(text);
 document.dl_d1.document.dl_d2.document.close();
   }

   // change start/end time
   text = '<strong>Start time</strong> ' + dynInfo.startTimeFormatted;
   if (document.all||document.getElementById) {
 cross_el = document.getElementById ? document.getElementById("startTimeText") : document.all.startTimeText;
 cross_el.innerHTML = "";
 cross_el.innerHTML = text;
   } else if (document.layers) {
 document.start_time_d1.document.start_time_d2.document.write(text);
 document.start_time_d1.document.start_time_d2.document.close();
   }

   text = '<strong>End time</strong> ' + dynInfo.endTimeFormatted;
   if (document.all||document.getElementById) {
 cross_el = document.getElementById ? document.getElementById("endTimeText") : document.all.endTimeText;
 cross_el.innerHTML = "";
 cross_el.innerHTML = text;
   } else if (document.layers) {
 document.end_time_d1.document.end_time_d2.document.write(text);
 document.end_time_d1.document.end_time_d2.document.close();
   }
}
//NEW FILMSTRIP: no more background image (green/orange highlight)
setBackground("startThumbFrame", imageDragStart);
setBackground("endThumbFrame", imageDragEnd);
 }
}

function computeMiddleText(dynInfo)
{
 var text = '';
 if (dynInfo.illegal == true && !isTour) {
text = '<table width="100%"  border="0" cellspacing="0" cellpadding="0"><tr><td height="60" valign="center" align="center" style="font-size: 14px">'+msg_partial_filmstripChooseStart+'</td></tr></table>';
 } else {
// set the length label
var lengthLab = $('lengthLabel');
if(lengthLab != null) {
 lengthLab.innerHTML = '<strong>'+msg_label_length+'</strong> ' + dynInfo.length;
 }
 
if (!isTour) {
   var dvdUrl = 'http://' + vid_path_dvdc + '/get/dvdc/' + scene.id + '/' + recommendAlgId + '/' + dynInfo.startSecond + '/' + dynInfo.endSecond + '/' + dvdcDirId + '/' + sessionId + '/' + dynInfo.filebase + '_dvd.wmv';
   var bigUrl = 'http://' + vid_path_bc + '/get/bc/' + scene.id + '/' + recommendAlgId + '/' + dynInfo.startSecond + '/' + dynInfo.endSecond + '/' + bcDirId + '/' + sessionId + '/' + dynInfo.filebase + '_b.wmv';
   var medUrl = 'http://' + vid_path_mc + '/get/mc/' + scene.id + '/' + recommendAlgId + '/' + dynInfo.startSecond + '/' + dynInfo.endSecond + '/' + mcDirId + '/' + sessionId + '/' + dynInfo.filebase + '_m.wmv';

   var urlBegin = '<a class="button-play list-item" onmousedown="sendDownloadReq('+scene.id+'); return true;" href="';
   var urlMiddle = '">';
   var urlEnd = ')</a>';

   text = '<span class="link-block clearfix">';
   if (show_dvd_res) {
     text += urlBegin + dvdUrl + urlMiddle + msg_label_format_dvd + ' - (' + dynInfo.dvdcSize + urlEnd;
   } else {
     if (show_dvd_upgrade) {
       //dvdUrl = "premium-upsell.seam";
       //text += urlBegin + dvdUrl + urlMiddle;
       //text += msg_partial_upgradeTo + ' ' + msg_label_format_dvd;
       //text += '</a>';
     }
   }
   text += urlBegin + bigUrl + urlMiddle + msg_label_format_high + ' - (' + dynInfo.bcSize + urlEnd;
   text += urlBegin + medUrl + urlMiddle + msg_label_format_medium + ' - (' + dynInfo.mcSize + urlEnd;
}
text += '</span>';
 }

 if (mac && ie4) {
text += "&nbsp;";
 }
 text +='<div class="instructions">'+msg_partial_download_popupInstructions+'</div>';
 return text;
}

function computeDynInfo()
{
var result = new Object();

if (startRow > endRow || (startRow == endRow && startCol > endCol)) {

 result.illegal = true;
 result.length = '???';

} else {

 result.illegal = false;
 col = startCol;
 row = startRow;

 startNum = 6 * startRow + startCol;
 endNum = 6 * endRow + endCol;
 numCols = (endNum - startNum) + 1;

 rawLength = thumbLength * numCols;
 dvdcSize = dvdcThumbSize * numCols;
 bcSize = bcThumbSize * numCols;
 mcSize = mcThumbSize * numCols;

 rawLength = Math.floor(rawLength);
 result.length = formatTime(rawLength);

result.startTimeFormatted = formatTime(Math.floor(thumbLength * startNum));
result.endTimeFormatted = formatTime(Math.floor(thumbLength * (endNum + 1)));

result.startSecond = Math.floor(6 * startRow * thumbLength + startCol * thumbLength);
if (endRow == numRows - 1 && endCol == 5) {
   result.endSecond = -1;
} else {
   result.endSecond = result.startSecond + rawLength;
}
   result.dvdcSize = formatSize(dvdcSize);
   result.bcSize = formatSize(bcSize);
   result.mcSize = formatSize(mcSize);
   result.filebase = scene.encoded_name + "_" + result.startSecond + "-" + result.endSecond;
 }
 return result;
}

function formatTime(seconds)
{
if (seconds <= 0) {
  return "0:00 " + msg_label_time_minutes;
}

 minutes = Math.floor(seconds / 60);
 if (minutes == 0) {
return "" + seconds + " " + msg_label_time_seconds;
 } else {
seconds = seconds % 60;
minutesStr = "" + minutes;
secondsStr = "" + seconds;
if (seconds < 10)
   secondsStr = "0" + secondsStr;
result = minutesStr + ":" + secondsStr + " " + msg_label_time_minutes;
return result;
 }
}

function formatSize(size)
{
if (size > (1024 * 1024 * 1024)) {
 size = Math.floor(size / (1024 * 1024 * 102.4 ));
 first = Math.floor(size / 10);
 last = size % 10;
 return first + "." + last + " GB";
} else if (size > (1024 * 1024)) {
 size = Math.floor(size / (1024 * 102.4));
 first = Math.floor(size / 10);
 last = size % 10;
 return first + "." + last + " MB";
} else {
 return Math.floor(size / 1024) + " KB";
}
}

//http://www.faqts.com/knowledge_base/view.phtml/aid/4005
function setBackground(idName, imgName)
{
 div = document.getElementById(idName);
 if (div == null) {
alert("div " + idName + " is " + div);
 } else {
divcss = div.style;

if (imgName == null)
   divcss.backgroundImage = "none";
else
   divcss.backgroundImage = 'url(' + imgName + ')';
 }
}

function setBackground(idName, imgName, alpha)
{
 div = document.getElementById(idName);
 if (div == null) {
alert("div " + idName + " is " + div);
 } else {
divcss = div.style;

if (imgName == null)
   divcss.backgroundImage = "none";
else
   divcss.backgroundImage = 'url(' + imgName + ')';

if (ie4 && !mac) {
   divcss.filter = "Alpha(opacity=" + (100 * alpha) + ")";
} else if (dom && !mac) {
   divcss.MozOpacity = alpha;
}

 }
}

function placeFrame(aStartRow, aStartCol, aEndRow, aEndCol)
{
 startRow = aStartRow;
 startCol = aStartCol;
 endRow = aEndRow;
 endCol = aEndCol;

 // set opacity
 for(row = 0; row < numRows; row++) {
for(col = 0; col < 6; col++) {
   if (row < startRow || (row == startRow && col < startCol)) {
 setBackground("frame_" + row + "," + col, null, 0.5);
   } else if (row > endRow || (row == endRow && col > endCol)) {
 setBackground("frame_" + row + "," + col, null, 0.5);
   } else if ((row < endRow || (row == endRow && col < endCol)) && (row > startRow || (row == startRow && col > startCol))) {
 setBackground("frame_" + row + "," + col, null, 1.0);
   }
}
 }
 
  if (startRow == endRow && startCol == endCol) {
setBackground("frame_" + startRow + "," + startCol, filmstripFrameBgGIF, 1.0);
 } else {
setBackground("frame_" + startRow + "," + startCol, filmstripFrameBgStartGIF, 1.0);
setBackground("frame_" + endRow + "," + endCol, filmstripFrameBgEndGIF, 1.0);
 }

}

//Browser detection
var dom = document.getElementById ? true:false;
var nn4 = document.layers ? true:false;
var ie4 = document.all ? true:false;
var mac = false;
if (navigator.userAgent.toLowerCase().indexOf("mac") != -1)
mac = true;

var timer = setTimeout("",500); // Repeat variable

//Mousedown
function down(e){
 if((document.layers && e.which!=1) || (document.all && event.button!=1)) return true; // Enables the right mousebutton
 if (endAnim) {
getMouse(e);
if (draggingThumb) {
   startDrag(false);
}
 }

 if (!ie4 && draggingThumb)
return false;
 else
return true;
}

//Drag function
function move(e){
 if (endAnim) {
if (draggingThumb) {
   getMouse(e);
   moveDrag(false);
}
 }

 return false;
}

function up(){
 if (endAnim) {
clearTimeout(timer);
endDrag();
 }

 return true;
}

//Reads mouse X and Y coordinates
function getMouse(e){
  if(ie4) {
     mouseY = Event.pointerY(event);
     mouseX = Event.pointerX(event);
   } else if(nn4 || dom){
       if (e == null && window.event) {
         e = window.event;
       }
       if (e != null) {
           mouseY = Event.pointerY(e); 
           mouseX = Event.pointerX(e);
       }
  }
}

//reloads page to position the layers again
function reloadPage() {
location.reload();
}

//Preload
function eventLoader(row) {
 doResize();
 // Initializes event capturing
 if(nn4){
document.captureEvents(Event.MOUSEDOWN | Event.MOUSEMOVE | Event.MOUSEUP);
window.onresize = reloadPage;
 }
 //document.onmousedown = down;
 //document.onmousemove = move;
 //document.onmouseup = up;

 div = document.getElementById('dragThumb');
 divcss = div.style;
 if (ie4 && !mac) {
divcss.filter = "Alpha(opacity=70)";
 } else if (dom && !mac) {
divcss.MozOpacity = 0.7;
 }

 // load images
 for(row = 0; row < numRows; row++) {
for(col = 0; col < 6; col++) {
   var content = getContent(row, col);
   document.getElementById("thumb_" + row + "," + col).src = content.smallImg.src;
}
 }
 // place start/end frames
 placeFrame(0, 0, numRows - 1, 5);

 document.onmousedown = down;
 document.onmousemove = move;
 document.onmouseup = up;

 if (startAnim) {
startAnimation();
 } else {
endAnim = true;
refreshState();
 }
}

function doResize()
{
var filmstrip = document.getElementById("stripwrapper");
 // perform the resizing
 if(ie4 && !isOpera){
   var bottom = document.documentElement.offsetHeight - bottomPadding + scrollOffBottom;
   if ((bottom - topPadding) < minHeight) {
     bottom = minHeight + topPadding;
   }
   var height = bottom - topPadding;
   if (height < 0)
       height = 0;
   // content layer and clip layer
   filmstrip.style.top = topPadding + "px";
   filmstrip.style.height = height + "px";
   filmstrip.style.visibility = "visible";
 } else if(nn4){
   var bottom = window.innerHeight - bottomPadding + scrollOffBottom;
   if ((bottom - topPadding) < minHeight) {
     bottom = minHeight + topPadding;
   }
   var height = bottom - topPadding;
   if (height < 0)
       height = 0;
   // content layer and clip layer
   filmstrip.top = topPadding + "px";
   filmstrip.height = height + "px";
   filmstrip.visibility = "visible";
 } else if(dom){
   var bottom = window.innerHeight - bottomPadding + scrollOffBottom;
   if ((bottom - topPadding) < minHeight) {
     bottom = minHeight + topPadding;
   }
   var height = bottom - topPadding;
   // if (navigator.userAgent.indexOf("Firefox")!=-1) {
   //   var height = bottom;
   // }
   if (height < 0)
       height = 0;
   filmstrip.style.top = topPadding + "px";
   filmstrip.style.height = height + "px";
   filmstrip.style.visibility = 'visible';
 }
//setAnimationCoordinates();
}

var endAnim = false;
var wait1 = 200;
var wait2 = 500;
var wait3 = 1000;
var speed = 80;

//states
var DRAG1 = 0;
var DRAG2 = 1;
var REFRESH = 3;
var animState;

//coordinates set by setAnimationCoordinates()
var drag1StartX = 0;
var drag1StartY = 0;
var drag1EndX = 0;
var drag1EndY = 0;

var drag2StartX = 0;
var drag2StartY = 0;
var drag2EndX = 0;
var drag2EndY = 0;

var numSteps = 20;
var animStep = 0;

function refreshState()
{
 // hide drag image
 draggingThumb = false;
 div = document.getElementById('dragThumb');
 divcss = div.style;
 divcss.visibility = 'hidden';

 div = document.getElementById('dragCursor');
 divcss = div.style;
 divcss.visibility = 'hidden';

 // hide instruction image
 div = document.getElementById('midInst');
 divcss = div.style;
 divcss.visibility = 'hidden';

 var content = getContent(0, 0);
 // change big thumb
 //NEW FILMSTRIP: no more start image
 // setBackground("startThumbImg", content.bigImageUrl);
//NEW FILMSTRIP: no more inner text
 // add instructional text over big thumb
//   if (document.all||document.getElementById) {
// cross_el = document.getElementById ? document.getElementById("startText") : document.all.startText;
// cross_el.innerHTML = '<div class="shadow">Drag Thumbnail Here<br /> to Change when<br /> Video Starts</div><div class="fronttext">Drag Thumbnail Here<br /> to Change when<br /> Video Starts</div>';
//   } else if (document.layers) {
// document.start_d1.document.start_d2.document.write('<div class="shadow">Drag Thumbnail Here<br /> to Change when<br /> Video Starts</div><div class="fronttext">Drag Thumbnail Here<br /> to Change when<br /> Video Starts</div>');
// document.start_d1.document.start_d2.document.close();
//   }

 var content = getContent(numRows - 1, 5);
 // change big thumb
 //NEW FILMSTRIP: no more start image
 // setBackground("endThumbImg", content.bigImageUrl);

 //NEW FILMSTRIP: no more inner text
 // add instructional text over big thumb
//   if (document.all||document.getElementById) {
// cross_el = document.getElementById ? document.getElementById("endText") : document.all.endText;
// cross_el.innerHTML = '<div class="shadow">Drag Thumbnail Here<br /> to Change when<br /> Video Ends</div><div class="fronttext">Drag Thumbnail Here<br /> to Change when<br /> Video Ends</div>';
//   } else if (document.layers) {
// document.end_d1.document.end_d2.document.write('<div class="shadow">Drag Thumbnail Here<br /> to Change when<br /> Video Ends</div><div class="fronttext">Drag Thumbnail Here<br /> to Change when<br /> Video Ends</div>');
// document.end_d1.document.end_d2.document.close();
//   }

 startRow = 0;
 endRow = numRows - 1;
 startCol = 0;
 endCol = 5;
 var dynInfo = computeDynInfo();

 // change middle text
 var text = computeMiddleText(dynInfo);
 //alert(text);
 if (document.all||document.getElementById) {
cross_el = document.getElementById ? document.getElementById("downloadText") : document.all.downloadText;
 if(cross_el != null) {
   //alert(cross_el.innerHTML);
   cross_el.innerHTML = "";
   cross_el.innerHTML = text;
   }
 } else if (document.layers) {
document.dl_d1.document.dl_d2.document.write(text);
document.dl_d1.document.dl_d2.document.close();
 }

 // change start/end time
 text = '<strong>'+msg_label_startTime+'</strong> ' + dynInfo.startTimeFormatted;
 if (document.all||document.getElementById) {
cross_el = document.getElementById ? document.getElementById("startTimeText") : document.all.startTimeText;
cross_el.innerHTML = "";
cross_el.innerHTML = text;
 } else if (document.layers) {
document.start_time_d1.document.start_time_d2.document.write(text);
document.start_time_d1.document.start_time_d2.document.close();
 }

 text = '<strong>'+msg_label_endTime+'</strong> ' + dynInfo.endTimeFormatted;
 if (document.all||document.getElementById) {
cross_el = document.getElementById ? document.getElementById("endTimeText") : document.all.endTimeText;
cross_el.innerHTML = "";
cross_el.innerHTML = text;
 } else if (document.layers) {
document.end_time_d1.document.end_time_d2.document.write(text);
document.end_time_d1.document.end_time_d2.document.close();
 }

 //NEW FILMSTRIP: no more frame replacement
 setBackground("startThumbImg",null);
 setBackground("endThumbImg",null);
 setBackground("startThumbFrame", imageDragStart);
 setBackground("endThumbFrame", imageDragEnd);
 // change start/end thumbnail bimageDragEndorders
 placeFrame(0, 0, numRows - 1, 5);
}

function advanceAnimation()
{
 setAnimationCoordinates();
 if (!endAnim) {
if (animState == DRAG1) {
   if (animStep == numSteps) {
 // we're done
 endDrag();
 animStep = 0;
 animState = DRAG2;
 setTimeout('advanceAnimation()', wait2);
   } else {
 // make layer visible
 mouseX = drag1StartX + animStep * ((drag1EndX - drag1StartX)/numSteps);
 mouseY = drag1StartY + animStep * ((drag1EndY - drag1StartY)/numSteps);
 if (animStep == 0)
     clickThumbGeneral(1, 1, true);
 else
     moveDrag(true);
 //move;
 animStep++;
 setTimeout('advanceAnimation()', speed);
   }
} else if (animState == DRAG2) {
   if (animStep == numSteps) {
 // we're done
 endDrag();
 animStep = 0;
 animState = REFRESH;
 setTimeout('advanceAnimation()', wait3);
   } else {
 // make layer visible
 mouseX = drag2StartX + animStep * ((drag2EndX - drag2StartX)/numSteps);
 mouseY = drag2StartY + animStep * ((drag2EndY - drag2StartY)/numSteps);
 if (animStep == 0)
     clickThumbGeneral(1, 4, true);
 else
     moveDrag(true);
 //move;
 animStep++;
 setTimeout('advanceAnimation()', speed);
   }
} else if (animState == REFRESH) {
   refreshState();
   animState = DRAG1;
   setTimeout('advanceAnimation()', wait1);
}
 }
}

function startAnimation()
{
 //setAnimationCoordinates();
 animState = DRAG1;
 setTimeout('advanceAnimation()', wait1);
}

function setAnimationCoordinates() {
 var rowTemp = 1;  // use the second row for the animation
 var colTemp1 = 1; // use the second frame of the row
 var colTemp2 = 4; // use the next to the last frame of the row
 
 if(numRows <= 1) {
     row = 0; // if only one row, use the first row
 }
  var position = Position.cumulativeOffset($('frame_'+rowTemp+','+colTemp1));
  if((position[1]+36) == drag1StartY && (position[0]+50) == drag1StartX) {
     return;  // do nothing since browser window size did not change
  }
  
  drag1StartX = position[0]+50;
  drag1StartY = position[1]+36;
  
  position = Position.cumulativeOffset($('startThumbFrame'));
  drag1EndX = position[0]+70;
  drag1EndY = position[1]+50;
 
  position = Position.cumulativeOffset($('frame_'+rowTemp+','+colTemp2));
  drag2StartX = position[0]+50;
  drag2StartY = position[1]+36;
  
  position = Position.cumulativeOffset($('endThumbFrame'));
  drag2EndX = position[0]+70;
  drag2EndY = position[1]+50;
}

function endAnimation()
{
 endAnim = true;
 refreshState();
 document.getElementById('firstTime').style.visibility = 'hidden';
}

//==============================
//END ./filmstrip/evn_scene4.js
//==============================

/* SWFObject v2.1 <http://code.google.com/p/swfobject/>
 Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis
 This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write("<script id=__ie_ondomload defer=true src=//:><\/script>");J=C("__ie_ondomload");if(J){I(J,"onreadystatechange",S)}}catch(q){}}if(h.webkit&&typeof K.readyState!=b){Z=setInterval(function(){if(/loaded|complete/.test(K.readyState)){E()}},10)}if(typeof K.addEventListener!=b){K.addEventListener("DOMContentLoaded",E,null)}R(E)}();function S(){if(J.readyState=="complete"){J.parentNode.removeChild(J);E()}}function E(){if(e){return }if(h.ie&&h.win){var v=a("span");try{var u=K.getElementsByTagName("body")[0].appendChild(v);u.parentNode.removeChild(u)}catch(w){return }}e=true;if(Z){clearInterval(Z);Z=null}var q=o.length;for(var r=0;r<q;r++){o[r]()}}function f(q){if(e){q()}else{o[o.length]=q}}function R(r){if(typeof j.addEventListener!=b){j.addEventListener("load",r,false)}else{if(typeof K.addEventListener!=b){K.addEventListener("load",r,false)}else{if(typeof j.attachEvent!=b){I(j,"onload",r)}else{if(typeof j.onload=="function"){var q=j.onload;j.onload=function(){q();r()}}else{j.onload=r}}}}}function H(){var t=N.length;for(var q=0;q<t;q++){var u=N[q].id;if(h.pv[0]>0){var r=C(u);if(r){N[q].width=r.getAttribute("width")?r.getAttribute("width"):"0";N[q].height=r.getAttribute("height")?r.getAttribute("height"):"0";if(c(N[q].swfVersion)){if(h.webkit&&h.webkit<312){Y(r)}W(u,true)}else{if(N[q].expressInstall&&!A&&c("6.0.65")&&(h.win||h.mac)){k(N[q])}else{O(r)}}}}else{W(u,true)}}}function Y(t){var q=t.getElementsByTagName(Q)[0];if(q){var w=a("embed"),y=q.attributes;if(y){var v=y.length;for(var u=0;u<v;u++){if(y[u].nodeName=="DATA"){w.setAttribute("src",y[u].nodeValue)}else{w.setAttribute(y[u].nodeName,y[u].nodeValue)}}}var x=q.childNodes;if(x){var z=x.length;for(var r=0;r<z;r++){if(x[r].nodeType==1&&x[r].nodeName=="PARAM"){w.setAttribute(x[r].getAttribute("name"),x[r].getAttribute("value"))}}}t.parentNode.replaceChild(w,t)}}function k(w){A=true;var u=C(w.id);if(u){if(w.altContentId){var y=C(w.altContentId);if(y){M=y;l=w.altContentId}}else{M=G(u)}if(!(/%$/.test(w.width))&&parseInt(w.width,10)<310){w.width="310"}if(!(/%$/.test(w.height))&&parseInt(w.height,10)<137){w.height="137"}K.title=K.title.slice(0,47)+" - Flash Player Installation";var z=h.ie&&h.win?"ActiveX":"PlugIn",q=K.title,r="MMredirectURL="+j.location+"&MMplayerType="+z+"&MMdoctitle="+q,x=w.id;if(h.ie&&h.win&&u.readyState!=4){var t=a("div");x+="SWFObjectNew";t.setAttribute("id",x);u.parentNode.insertBefore(t,u);u.style.display="none";var v=function(){u.parentNode.removeChild(u)};I(j,"onload",v)}U({data:w.expressInstall,id:m,width:w.width,height:w.height},{flashvars:r},x)}}function O(t){if(h.ie&&h.win&&t.readyState!=4){var r=a("div");t.parentNode.insertBefore(r,t);r.parentNode.replaceChild(G(t),r);t.style.display="none";var q=function(){t.parentNode.removeChild(t)};I(j,"onload",q)}else{t.parentNode.replaceChild(G(t),t)}}function G(v){var u=a("div");if(h.win&&h.ie){u.innerHTML=v.innerHTML}else{var r=v.getElementsByTagName(Q)[0];if(r){var w=r.childNodes;if(w){var q=w.length;for(var t=0;t<q;t++){if(!(w[t].nodeType==1&&w[t].nodeName=="PARAM")&&!(w[t].nodeType==8)){u.appendChild(w[t].cloneNode(true))}}}}}return u}function U(AG,AE,t){var q,v=C(t);if(v){if(typeof AG.id==b){AG.id=t}if(h.ie&&h.win){var AF="";for(var AB in AG){if(AG[AB]!=Object.prototype[AB]){if(AB.toLowerCase()=="data"){AE.movie=AG[AB]}else{if(AB.toLowerCase()=="styleclass"){AF+=' class="'+AG[AB]+'"'}else{if(AB.toLowerCase()!="classid"){AF+=" "+AB+'="'+AG[AB]+'"'}}}}}var AD="";for(var AA in AE){if(AE[AA]!=Object.prototype[AA]){AD+='<param name="'+AA+'" value="'+AE[AA]+'" />'}}v.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+AF+">"+AD+"</object>";i[i.length]=AG.id;q=C(AG.id)}else{if(h.webkit&&h.webkit<312){var AC=a("embed");AC.setAttribute("type",P);for(var z in AG){if(AG[z]!=Object.prototype[z]){if(z.toLowerCase()=="data"){AC.setAttribute("src",AG[z])}else{if(z.toLowerCase()=="styleclass"){AC.setAttribute("class",AG[z])}else{if(z.toLowerCase()!="classid"){AC.setAttribute(z,AG[z])}}}}}for(var y in AE){if(AE[y]!=Object.prototype[y]){if(y.toLowerCase()!="movie"){AC.setAttribute(y,AE[y])}}}v.parentNode.replaceChild(AC,v);q=AC}else{var u=a(Q);u.setAttribute("type",P);for(var x in AG){if(AG[x]!=Object.prototype[x]){if(x.toLowerCase()=="styleclass"){u.setAttribute("class",AG[x])}else{if(x.toLowerCase()!="classid"){u.setAttribute(x,AG[x])}}}}for(var w in AE){if(AE[w]!=Object.prototype[w]&&w.toLowerCase()!="movie"){F(u,w,AE[w])}}v.parentNode.replaceChild(u,v);q=u}}}return q}function F(t,q,r){var u=a("param");u.setAttribute("name",q);u.setAttribute("value",r);t.appendChild(u)}function X(r){var q=C(r);if(q&&(q.nodeName=="OBJECT"||q.nodeName=="EMBED")){if(h.ie&&h.win){if(q.readyState==4){B(r)}else{j.attachEvent("onload",function(){B(r)})}}else{q.parentNode.removeChild(q)}}}function B(t){var r=C(t);if(r){for(var q in r){if(typeof r[q]=="function"){r[q]=null}}r.parentNode.removeChild(r)}}function C(t){var q=null;try{q=K.getElementById(t)}catch(r){}return q}function a(q){return K.createElement(q)}function I(t,q,r){t.attachEvent(q,r);d[d.length]=[t,q,r]}function c(t){var r=h.pv,q=t.split(".");q[0]=parseInt(q[0],10);q[1]=parseInt(q[1],10)||0;q[2]=parseInt(q[2],10)||0;return(r[0]>q[0]||(r[0]==q[0]&&r[1]>q[1])||(r[0]==q[0]&&r[1]==q[1]&&r[2]>=q[2]))?true:false}function V(v,r){if(h.ie&&h.mac){return }var u=K.getElementsByTagName("head")[0],t=a("style");t.setAttribute("type","text/css");t.setAttribute("media","screen");if(!(h.ie&&h.win)&&typeof K.createTextNode!=b){t.appendChild(K.createTextNode(v+" {"+r+"}"))}u.appendChild(t);if(h.ie&&h.win&&typeof K.styleSheets!=b&&K.styleSheets.length>0){var q=K.styleSheets[K.styleSheets.length-1];if(typeof q.addRule==Q){q.addRule(v,r)}}}function W(t,q){var r=q?"visible":"hidden";if(e&&C(t)){C(t).style.visibility=r}else{V("#"+t,"visibility:"+r)}}function g(s){var r=/[\\\"<>\.;]/;var q=r.exec(s)!=null;return q?encodeURIComponent(s):s}var D=function(){if(h.ie&&h.win){window.attachEvent("onunload",function(){var w=d.length;for(var v=0;v<w;v++){d[v][0].detachEvent(d[v][1],d[v][2])}var t=i.length;for(var u=0;u<t;u++){X(i[u])}for(var r in h){h[r]=null}h=null;for(var q in swfobject){swfobject[q]=null}swfobject=null})}}();return{registerObject:function(u,q,t){if(!h.w3cdom||!u||!q){return }var r={};r.id=u;r.swfVersion=q;r.expressInstall=t?t:false;N[N.length]=r;W(u,false)},getObjectById:function(v){var q=null;if(h.w3cdom){var t=C(v);if(t){var u=t.getElementsByTagName(Q)[0];if(!u||(u&&typeof t.SetVariable!=b)){q=t}else{if(typeof u.SetVariable!=b){q=u}}}}return q},embedSWF:function(x,AE,AB,AD,q,w,r,z,AC){if(!h.w3cdom||!x||!AE||!AB||!AD||!q){return }AB+="";AD+="";if(c(q)){W(AE,false);var AA={};if(AC&&typeof AC===Q){for(var v in AC){if(AC[v]!=Object.prototype[v]){AA[v]=AC[v]}}}AA.data=x;AA.width=AB;AA.height=AD;var y={};if(z&&typeof z===Q){for(var u in z){if(z[u]!=Object.prototype[u]){y[u]=z[u]}}}if(r&&typeof r===Q){for(var t in r){if(r[t]!=Object.prototype[t]){if(typeof y.flashvars!=b){y.flashvars+="&"+t+"="+r[t]}else{y.flashvars=t+"="+r[t]}}}}f(function(){U(AA,y,AE);if(AA.id==AE){W(AE,true)}})}else{if(w&&!A&&c("6.0.65")&&(h.win||h.mac)){A=true;W(AE,false);f(function(){var AF={};AF.id=AF.altContentId=AE;AF.width=AB;AF.height=AD;AF.expressInstall=w;k(AF)})}}},getFlashPlayerVersion:function(){return{major:h.pv[0],minor:h.pv[1],release:h.pv[2]}},hasFlashPlayerVersion:c,createSWF:function(t,r,q){if(h.w3cdom){return U(t,r,q)}else{return undefined}},removeSWF:function(q){if(h.w3cdom){X(q)}},createCSS:function(r,q){if(h.w3cdom){V(r,q)}},addDomLoadEvent:f,addLoadEvent:R,getQueryParamValue:function(v){var u=K.location.search||K.location.hash;if(v==null){return g(u)}if(u){var t=u.substring(1).split("&");for(var r=0;r<t.length;r++){if(t[r].substring(0,t[r].indexOf("="))==v){return g(t[r].substring((t[r].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(A&&M){var q=C(m);if(q){q.parentNode.replaceChild(M,q);if(l){W(l,true);if(h.ie&&h.win){M.style.display="block"}}M=null;l=null;A=false}}}}}();

//==============================
//END ./flash/swfobject.js
//==============================

//==============================
//BEGIN tooltip.js
//==============================

/*
* Copyright (c) 2006 Jonathan Weiss <jw@innerewut.de>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/


/* tooltip-0.1.js - Small tooltip library on top of Prototype 
* by Jonathan Weiss <jw@innerewut.de> distributed under the BSD license. 
*
* Unlike other libraries it does not declare its own tooltip 
* div or window. It relies on an already existing div or element defined by you to display as 
* the tooltip. This element will be placed (and shown) near the mouse pointer when a trigger-element is moused-over.
* 
*
* Usage: 
*   <script src="/javascripts/prototype.js" type="text/javascript"></script>
*   <script src="/javascripts/tooltip.js" type="text/javascript"></script>
*   <script type="text/javascript">
*     var my_tooltip = new Tooltip('id_of_trigger_element', 'id_of_tooltip_to_show_element')
*   </script>
* 
* Now whenever you trigger a mouseOver on the `trigger` element, the tooltip element will
* be shown. On o mouseOut the tooltip disappears. 
* 
* Example:
* 
*   <script src="/javascripts/prototype.js" type="text/javascript"></script>
*   <script src="/javascripts/scriptaculous.js" type="text/javascript"></script>
*   <script src="/javascripts/tooltip.js" type="text/javascript"></script>
*
*   <div id='tooltip' style="display:none; margin: 5px; background-color: red;">
*     Detail infos on product 1....<br />
*   </div>
*
*   <div id='product_1'>
*     This is product 1
*   </div>
*
*   <script type="text/javascript">
*     var my_tooltip = new Tooltip('product_1', 'tooltip')
*   </script>
*
* You can use my_tooltip.destroy() to remove the event observers and thereby the tooltip.
*/

var Tooltip = Class.create();
Tooltip.prototype = {
initialize: function(element, tool_tip) {
 var options = Object.extend({
   default_css: false,
   margin: "0px",
   padding: "5px",
   backgroundColor: "#d6d6fc",
   delta_x: 12,
   delta_y: -100,
   zindex: 1000
 }, arguments[1] || {});

 this.element      = $(element);
 this.tool_tip     = $(tool_tip);

 this.options      = options;

 // hide the tool-tip by default
 this.tool_tip.hide();

 this.eventMouseOver = this.showTooltip.bindAsEventListener(this);
 this.eventMouseOut   = this.hideTooltip.bindAsEventListener(this);

 this.registerEvents();
},

destroy: function() {
 Event.stopObserving(this.element, "mouseover", this.eventMouseOver);
 Event.stopObserving(this.element, "mouseout", this.eventMouseOut);
},

registerEvents: function() {
 Event.observe(this.element, "mouseover", this.eventMouseOver);
 Event.observe(this.element, "mouseout", this.eventMouseOut);
},

showTooltip: function(event){
 Event.stop(event);
 // get Mouse position
 var mouse_x = Event.pointerX(event);
 var mouse_y = Event.pointerY(event);
 
 
 // decide if wee need to switch sides for the tooltip
 var dimensions = Element.getDimensions( this.tool_tip );
 var element_width = dimensions.width;
 var element_height = dimensions.height;
 
 if ( (element_width + mouse_x) >= ( this.getWindowWidth() - this.options.delta_x) ){ // too big for X
     mouse_x = mouse_x - element_width;
     // apply delta to make sure that the mouse is not on the tool-tip
     mouse_x = mouse_x - this.options.delta_x;
 } else {
     mouse_x = mouse_x + this.options.delta_x;
 }
 
 if ( (element_height + mouse_y) >= ( this.getWindowHeight() - this.options.delta_y) ){ // too big for Y
     mouse_y = mouse_y - element_height;
     // apply delta to make sure that the mouse is not on the tool-tip
     mouse_y = mouse_y - this.options.delta_y;
 } else {
     mouse_y = mouse_y + this.options.delta_y;
 } 
 
 // now set the right styles
 this.setStyles(mouse_x, mouse_y);
 
     
 // finally show the Tooltip
 //new Effect.Appear(this.tool_tip);
 new Element.show(this.tool_tip);

},

setStyles: function(x, y){
 // set the right styles to position the tool tip
 Element.setStyle(this.tool_tip, { position:'absolute',
                                   top:y + "px",
                                   left:x + "px",
                                   zindex:this.options.zindex
                                 });
 
 // apply default theme if wanted
 if (this.options.default_css){
     Element.setStyle(this.tool_tip, { margin:this.options.margin,
                                       padding:this.options.padding,
                       backgroundColor:this.options.backgroundColor,
                                       zindex:this.options.zindex
                                     }); 
 }   
},

hideTooltip: function(event){
 //new Effect.Fade(this.tool_tip);
 new Element.hide(this.tool_tip);
},

getWindowHeight: function(){
 var innerHeight;
 if (navigator.appVersion.indexOf('MSIE')>0) {
     innerHeight = document.body.clientHeight;
 } else {
     innerHeight = window.innerHeight;
 }
 return innerHeight; 
},

getWindowWidth: function(){
 var innerWidth;
 if (navigator.appVersion.indexOf('MSIE')>0) {
     innerWidth = document.body.clientWidth;
 } else {
     innerWidth = window.innerWidth;
 }
 return innerWidth;  
}

}

//==============================
//END tooltip.js
//==============================
//==============================
//BEGIN register.js
//==============================

function updateContinueButtonPopup(div, biller) {
 var billerScreenShot = $('biller_screenshot'); 
 if(billerScreenShot!=null) {
     billerScreenShot.src = "/beta/style/shun/base/base/en/graphic/join/screenshots/" + biller.toLowerCase() + ".jpg";
 }
 if($('biller-name')!=null) {
     Element.update('biller-name', biller);
 }
}

function updateSelectedBiller(div, biller) {
	if($("jform:biller") != null) $("jform:biller").value = biller.toLowerCase();
}

function screenshotClick(div, biller, option) {
 var billerScreenShot = $('biller_screenshot'); 
 if(billerScreenShot!=null) {
     billerScreenShot.src = "/beta/style/shun/base/base/en/graphic/join/screenshots/" + biller.toLowerCase() + ".jpg";
 }
 $('jform:pay').value = option;
 $("jform:biller").value = biller.toLowerCase();
 // do not use prototype cssSelector here $$('a.biller'), it does not work in firefox
 unselect(div.parentNode.parentNode.childNodes);
 $('block-' + biller.toLowerCase()).addClassName("selected");
 $(biller.toLowerCase() + '-' + option).checked = true;
 Element.update('biller-name', biller);
}


function planClick(link) {

 // parse the plan from the link id
 var plan = link.id.substring(link.id.indexOf("-")+1);
  $("jform:selectedPlanId").value = plan;

 // do not use prototype cssSelector here $$('a.plan'), it does not work in firefox
 unselect(link.parentNode.childNodes);
 $('plan-' + plan).addClassName("selected");
 $('radio-' + plan).checked = true;

 var divs = document.getElementsByTagName('div');
 if (divs != null) {
     for (var i = 0; i < divs.length; i++) {
         if (divs[i].id.substring(0, 10) == 'upgradeDiv') {
             divs[i].style.display = 'none';
         } 
     }
 }
 
 var checkboxes = document.getElementsByTagName('input');
 if (checkboxes != null) {
 	for (var i = 0; i < checkboxes.length; i++) {
 	    if (checkboxes[i].type == 'checkbox') {
 	        checkboxes[i].checked = false;
 	    }
 	}
 }

 var upgradeDiv = document.getElementById("upgradeDiv_"+plan);    
 if (upgradeDiv!=null) {
     upgradeDiv.style.display = 'block';
 }    
}

function unselect(elms) {
 for(i=0; i<elms.length; i++) {
     // check for undefined is necessary for firefox since there are text nodes w/o id's
     if(elms[i].id != undefined) {
         $(elms[i].id).removeClassName("selected");
     }
 }
}

//==============================
//END register.js
//==============================

//==============================
//BEGIN validation.js
//==============================

/*
* Really easy field validation with Prototype
* http://tetlaw.id.au/view/javascript/really-easy-field-validation
* Andrew Tetlaw
* Version 1.5.4.1 (2007-01-05)
* 
* Copyright (c) 2007 Andrew Tetlaw
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 
*/
/*
* Added password-confirm and validate-length validations
* Huy Hong
*/
var Validator = Class.create();

Validator.prototype = {
 initialize : function(className, error, test, options) {
     if(typeof test == 'function'){
         this.options = $H(options);
         this._test = test;
     } else {
         this.options = $H(test);
         this._test = function(){return true};
     }
     this.error = error || 'Validation failed.';
     this.className = className;
 },
 test : function(v, elm) {
     return (this._test(v,elm) && this.options.all(function(p){
         return Validator.methods[p.key] ? Validator.methods[p.key](v,elm,p.value) : true;
     }));
 }
}
Validator.methods = {
 pattern : function(v,elm,opt) {return Validation.get('IsEmpty').test(v) || opt.test(v)},
 minLength : function(v,elm,opt) {return v.length >= opt},
 maxLength : function(v,elm,opt) {return v.length <= opt},
 min : function(v,elm,opt) {return v >= parseFloat(opt)}, 
 max : function(v,elm,opt) {return v <= parseFloat(opt)},
 notOneOf : function(v,elm,opt) {return $A(opt).all(function(value) {
     return v != value;
 })},
 oneOf : function(v,elm,opt) {return $A(opt).any(function(value) {
     return v == value;
 })},
 is : function(v,elm,opt) {return v == opt},
 isNot : function(v,elm,opt) {return v != opt},
 equalToField : function(v,elm,opt) {return v == $F(opt)},
 notEqualToField : function(v,elm,opt) {return v != $F(opt)},
 include : function(v,elm,opt) {return $A(opt).all(function(value) {
     return Validation.get(value).test(v,elm);
 })}
}

var Validation = Class.create();

Validation.prototype = {
 initialize : function(form, options){
     this.options = Object.extend({
         onSubmit : true,
         stopOnFirst : false,
         immediate : false,
         focusOnError : true,
         useTitles : false,
         onFormValidate : function(result, form) {},
         onElementValidate : function(result, elm) {}
     }, options || {});
     this.form = $(form);
     if(this.options.onSubmit) Event.observe(this.form,'submit',this.onSubmit.bind(this),false);
     if(this.options.immediate) {
         var useTitles = this.options.useTitles;
         var callback = this.options.onElementValidate;
         Form.getElements(this.form).each(function(input) { // Thanks Mike!
             Event.observe(input, 'blur', function(ev) { Validation.validate(Event.element(ev),{useTitle : useTitles, onElementValidate : callback}); });
         });
     }
 },
 onSubmit :  function(ev){
     if(!this.validate()) Event.stop(ev);
 },
 validate : function() {
     var result = false;
     var useTitles = this.options.useTitles;
     var callback = this.options.onElementValidate;
     if(this.options.stopOnFirst) {
         result = Form.getElements(this.form).all(function(elm) { return Validation.validate(elm,{useTitle : useTitles, onElementValidate : callback}); });
     } else {
         result = Form.getElements(this.form).collect(function(elm) { return Validation.validate(elm,{useTitle : useTitles, onElementValidate : callback}); }).all();
     }
     if(!result && this.options.focusOnError) {
         Form.getElements(this.form).findAll(function(elm){return $(elm).hasClassName('validation-failed')}).first().focus()
     }
     this.options.onFormValidate(result, this.form);
     return result;
 },
 reset : function() {
     Form.getElements(this.form).each(Validation.reset);
 }
}

Object.extend(Validation, {
 validate : function(elm, options){
     options = Object.extend({
         useTitle : false,
         onElementValidate : function(result, elm) {}
     }, options || {});
     elm = $(elm);
     var cn = elm.classNames();
     return result = cn.all(function(value) {
         var test = Validation.test(value,elm,options.useTitle);
         options.onElementValidate(test, elm);
         return test;
     });
 },
 test : function(name, elm, useTitle) {
     var v = Validation.get(name);
     var prop = '__advice'+name.camelize();
     try {
     if(Validation.isVisible(elm) && !v.test($F(elm), elm)) {
         if(!elm[prop]) {
             var advice = Validation.getAdvice(name, elm);
             if(advice == null) {
                 var errorMsg = useTitle ? ((elm && elm.title) ? elm.title : v.error) : v.error;
                 advice = '<div class="validation-advice" id="advice-' + name + '-' + Validation.getElmID(elm) +'" style="display:none">' + errorMsg + '</div>'
                 switch (elm.type.toLowerCase()) {
                     case 'checkbox':
                     case 'radio':
                         var p = elm.parentNode;
                         if(p) {
                             new Insertion.Bottom(p, advice);
                         } else {
                             new Insertion.After(elm, advice);
                         }
                         break;
                     default:
                         new Insertion.After(elm, advice);
                 }
                 advice = Validation.getAdvice(name, elm);
             }
             if(typeof Effect == 'undefined') {
                 advice.style.display = 'block';
             } else {
                 new Effect.Appear(advice, {duration : 1 });
             }
         }
         elm[prop] = true;
         elm.removeClassName('validation-passed');
         elm.addClassName('validation-failed');
         return false;
     } else {
         var advice = Validation.getAdvice(name, elm);
         if(advice != null) advice.hide();
         elm[prop] = '';
         elm.removeClassName('validation-failed');
         elm.addClassName('validation-passed');
         return true;
     }
     } catch(e) {
         throw(e);
     }
 },
 isVisible : function(elm) {
     while(elm.tagName != 'BODY') {
         if(!$(elm).visible()) return false;
         elm = elm.parentNode;
     }
     return true;
 },
 getAdvice : function(name, elm) {
     return $('advice-' + name + '-' + Validation.getElmID(elm)) || $('advice-' + Validation.getElmID(elm));
 },
 getElmID : function(elm) {
     return elm.id ? elm.id : elm.name;
 },
 reset : function(elm) {
     elm = $(elm);
     var cn = elm.classNames();
     cn.each(function(value) {
         var prop = '__advice'+value.camelize();
         if(elm[prop]) {
             var advice = Validation.getAdvice(value, elm);
             advice.hide();
             elm[prop] = '';
         }
         elm.removeClassName('validation-failed');
         elm.removeClassName('validation-passed');
     });
 },
 add : function(className, error, test, options) {
     var nv = {};
     nv[className] = new Validator(className, error, test, options);
     Object.extend(Validation.methods, nv);
 },
 addAllThese : function(validators) {
     var nv = {};
     $A(validators).each(function(value) {
             nv[value[0]] = new Validator(value[0], value[1], value[2], (value.length > 3 ? value[3] : {}));
         });
     Object.extend(Validation.methods, nv);
 },
 get : function(name) {
     return  Validation.methods[name] ? Validation.methods[name] : Validation.methods['_LikeNoIDIEverSaw_'];
 },
 methods : {
     '_LikeNoIDIEverSaw_' : new Validator('_LikeNoIDIEverSaw_','',{})
 }
});

Validation.add('IsEmpty', '', function(v) {
             return  ((v == null) || (v.length == 0)); // || /^\s+$/.test(v));
         });

Validation.add('IsShortLong', '', function(v) {
             return ((v == null) || (v.length < 4 | v.length > 16) || /^\s+$/.test(v));
         });

Validation.addAllThese([
 ['required', msg_validation_required_field, function(v) {
             return !Validation.get('IsEmpty').test(v);
         }],
 ['password-confirm', msg_validation_passwords_dont_match, function(v) {
             if($F('jform:pass1:pass1') != $F('jform:pass2:pass2')) {
               if(passwordCheck == 1) {
                 $('advice-password-confirm-confirm').hide();
                 passwordCheck = 0;
               }
               return false;
             }
             else {
                 passwordCheck = 2;
                 return !Validation.get('IsEmpty').test(v);
             }
         }],
 ['validate-length-password', msg_validation_choose_password, function(v) {
             return !Validation.get('IsShortLong').test(v);
     }],
 ['validate-length-username', msg_validation_choose_username, function(v) {
             return !Validation.get('IsShortLong').test(v);
     }],
 ['validate-number', msg_validation_number, function(v) {
             return Validation.get('IsEmpty').test(v) || (!isNaN(v) && !/^\s+$/.test(v));
         }],
 ['validate-digits', msg_validation_numbers_only, function(v) {
             return Validation.get('IsEmpty').test(v) ||  !/[^\d]/.test(v);
         }],
 ['validate-alpha', msg_validation_letters_only, function (v) {
             return Validation.get('IsEmpty').test(v) ||  /^[a-zA-Z]+$/.test(v)
         }],
 ['validate-alphanum', msg_validation_letters_or_numbers, function(v) {
             return Validation.get('IsEmpty').test(v) ||  !/\W/.test(v)
         }],
 ['validate-date', msg_validation_date, function(v) {
             var test = new Date(v);
             return Validation.get('IsEmpty').test(v) || !isNaN(test);
         }],
 ['validate-email', msg_validation_email, function (v) {
             return Validation.get('IsEmpty').test(v) || /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(v)
         }],
 ['validate-url', msg_validation_url, function (v) {
             return Validation.get('IsEmpty').test(v) || /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(v)
         }],
 ['validate-date-au', msg_validation_date_format, function(v) {
             if(Validation.get('IsEmpty').test(v)) return true;
             var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;
             if(!regex.test(v)) return false;
             var d = new Date(v.replace(regex, '$2/$1/$3'));
             return ( parseInt(RegExp.$2, 10) == (1+d.getMonth()) ) && 
                         (parseInt(RegExp.$1, 10) == d.getDate()) && 
                         (parseInt(RegExp.$3, 10) == d.getFullYear() );
         }],
 ['validate-currency-dollar', msg_validation_currency_amount, function(v) {
             // [$]1[##][,###]+[.##]
             // [$]1###+[.##]
             // [$]0.##
             // [$].##
             return Validation.get('IsEmpty').test(v) ||  /^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/.test(v)
         }],
 ['validate-selection', msg_validation_selection, function(v,elm){
             return elm.options ? elm.selectedIndex > 0 : !Validation.get('IsEmpty').test(v);
         }],
 ['validate-one-required', msg_validation_select_option, function (v,elm) {
             var p = elm.parentNode;
             var options = p.getElementsByTagName('INPUT');
             return $A(options).any(function(elm) {
                 return $F(elm);
             });
         }]
]);
//==============================
//END validation.js
//==============================


//Download UI Help Tooltip
//==============================
function showDownloadUIHelpToolTip (contentID) {
 if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)){ //test for MSIE x.x;
   if (document.getElementById('panel')) {
     document.getElementById('panel').style.zIndex = '-1';
   }
   if (document.getElementById('toggle')) {
     document.getElementById('toggle').style.display = 'none';
   }
 }
 document.getElementById('htt_' + contentID).style.display='block';
}

function hideDownloadUIHelpToolTip (contentID) {
 if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)){ //test for MSIE x.x;
   if (document.getElementById('panel')) {
     document.getElementById('panel').style.zIndex = '';
   }
   if (document.getElementById('toggle')) {
     document.getElementById('toggle').style.display = '';
   }
 }
 document.getElementById('htt_' + contentID).style.display='none';
}
//==============================

function toggleDisplay(id){
	  if(document.getElementById(id).style.display == 'none'){
		  document.getElementById(id).style.display = 'block';
	  }else{
		  document.getElementById(id).style.display = 'none';
	  }
}


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

	};
BrowserDetect.init();

//replacement for innerHTML with XML content
//IE removes quotes 
function myInnerHTML(node) {
 
 // internet explorer's innerHTML is craptastic so we use some hackery to fix it
 //if(navigator.appVersion.indexOf("MSIE") != -1 && navigator.appVersion.indexOf("Windows") > -1){
     // BUG: self-closing <a> tags don't work , e.g "<a name='inline' />"
     
     var reTag = /(<\/?\w+)([^>]*>)/g;
     var reAttr = /(\w+=)((['"])[\s\S]*\3|[^\s>]+)/g;
     var str = node.innerHTML;
         
     function fixAttr($0, $1, $2, $3) {
         if ($3) return $1.toLowerCase() + $2;
         else return $1.toLowerCase() + '"' + $2 + '"'
     }       

     function fixTag($0, $1, $2) {
         return $1.toLowerCase() + $2.replace(reAttr, fixAttr);
     }

     // clean up tags (make html tags and attributes lowercase)
     str = str.replace(reTag, fixTag);

     // make sure self-closing tags are closed 
     var reSelfClosing = new RegExp("\<(area|base|basefont|br|hr|img|input)(.*?)>", "g");
     
     str = str.replace(reSelfClosing, "<$1$2/>");
     
     // IE's treatment of UL's and DL's is mind boggling.
     // Dan's big brain came up with this series of search/replaces that fixes them.  you go dan.  
     str = str.replace(/<\/li>|<\/dt>/g, "");                            // get rid of all closing li and dt tags (for IE)
     str = str.replace(/\s*<li([^>]*)>/g, "<\/li><li$1>");       // put a closing li in front of all opening li
     str = str.replace(/<\/ul>/g, "<\/li><\/ul>");                   // put a closing li in front of closing ul
     str = str.replace(/<ul([^>]*)>\s*<\/li>/g, "<ul$1>");       // remove closing li's that appear directly after opening ul
     str = str.replace(/\s*<dd([^>]*)>/g, "<\/dt><dd$1>");   // put a closing dt in front of all opening dd's
     //end dan hackery       
     return str;
 //} else {
 //  return node.innerHTML;
 //}
}

function toggleDiv(tLink,tDiv,ltext1,ltext2) {
   var display = document.getElementById(tDiv).style.display;
   if(display == "none") {
       document.getElementById(tDiv).style.display = "block";
       setInnerHTML(tLink, ltext1);
   } else {
       document.getElementById(tDiv).style.display = "none";
       setInnerHTML(tLink, ltext2);
   }
}

function toggleCategoryPop(tDiv) {
	var flashPlayerDiv = document.getElementById('flashcontent');
	if(document.getElementById(tDiv).style.display == "none") {
		document.getElementById(tDiv).style.display = "block";
		if(navigator.appVersion.indexOf('Windows') > -1 && flashPlayerDiv != null && Element.hasClassName(flashPlayerDiv, 'player')) {
			var flashMargin = document.getElementById(tDiv).offsetHeight - 10;
			if(Element.hasClassName(flashPlayerDiv, 'star0')) {
				flashMargin = (flashMargin - 66);
			} else if(Element.hasClassName(flashPlayerDiv, 'starTemplate')) {
				flashMargin = (flashMargin - 147);
			}
			flashPlayerDiv.style.marginTop = flashMargin + "px";
		}	
	} else {
		document.getElementById(tDiv).style.display = "none";
		if(navigator.appVersion.indexOf('Windows') > -1 && flashPlayerDiv != null && Element.hasClassName(flashPlayerDiv, 'player')) {
			flashPlayerDiv.style.marginTop = "0";
		}
 }
}

function hidePop(tDiv, event) {
	var curMouseTarget = null;
	if(event.toElement) {				
		curMouseTarget = event.toElement;
	} else if(event.relatedTarget) {				
		curMouseTarget = event.relatedTarget;
	}
	if(!isChildOf(tDiv, curMouseTarget) && tDiv != curMouseTarget) {
		tDiv.style.display = "none";
		if(navigator.appVersion.indexOf('Windows') > -1 && document.getElementById('flashcontent') != null && document.getElementById('flashcontent').className.indexOf('player')) {
			document.getElementById('flashcontent').style.marginTop = "0";
		}
	}	
}

function isChildOf(parent, child) {
	if( child != null ) {			
		while( child.parentNode ) {
			if( (child = child.parentNode) == parent ) {
				return true;
			}
		}
	}
	return false;
}

//==============================
//BEGIN Modal Div Popups
//Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
//==============================
var Util = {'$VERSION':1.06};

//Determine if an object is an array
function isArray(o) {
	return (o!=null && typeof(o)=="object" && typeof(o.length)=="number" && (o.length==0 || defined(o[0])));
};

//Determine if an object is an Object
function isObject(o) {
	return (o!=null && typeof(o)=="object" && defined(o.constructor) && o.constructor==Object && !defined(o.nodeName));
};

//Determine if a reference is defined
function defined(o) {
	return (typeof(o)!="undefined");
};

//Iterate over an array, object, or list of items and run code against each item
//Similar functionality to Perl's map() function
function map(func) {
	var i,j,o;
	var results = [];
	if (typeof(func)=="string") {
		func = new Function('$_',func);
	}
	for (i=1; i<arguments.length; i++) {
		o = arguments[i];
		if (isArray(o)) {
			for (j=0; j<o.length; j++) {
				results[results.length] = func(o[j]);
			}
		}
		else if (isObject(o)) {
			for (j in o) {
				results[results.length] = func(o[j]);
			}
		}
		else {
			results[results.length] = func(o);
		}
	}
	return results;
};

//Set default values in an object if they are undefined
function setDefaultValues(o,values) {
	if (!defined(o) || o==null) {
		o = {};
	}
	if (!defined(values) || values==null) {
		return o;
	}
	for (var val in values) {
		if (!defined(o[val])) {
			o[val] = values[val];
		}
	}
	return o;
};

//These functions add useful functionality to built-in objects
Array.prototype.contains = function(o) {
	var i,l;
	if (!(l = this.length)) { return false; }
	for (i=0; i<l; i++) {
		if (o==this[i]) {
			return true;
		}
	}
};

var DOM = (function() { 
	var dom = {};
	
	// Get a parent tag with a given nodename
	dom.getParentByTagName = function(o,tagNames) {
		if(o==null) { return null; }
		if (isArray(tagNames)) {
			tagNames = map("return $_.toUpperCase()",tagNames);
			while (o=o.parentNode) {
				if (o.nodeName && tagNames.contains(o.nodeName)) {
					return o;
				}
			}
		}
		else {
			tagNames = tagNames.toUpperCase();
			while (o=o.parentNode) {
				if (o.nodeName && tagNames==o.nodeName) {
					return o;
				}
			}
		}
		return null;
	};
	
	// Remove a node from its parent
	dom.removeNode = function(o) {
		if (o!=null && o.parentNode && o.parentNode.removeChild) {
			// First remove all attributes which are func references, to avoid memory leaks
			for (var i in o) {
				if (typeof(o[i])=="function") {
					o[i] = null;
				}
			}
			o.parentNode.removeChild(o);
			return true;
		}
		return false;
	};

	// Get the outer width in pixels of an object, including borders, padding, and margin
	dom.getOuterWidth = function(o) {
		if (defined(o.offsetWidth)) {
			return o.offsetWidth;
		}
		return null;
	};

	// Get the outer height in pixels of an object, including borders, padding, and margin
	dom.getOuterHeight = function(o) {
		if (defined(o.offsetHeight)) {
			return o.offsetHeight;
		}
		return null;
	};

	// Resolve an item, an array of items, or an object of items
	dom.resolve = function() {
		var results = new Array();
		var i,j,o;
		for (var i=0; i<arguments.length; i++) {
			var o = arguments[i];
			if (o==null) {
				if (arguments.length==1) {
					return null;
				}
				results[results.length] = null;
			}
			else if (typeof(o)=='string') {
				if (document.getElementById) {
					o = document.getElementById(o);
				}
				else if (document.all) {
					o = document.all[o];
				}
				if (arguments.length==1) {
					return o;
				}
				results[results.length] = o;
			}
			else if (isArray(o)) {
				for (j=0; j<o.length; j++) {
					results[results.length] = o[j];
				}
			}
			else if (isObject(o)) {
				for (j in o) {
					results[results.length] = o[j];
				}
			}
			else if (arguments.length==1) {
				return o;
			}
			else {
				results[results.length] = o;
			}
	  }
	  return results;
	};
	dom.$ = dom.resolve;
	
	return dom;
})();

var CSS = (function(){
	var css = {};

	// Convert an RGB string in the form "rgb (255, 255, 255)" to "#ffffff"
	css.rgb2hex = function(rgbString) {
		if (typeof(rgbString)!="string" || !defined(rgbString.match)) { return null; }
		var result = rgbString.match(/^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*/);
		if (result==null) { return rgbString; }
		var rgb = +result[1] << 16 | +result[2] << 8 | +result[3];
		var hex = "";
		var digits = "0123456789abcdef";
		while(rgb!=0) { 
			hex = digits.charAt(rgb&0xf)+hex; 
			rgb>>>=4; 
		} 
		while(hex.length<6) { hex='0'+hex; }
		return "#" + hex;
	};

	// Convert hyphen style names like border-width to camel case like borderWidth
	css.hyphen2camel = function(property) {
		if (!defined(property) || property==null) { return null; }
		if (property.indexOf("-")<0) { return property; }
		var str = "";
		var c = null;
		var l = property.length;
		for (var i=0; i<l; i++) {
			c = property.charAt(i);
			str += (c!="-")?c:property.charAt(++i).toUpperCase();
		}
		return str;
	};
	
	// Determine if an object or class string contains a given class.
	css.hasClass = function(obj,className) {
		if (!defined(obj) || obj==null || !RegExp) { return false; }
		var re = new RegExp("(^|\\s)" + className + "(\\s|$)");
		if (typeof(obj)=="string") {
			return re.test(obj);
		}
		else if (typeof(obj)=="object" && obj.className) {
			return re.test(obj.className);
		}
		return false;
	};
	
	// Add a class to an object
	css.addClass = function(obj,className) {
		if (typeof(obj)!="object" || obj==null || !defined(obj.className)) { return false; }
		if (obj.className==null || obj.className=='') { 
			obj.className = className; 
			return true; 
		}
		if (css.hasClass(obj,className)) { return true; }
		obj.className = obj.className + " " + className;
		return true;
	};
	
	// Remove a class from an object
	css.removeClass = function(obj,className) {
		if (typeof(obj)!="object" || obj==null || !defined(obj.className) || obj.className==null) { return false; }
		if (!css.hasClass(obj,className)) { return false; }
		var re = new RegExp("(^|\\s+)" + className + "(\\s+|$)");
		obj.className = obj.className.replace(re,' ');
		return true;
	};
	
	// Fully replace a class with a new one
	css.replaceClass = function(obj,className,newClassName) {
		if (typeof(obj)!="object" || obj==null || !defined(obj.className) || obj.className==null) { return false; }
		css.removeClass(obj,className);
		css.addClass(obj,newClassName);
		return true;
	};
	
	// Get the currently-applied style of an object
	css.getStyle = function(o, property) {
		if (o==null) { return null; }
		var val = null;
		var camelProperty = css.hyphen2camel(property);
		// Handle "float" property as a special case
		if (property=="float") {
			val = css.getStyle(o,"cssFloat");
			if (val==null) { 
				val = css.getStyle(o,"styleFloat"); 
			}
		}
		else if (o.currentStyle && defined(o.currentStyle[camelProperty])) {
			val = o.currentStyle[camelProperty];
		}
		else if (window.getComputedStyle) {
			val = window.getComputedStyle(o,null).getPropertyValue(property);
		}
		else if (o.style && defined(o.style[camelProperty])) {
			val = o.style[camelProperty];
		}
		// For color values, make the value consistent across browsers
		// Convert rgb() colors back to hex for consistency
		if (/^\s*rgb\s*\(/.test(val)) {
			val = css.rgb2hex(val);
		}
		// Lowercase all #hex values
		if (/^#/.test(val)) {
			val = val.toLowerCase();
		}
		return val;
	};
	css.get = css.getStyle;

	// Set a style on an object
	css.setStyle = function(o, property, value) {
		if (o==null || !defined(o.style) || !defined(property) || property==null || !defined(value)) { return false; }
		if (property=="float") {
			o.style["cssFloat"] = value;
			o.style["styleFloat"] = value;
		}
		else if (property=="opacity") {
			o.style['-moz-opacity'] = value;
			o.style['-khtml-opacity'] = value;
			o.style.opacity = value;
			if (defined(o.style.filter)) {
				o.style.filter = "alpha(opacity=" + value*100 + ")";
			}
		}
		else {
			o.style[css.hyphen2camel(property)] = value;
		}
		return true;
	};
	css.set = css.setStyle;
	
	// Get a unique ID which doesn't already exist on the page
	css.uniqueIdNumber=1000;
	css.createId = function(o) {
		if (defined(o) && o!=null && defined(o.id) && o.id!=null && o.id!="") { 
			return o.id;
		}
		var id = null;
		while (id==null || document.getElementById(id)!=null) {
			id = "ID_"+(css.uniqueIdNumber++);
		}
		if (defined(o) && o!=null && (!defined(o.id)||o.id=="")) {
			o.id = id;
		}
		return id;
	};
	
	return css;
})();

var mEvent = (function(){
	var ev = {};
	
	// Resolve an event using IE's window.event if necessary
	ev.resolve = function(e) {
		if (!defined(e) && defined(window.event)) {
			e = window.event;
		}
		return e;
	};
	
	// Add an event handler to a function
	// Note: Don't use 'this' within functions added using this method, since
	// the attachEvent and addEventListener models differ.
	ev.add = function( obj, type, fn, capture ) {
		if (obj.addEventListener) {
			obj.addEventListener( type, fn, capture );
			return true;
		}
		else if (obj.attachEvent) {
			obj.attachEvent( "on"+type, fn );
			return true;
		}
		return false;
	};

	// Get the mouse position of an event
	// PageX/Y, where they exist, are more reliable than ClientX/Y because 
	// of some browser bugs in Opera/Safari
	ev.getMouseX = function(e) {
		e = ev.resolve(e);
		if (defined(e.pageX)) {
			return e.pageX;
		}
		if (defined(e.clientX)) {
			return e.clientX+Screen.getScrollLeft();
		}
		return null;
	};
	ev.getMouseY = function(e) {
		e = ev.resolve(e);
		if (defined(e.pageY)) {
			return e.pageY;
		}
		if (defined(e.clientY)) {
			return e.clientY+Screen.getScrollTop();
		}
		return null;
	};

	// Stop the event from bubbling up to parent elements.
	// Two method names map to the same function
	ev.cancelBubble = function(e) {
		e = ev.resolve(e);
		if (typeof(e.stopPropagation)=="function") { e.stopPropagation(); } 
		if (defined(e.cancelBubble)) { e.cancelBubble = true; }
	};
	ev.stopPropagation = ev.cancelBubble;

	// Prevent the default handling of the event to occur
	ev.preventDefault = function(e) {
		e = ev.resolve(e);
		if (typeof(e.preventDefault)=="function") { e.preventDefault(); } 
		if (defined(e.returnValue)) { e.returnValue = false; }
	};
	
	return ev;
})();

var Screen = (function() {
	var screen = {};

	// Get a reference to the body
	screen.getBody = function() {
		if (document.body) {
			return document.body;
		}
		if (document.getElementsByTagName) {
			var bodies = document.getElementsByTagName("BODY");
			if (bodies!=null && bodies.length>0) {
				return bodies[0];
			}
		}
		return null;
	};

	// Get the amount that the main document has scrolled from top
	screen.getScrollTop = function() {
		if (document.documentElement && defined(document.documentElement.scrollTop) && document.documentElement.scrollTop>0) {
			return document.documentElement.scrollTop;
		}
		if (document.body && defined(document.body.scrollTop)) {
			return document.body.scrollTop;
		}
		return null;
	};
	
	// Get the amount that the main document has scrolled from left
	screen.getScrollLeft = function() {
		if (document.documentElement && defined(document.documentElement.scrollLeft) && document.documentElement.scrollLeft>0) {
			return document.documentElement.scrollLeft;
		}
		if (document.body && defined(document.body.scrollLeft)) {
			return document.body.scrollLeft;
		}
		return null;
	};
	
	// Util function to default a bad number to 0
	screen.zero = function(n) {
		return (!defined(n) || isNaN(n))?0:n;
	};

	// Get the width of the entire document
	screen.getDocumentWidth = function() {
		var width = 0;
		var body = screen.getBody();
		if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
		    var rightMargin = parseInt(CSS.get(body,'marginRight'),10) || 0;
		    var leftMargin = parseInt(CSS.get(body,'marginLeft'), 10) || 0;
			width = Math.max(body.offsetWidth + leftMargin + rightMargin, document.documentElement.clientWidth);
		}
		else {
			width =  Math.max(body.clientWidth, body.scrollWidth);
		}
		if (isNaN(width) || width==0) {
			width = screen.zero(self.innerWidth);
		}
		return width;
	};
	
	// Get the height of the entire document
	screen.getDocumentHeight = function() {
		var body = screen.getBody();
		var innerHeight = (defined(self.innerHeight)&&!isNaN(self.innerHeight))?self.innerHeight:0;
		if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
		    var topMargin = parseInt(CSS.get(body,'marginTop'),10) || 0;
		    var bottomMargin = parseInt(CSS.get(body,'marginBottom'), 10) || 0;
			return Math.max(body.offsetHeight + topMargin + bottomMargin, document.documentElement.clientHeight, document.documentElement.scrollHeight, screen.zero(self.innerHeight));
		}
		return Math.max(body.scrollHeight, body.clientHeight, screen.zero(self.innerHeight));
	};
	
	// Get the width of the viewport (viewable area) in the browser window
	screen.getViewportWidth = function() {
		if (document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
			return document.documentElement.clientWidth;
		}
		else if (document.compatMode && document.body) {
			return document.body.clientWidth;
		}
		return screen.zero(self.innerWidth);
	};
	
	// Get the height of the viewport (viewable area) in the browser window
	screen.getViewportHeight = function() {
		if (!window.opera && document.documentElement && (!document.compatMode || document.compatMode=="CSS1Compat")) {
			return document.documentElement.clientHeight;
		}
		else if (document.compatMode && !window.opera && document.body) {
			return document.body.clientHeight;
		}
		return screen.zero(self.innerHeight);
	};

	return screen;
})();var Sort = (function(){
	var sort = {};
	sort.AlphaNumeric = function(a,b) {
		if (a==b) { return 0; }
		if (a<b) { return -1; }
		return 1;
	};

	sort.Default = sort.AlphaNumeric;
	
	sort.NumericConversion = function(val) {
		if (typeof(val)!="number") {
			if (typeof(val)=="string") {
				val = parseFloat(val.replace(/,/g,''));
				if (isNaN(val) || val==null) { val=0; }
			}
			else {
				val = 0;
			}
		}
		return val;
	};
	
	sort.Numeric = function(a,b) {
		return sort.NumericConversion(a)-sort.NumericConversion(b);
	};

	sort.IgnoreCaseConversion = function(val) {
		if (val==null) { val=""; }
		return (""+val).toLowerCase();
	};

	sort.IgnoreCase = function(a,b) {
		return sort.AlphaNumeric(sort.IgnoreCaseConversion(a),sort.IgnoreCaseConversion(b));
	};

	sort.CurrencyConversion = function(val) {
		if (typeof(val)=="string") {
			val = val.replace(/^[^\d\.]/,'');
		}
		return sort.NumericConversion(val);
	};
	
	sort.Currency = function(a,b) {
		return sort.Numeric(sort.CurrencyConversion(a),sort.CurrencyConversion(b));
	};
	
	sort.DateConversion = function(val) {
		// inner util function to parse date formats
		function getdate(str) {
			// inner util function to convert 2-digit years to 4
			function fixYear(yr) {
				yr = +yr;
				if (yr<50) { yr += 2000; }
				else if (yr<100) { yr += 1900; }
				return yr;
			};
			var ret;
			// YYYY-MM-DD
			if (ret=str.match(/(\d{2,4})-(\d{1,2})-(\d{1,2})/)) {
				return (fixYear(ret[1])*10000) + (ret[2]*100) + (+ret[3]);
			}
			// MM/DD/YY[YY] or MM-DD-YY[YY]
			if (ret=str.match(/(\d{1,2})[\/-](\d{1,2})[\/-](\d{2,4})/)) {
				return (fixYear(ret[3])*10000) + (ret[1]*100) + (+ret[2]);
			}
			return 99999999; // So non-parsed dates will be last, not first
		};
		return getdate(val);
	};

	sort.Date = function(a,b) {
		return sort.Numeric(sort.DateConversion(a),sort.DateConversion(b));
	};

	return sort;
})();

var mPosition = (function() {
	// Resolve a string identifier to an object
	function resolveObject(s) {
		if (document.getElementById && document.getElementById(s)!=null) {
			return document.getElementById(s);
		}
		else if (document.all && document.all[s]!=null) {
			return document.all[s];
		}
		else if (document.anchors && document.anchors.length && document.anchors.length>0 && document.anchors[0].x) {
			for (var i=0; i<document.anchors.length; i++) {
				if (document.anchors[i].name==s) { 
					return document.anchors[i]
				}
			}
		}
	}
	
	var pos = {};
	pos.$VERSION = 1.0;
	
	// Set the position of an object
	pos.set = function(o,left,top) {
		if (typeof(o)=="string") {
			o = resolveObject(o);
		}
		if (o==null || !o.style) {
			return false;
		}
		
		// If the second parameter is an object, it is assumed to be the result of getPosition()
		if (typeof(left)=="object") {
			var pos = left;
			left = pos.left;
			top = pos.top;
		}
		
		o.style.left = left + "px";
		o.style.top = top + "px";
		return true;
	};
	
	// Retrieve the position and size of an object
	pos.get = function(o) {
		var fixBrowserQuirks = true;
			// If a string is passed in instead of an object ref, resolve it
		if (typeof(o)=="string") {
			o = resolveObject(o);
		}
		
		if (o==null) {
			return null;
		}
		
		var left = 0;
		var top = 0;
		var width = 0;
		var height = 0;
		var parentNode = null;
		var offsetParent = null;
	
		
		offsetParent = o.offsetParent;
		var originalObject = o;
		var el = o; // "el" will be nodes as we walk up, "o" will be saved for offsetParent references
		while (el.parentNode!=null) {
			el = el.parentNode;
			if (el.offsetParent==null) {
			}
			else {
				var considerScroll = true;
				/*
				In Opera, if parentNode of the first object is scrollable, then offsetLeft/offsetTop already 
				take its scroll position into account. If elements further up the chain are scrollable, their 
				scroll offsets still need to be added in. And for some reason, TR nodes have a scrolltop value
				which must be ignored.
				*/
				if (fixBrowserQuirks && window.opera) {
					if (el==originalObject.parentNode || el.nodeName=="TR") {
						considerScroll = false;
					}
				}
				if (considerScroll) {
					if (el.scrollTop && el.scrollTop>0) {
						top -= el.scrollTop;
					}
					if (el.scrollLeft && el.scrollLeft>0) {
						left -= el.scrollLeft;
					}
				}
			}
			// If this node is also the offsetParent, add on the offsets and reset to the new offsetParent
			if (el == offsetParent) {
				left += o.offsetLeft;
				if (el.clientLeft && el.nodeName!="TABLE") { 
					left += el.clientLeft;
				}
				top += o.offsetTop;
				if (el.clientTop && el.nodeName!="TABLE") {
					top += el.clientTop;
				}
				o = el;
				if (o.offsetParent==null) {
					if (o.offsetLeft) {
						left += o.offsetLeft;
					}
					if (o.offsetTop) {
						top += o.offsetTop;
					}
				}
				offsetParent = o.offsetParent;
			}
		}
		
	
		if (originalObject.offsetWidth) {
			width = originalObject.offsetWidth;
		}
		if (originalObject.offsetHeight) {
			height = originalObject.offsetHeight;
		}
		
		return {'left':left, 'top':top, 'width':width, 'height':height
				};
	};
	
	// Retrieve the position of an object's center point
	pos.getCenter = function(o) {
		var c = this.get(o);
		if (c==null) { return null; }
		c.left = c.left + (c.width/2);
		c.top = c.top + (c.height/2);
		return c;
	};
	
	return pos;
})();// CLASS CONSTRUCTOR

var Popup = function(div, options) {
	this.div = defined(div)?div:null;
	this.index = Popup.maxIndex++;
	this.ref = "Popup.objects["+this.index+"]";
	Popup.objects[this.index] = this;
	// Store a reference to the DIV by id, also
	if (typeof(this.div)=="string") {
		Popup.objectsById[this.div] = this;
	}
	if (defined(this.div) && this.div!=null && defined(this.div.id)) {
		Popup.objectsById[this.div.id] = this.div.id;
	}
	// Apply passed-in options
	if (defined(options) && options!=null && typeof(options)=="object") {
		for (var i in options) {
			this[i] = options[i];
		}
	}
	return this;
};

//CLASS PROPERTIES
//Index of popup objects, to maintain a global reference if necessary
Popup.maxIndex = 0;
Popup.objects = {};
Popup.objectsById = {};

//The z-index value that popups will start at
Popup.minZIndex = 1001;

//Class names to assign to other objects
Popup.screenClass = "PopupScreen";
Popup.iframeClass = "PopupIframe";
Popup.screenIframeClass = "PopupScreenIframe";

//CLASS METHODS
//Hide all currently-visible non-modal dialogs
Popup.hideAll = function() {
	for (var i in Popup.objects) {
		var p = Popup.objects[i];
		if (!p.modal && p.autoHide) {
			p.hideMe();
		}
	}
};
//Catch global events as a trigger to hide auto-hide popups
mEvent.add(document, "mouseup", Popup.hideAll, false);

//A simple class method to show a popup without creating an instance
Popup.show = function(divObject, referenceObject, position, options, modal) {
	var popup;
	if (defined(divObject)) { 
		popup = new Popup(divObject);
	}
	else {
		popup = new Popup();
		popup.destroyDivOnHide = true;
	}
	if (defined(referenceObject)) { popup.reference = DOM.resolve(referenceObject); }
	if (defined(position)) { popup.position = position; }
	if (defined(options) && options!=null && typeof(options)=="object") {
		for (var i in options) {
			popup[i] = options[i];
		}
	}
	if (typeof(modal)=="boolean") {
		popup.modal = modal;
	}
	popup.destroyObjectsOnHide = true;
	popup.show();
	return popup;
};

//A simple class method to show a modal popup
Popup.showModal = function(divObject, referenceObject, position, options) {
	Popup.show(divObject, referenceObject, position, options, true);
};

//A method to retrieve a popup object based on a div ID
Popup.get = function(divId) {
	if (defined(Popup.objectsById[divId])) {
		return Popup.objectsById[divId];
	}
	return null;
};

//A method to hide a popup based on a div id
Popup.hide = function(divId) {
	var popup = Popup.get(divId);
	if (popup!=null) {
		popup.hideMe();
	}
};

//PROTOTYPE PROPERTIES
Popup.prototype.content = null;
Popup.prototype.className = "PopupDiv";
Popup.prototype.style = null; // Styles to be applied to the DIV
Popup.prototype.width = null;
Popup.prototype.height = null;
Popup.prototype.top = null;
Popup.prototype.left = null;
Popup.prototype.offsetLeft = 0;
Popup.prototype.offsetTop = 0;
Popup.prototype.constrainToScreen = true;
Popup.prototype.autoHide = true;
Popup.prototype.useIframeShim = false; /*@cc_on @*/ /*@if (@_win32) {Popup.prototype.useIframeShim = true;} @end @*/ 
Popup.prototype.iframe = null;
Popup.prototype.position = null; // vertical: "above top center bottom below", horizontal: "adjacent-left,left,center,right,adjacent-right"
Popup.prototype.reference = null;
Popup.prototype.modal = false;
Popup.prototype.destroyDivOnHide = false;
Popup.prototype.destroyObjectsOnHide = false;
Popup.prototype.screen = null;
Popup.prototype.screenIframeShim = null;
Popup.prototype.screenOpacity=.7;
Popup.prototype.screenColor="#000";

//INSTANCE METHODS

//Show the popup
Popup.prototype.show = function(options, modal) {
	this.modal = this.modal || (typeof(modal)=="boolean" && modal);
	if (defined(options) && options!=null && typeof(options)=="object") {
		for (var i in options) {
			this[i] = options[i];
		}
	}
	this.div = DOM.resolve(this.div);
	CSS.setStyle(this.div,'position','absolute');
	
	// If there is no div pre-defined to use, create one
	if (this.div==null) {
		this.div = this.createDiv();
	}
	if (this.content!=null) {
		this.div.innerHTML = this.content;
		this.content = null;
	}
	if (this.className!=null) {
		this.div.className = this.className;
	}
	if (this.style!=null) {
		this.applyStyle();
	}
	if (this.width!=null) {
		this.div.style.width = this.width+"px";
		this.div.style.overflowX="auto";
	}
	if (this.height!=null) {
		this.div.style.height = this.height+"px";
		this.div.style.overflowY="auto";
	}

	// Do the actual display - this is a separate method so display transitions can be implemented
	this.transition();
	
	// Make sure clicks on the DIV don't bubble up to the document
	this.div.onclick = function(e) { 
		mEvent.cancelBubble(mEvent.resolve(e));
	};
	this.div.onmouseup = this.div.onclick;
	
	// Focus to the DIV if possible	
	if (this.modal && this.div.focus) {
		this.div.focus();
	}
};

//Show the popup but make it modal
Popup.prototype.transition = function() {
	if (this.modal) {
		this.addScreen();
	}
	
	// Make the DIV displayed but hidden so its size can be measured
	CSS.setStyle(this.div,'visibility','hidden');
	CSS.setStyle(this.div,'display','block');

	// Position the popup
	this.setPosition();

	// Add the shim if necessary	
	if (this.useIframeShim) {
		this.addIframeShim();
	}

	// Make sure the DIV is higher than the shim
	this.div.style.zIndex = Popup.minZIndex++;

	CSS.setStyle(this.div,'display','block');
	CSS.setStyle(this.div,'visibility','visible');
};

//Show the popup but make it modal
Popup.prototype.showModal = function(options) {
	this.show(options,true);
};

//Apply user styles to the DIV
Popup.prototype.applyStyle = function() {
	if (this.div!=null && this.style!=null && typeof(this.style)=="object") {
		for (var i in this.style) {
			this.div.style[i] = this.style[i];
		}
	}
};

//Hide the popup
Popup.prototype.hideMe = function() {
	// If this was a temp object creating on-the-fly, then remove objects from the DOM so
	// The document doesn't get littered with extra objects
	if (this.destroyDivOnHide) {
		//DOM.removeNode(this.div);
		this.div.remove();
		this.div = null;
		delete Popup.objects[this.id];
	}
	else if (this.div!=null) {
		CSS.setStyle(this.div,'display','none');
	}

	if (this.destroyObjectsOnHide) {
		if (isMinIE6){
			if(this.iframe != null) DOM.removeNode(this.iframe);
			DOM.removeNode(this.screen);
			DOM.removeNode(this.screenIframeShim);
		} else {	
			if(this.iframe != null) this.iframe.remove();
			this.screen.remove();
			this.screenIframeShim.remove();
		}	
	}
	else {
		if (this.iframe!=null) {
			this.iframe.style.display = "none";
		}
		if (this.screen!=null) {
			this.screen.style.display = "none";
		}
		if (this.screenIframeShim!=null) {
			this.screenIframeShim.style.display = "none";
		}
	}
};

//Util funcs for position
Popup.prototype.setTop = function(top) {
	this.div.style.top = top+"px";
};
Popup.prototype.setLeft = function(left) {
	this.div.style.left = left+"px";
};
Popup.prototype.getTop = function() {
	return parseInt(CSS.getStyle(this.div,"top"),10);
};
Popup.prototype.getLeft = function() {
	return parseInt(CSS.getStyle(this.div,"left"),10);
};

//All the logic to position the popup based on various criteria
Popup.prototype.setPosition = function() {
	if (this.position!=null) {
		var m = this.position.match(/^(\S+)\s+(\S+)/); 
		if (m!=null && m.length==3) {
			var v = m[1];
			var h = m[2];

			var ref = this.reference;
			if (ref==null) { ref = Screen.getBody(); }
			var p = mPosition.get(ref);
			var refTop = p.top;
			var refLeft = p.left;
			var refWidth = DOM.getOuterWidth(ref);
			var refHeight = DOM.getOuterHeight(ref);
			
			var width = DOM.getOuterWidth(this.div);
			var height = DOM.getOuterHeight(this.div);
			
			var scrollLeft = Screen.getScrollLeft();
			var scrollTop = Screen.getScrollTop();

			// Set vertical position relative to reference object
			if (v=="above") { this.setTop(refTop-height+this.offsetTop); }
			else if (v=="top") { this.setTop(refTop+this.offsetTop); }
			else if (v=="center") { this.setTop(refTop+(refHeight/2)-(height/2)+this.offsetTop); }
			else if (v=="bottom") { this.setTop(refTop+refHeight-height+this.offsetTop); }
			else if (v=="below") { this.setTop(refTop+refHeight+this.offsetTop); }

			// Set horizontal position relative to reference object
			if (h=="adjacent-left") { this.setLeft(refLeft-width+this.offsetLeft); }
			else if (h=="left") { this.setLeft(refLeft+this.offsetLeft); }
			else if (h=="center") { this.setLeft(refLeft+(refWidth/2)-(width/2)+this.offsetLeft); }
			else if (h=="right") { this.setLeft(refLeft+refWidth-width+this.offsetLeft); }
			else if (h=="adjacent-right") { this.setLeft(refLeft+refWidth+this.offsetLeft); }
		}
	}
	else if (this.top==null && this.left==null) {
		this.center();
	}
	else {
		if (this.top==null) { this.top=0; }
		if (this.left==null) { this.left=0; }
		this.div.style.top = this.top+this.offsetTop+"px";
		this.div.style.left = this.left+this.offsetLeft+"px";
	}

	// Re-position to make sure it stays on the screen
	if (this.constrainToScreen) {
		this.fitToScreen();
	}
};

//Append an object to the body
Popup.prototype.appendToBody = function(o) {
	var body = Screen.getBody();
	if (body && body.appendChild) {
		body.appendChild(o);
	}
};

//Create a new DIV object to be used for a popup
Popup.prototype.createDiv = function() {
	if (document.createElement) {
		var d = document.createElement("DIV");
		d.style.position="absolute";
		d.style.display="block";
		d.style.visibility="hidden";
		this.appendToBody(d);
		return d;
	}
	alert("ERROR: Couldn't create DIV element in Popup.prototype.createDiv()");
	return null;
};

//Create a new IFRAME object to be used behind the popup
Popup.prototype.createIframe = function() {
	if (document.createElement) {
		var i= document.createElement("IFRAME");
		i.style.position="absolute";
		i.style.display="block";
		i.style.visibility="hidden";
		i.style.background="none";
		this.appendToBody(i);
		return i;
	}
	else {
		alert("ERROR: Couldn't create IFRAME object in Popup.prototype.createIframe()");
	}
};

//Add an IFRAME shim for the DIV
Popup.prototype.addIframeShim = function() {
	if (this.iframe==null) {
		this.iframe = this.createIframe();
	}
	this.iframe.className = Popup.iframeClass;
	CSS.setStyle(this.iframe,'top',this.getTop()+"px");
	CSS.setStyle(this.iframe,'left',this.getLeft()+"px");
	CSS.setStyle(this.iframe,'width',DOM.getOuterWidth(this.div) + "px");
	CSS.setStyle(this.iframe,'height',DOM.getOuterHeight(this.div) + "px");
	CSS.setStyle(this.iframe,'zIndex',Popup.minZIndex++);
	CSS.setStyle(this.iframe,'opacity',0);
	CSS.setStyle(this.iframe,'visibility','visible');
	CSS.setStyle(this.iframe,'display','block');
};

//Create a "screen" to make a popup modal
Popup.prototype.addScreen = function() {
	if (this.screen==null) {
		this.screen = this.createDiv();
		this.screen.style.top="0px";
		this.screen.style.left="0px";
		this.screen.style.backgroundColor = this.screenColor;
		this.screen.className=Popup.screenClass;;
		CSS.setStyle(this.screen,"opacity",this.screenOpacity);
		this.screen.onclick = function(e) { mEvent.cancelBubble(mEvent.resolve(e)); }
	}
	if (this.screenIframeShim==null) {
		this.screenIframeShim = this.createIframe();
		this.screenIframeShim.style.top="0px";
		this.screenIframeShim.style.left="0px";
		this.screenIframeShim.className=Popup.screenIframeClass;
		CSS.setStyle(this.screenIframeShim,"opacity",0);
	}
	this.screen.style.width = Screen.getDocumentWidth()+"px";
	this.screen.style.height = Screen.getDocumentHeight()+"px";
	this.screenIframeShim.style.width = Screen.getDocumentWidth()+"px";
	this.screenIframeShim.style.height = Screen.getDocumentHeight()+"px";
	this.screenIframeShim.style.zIndex = Popup.minZIndex++;
	this.screenIframeShim.style.visibility="visible";
	this.screenIframeShim.style.display="block";
	this.screen.style.zIndex = Popup.minZIndex++;
	this.screen.style.visibility="visible";
	this.screen.style.display="block";
};

//Re-position the DIV so it stays on the screen
Popup.prototype.fitToScreen = function() {
	var width = DOM.getOuterWidth(this.div);
	var height = DOM.getOuterHeight(this.div);
	var top = this.getTop();
	var left = this.getLeft();
	
	var clientWidth = Screen.getViewportWidth();
	var clientHeight = Screen.getViewportHeight();
	
	var scrollLeft = Screen.getScrollLeft();
	var scrollTop = Screen.getScrollTop();

	if (top-scrollTop+height>clientHeight) {
		top = top - ((top+height) - (scrollTop+clientHeight));
		this.div.style.top = top + "px";
	}
	if (left-scrollLeft+width>clientWidth) {
		left = left - ((left+width) - (scrollLeft+clientWidth));
		this.div.style.left = left + "px";
	}
	if (top<scrollTop) {
		this.div.style.top=scrollTop+"px";
	}
	if (left<scrollLeft) {
		this.div.style.left=scrollLeft+"px";
	}
};

//Center the DIV object
Popup.prototype.center = function() {
	var left = DOM.getOuterWidth(this.div);
	var top = DOM.getOuterHeight(this.div);
	if (isNaN(left)) { left=0; }
	if (isNaN(top)) { top=0; }	
	var clientW = Screen.getViewportWidth();
	var clientH = Screen.getViewportHeight();
	if (clientW!=null && clientH!=null) {
		top = (clientH-top)/2;
		left = (clientW-left)/2;
	}
	top += Screen.getScrollTop();
	left += Screen.getScrollLeft();
	
	this.div.style.top = top+this.offsetTop+"px";
	this.div.style.left = left+this.offsetLeft+"px";
};
//==============================
//END Modal Div Popups
//==============================
if(isMinIE6 && !isMinIE7) {
    try {
        document.execCommand("BackgroundImageCache", false, true);
    } catch(err) {
    }
}
if (window.tString != undefined) {
	tString += " aEndExecute:" + ((new Date()).getTime() - tHead);
}
