/*!
 * jQuery JavaScript Library v1.4.2
 * http://jquery.com/
 *
 * Copyright 2010, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 * Copyright 2010, The Dojo Foundation
 * Released under the MIT, BSD, and GPL Licenses.
 *
 * Date: Sat Feb 13 22:33:48 2010 -0500
 */
(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML="   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);jQuery.noConflict();

jQuery.ajaxSetup({
	cache: false
});

jQuery.fn.ljAddContextualPopup = function()
{
	if (!window.ContextualPopup) return this;
	
	return this.each(function()
	{
		ContextualPopup.searchAndAdd(this);
	});
}

jQuery.fn.hourglass = function(xhr)
{
	var hourglasses = [];
	this.each(function()
	{
		// is complete or was aborted
		if (xhr && (xhr.readyState == 0 || xhr.readyState == 4)) return;
		
		if (this.nodeType) { // node
			
		} else { // position from event
			var e = jQuery.event.fix(this),
				hourglass = new Hourglass(),
				offset = {};
			
			// from keyboard
			if (!e.clientX || !e.clientY) {
				offset = jQuery(e.target).offset();
			}
			
			hourglass.init();
			hourglass.hourglass_at(offset.left || e.pageX, offset.top || e.pageY);
		}
		
		hourglasses.push(hourglass)
		
		if (xhr)
		{
			jQuery(hourglass.ele).bind('ajaxComplete', function(event, request)
			{
				if (request == xhr) {
					hourglass.hide();
					jQuery(hourglass.ele).unbind('ajaxComplete', arguments.callee);
				}
			});
		}
	});
	
	return hourglasses;
}
/*
Core JavaScript Library
$Id: core.js 275 2009-11-27 08:42:15Z pkornilov $

Copyright (c) 2005, Six Apart, Ltd.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.

    * Neither the name of "Six Apart" nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

/* stubs */

log = function() {};
log.error = log.warn = log.debug = log;


/* utility functions */

defined = function( x ) {
    return x === undefined ? false : true;
}


/**
 * Utility method.
 * @param x <code>any</code> Any JavaScript value, including <code>undefined</code>.
 * @return boolean <code>true</code> if the value is not <code>null</code> and is not <code>undefined</code>.
 */
exists = function( x ) {
   return (x === undefined || x === null) ? false : true;
}


finite = function( x ) {
    return isFinite( x ) ? x : 0;
}


finiteInt = function( x, base ) {
    return finite( parseInt( x, base ) );
}


finiteFloat = function( x ) {
    return finite( parseFloat( x ) );
}


max = function() {
    var a = arguments;
    var n = a[ 0 ];
    for( var i = 1; i < a.length; i++ )
        if( a[ i ] > n )
            n = a[ i ];
    return n;
}


min = function() {
    var a = arguments;
    var n = a[ 0 ];
    for( var i = 1; i < a.length; i++ )
        if( a[ i ] < n )
            n = a[ i ];
    return n;
}


/* try block */  
 
Try = {
    these: function() {
        for( var i = 0; i < arguments.length; i++ ) {
            try {
                return arguments[ i ]();
            } catch( e ) {}
        }
        return undefined;
    }
}


/* unique id generator */

Unique = {
    length: 0,
    
    id: function() {
        return ++this.length;
    }
}


/* event methods */

if( !defined( window.Event ) )
    Event = {};


Event.stop = function( e ) {
	// this set in Event.prep
	e = e || window.event || this;
	Event.stopPropagation( e );
	Event.preventDefault( e );
    return false;
}


Event.stopPropagation = function( e ) {
    if ( e && e.stopPropagation )
        e.stopPropagation();
    else
        window.event.cancelBubble = true;
}


Event.preventDefault = function( e ) {
    e = e || window.event;
    if ( e.preventDefault )
        e.preventDefault();
    e.returnValue = false;
}


Event.prep = function( event ) {
    event = event || window.event;
    if( !defined( event.stop ) )
        event.stop = this.stop;
    if( !defined( event.target ) )
        event.target = event.srcElement;
    if( !defined( event.relatedTarget ) ) 
        event.relatedTarget = event.toElement;
    return event;
}


/* object extensions */

Function.stub = function() {};

if (!Object.extend)
	Object.extend = function (d, s) { if (d) for (var p in s) if (!d[p]) d[p] = s[p]; return d }

if (!Object.override)
	Object.override = function (d, s) { if (d) for (var p in s) d[p] = s[p]; return d }

/* function extensions */

Object.extend(Function.prototype, {
    bind: function( object ) {
        var method = this;
        return function() {
            return method.apply( object, arguments );
        };
    },
    
    
    bindEventListener: function( object ) {
        var method = this; // Use double closure to work around IE 6 memory leak.
        return function( event ) {
            try {
                event = Event.prep( event );
            } catch( e ) {}
            return method.call( object, event );
        };
    }
} );


/* class helpers */

indirectObjects = [];


Class = function( superClass ) {

    // Set the constructor:
    var constructor = function() {
        if( arguments.length )
            this.init.apply( this, arguments );
    };    
    //   -- Accomplish static-inheritance:
    Object.override(constructor, Class);  // inherit static methods from Class
    
    superClass = superClass || function(){};
    superClassFunc = function(){}
    Object.extend(superClassFunc.prototype, superClass.prototype)
    Object.extend(superClassFunc.prototype, {
        init: function(){},
        destroy: function(){}
    })
    Object.override(constructor, superClass); // inherit static methods from the superClass
    constructor.superClass = superClassFunc.prototype;
    
    // Set the constructor's prototype (accomplish object-inheritance):
    constructor.prototype = new superClass();
    constructor.prototype.constructor = constructor; // rev. 0.7    
    //   -- extend prototype with Class instance methods
    Object.extend(constructor.prototype, Class.prototype);
    //   -- override prototype with interface methods
    for( var i = 1; i < arguments.length; i++ )
        Object.override(constructor.prototype, arguments[i]);
    
    return constructor;
}


Object.extend(Class, {
    initSingleton: function() {
        if( this.singleton )
            return this.singleton;
        this.singleton = this.singletonConstructor
            ? new this.singletonConstructor()
            : new this();
        this.singleton.init.apply( this.singleton, arguments );
        return this.singleton;
    }
} );


Class.prototype = {
    destroy: function() {
        try {
            if( this.indirectIndex )
                indirectObjects[ this.indirectIndex ] = undefined;
            delete this.indirectIndex;
        } catch( e ) {}
        
        for( var property in this ) {
            try {
                delete this[ property ];
            } catch( e ) {}
        }
    },
    
    
    getBoundMethod: function( methodName ) {
        return this[ name ].bind( this );
    },
    
    
    getEventListener: function( methodName ) {
        return this[ methodName ].bindEventListener( this );
    },
    
    
    getIndirectIndex: function() {
        if( !defined( this.indirectIndex ) ) {
            this.indirectIndex = indirectObjects.length;
            indirectObjects.push( this );
        }
        return this.indirectIndex;
    },
    
    
    getIndirectMethod: function( methodName ) {
        if( !this.indirectMethods )
            this.indirectMethods = {};
        var method = this[ methodName ];
        if( typeof method != "function" )
            return undefined;
        var indirectIndex = this.getIndirectIndex();
        if( !this.indirectMethods[ methodName ] ) {
            this.indirectMethods[ methodName ] = new Function(
                "var o = indirectObjects[" + indirectIndex + "];" +
                "return o." + methodName + ".apply( o, arguments );"
            );
        }
        return this.indirectMethods[ methodName ];
    },
    
    
    getIndirectEventListener: function( methodName ) {
        if( !this.indirectEventListeners )
            this.indirectEventListeners = {};
        var method = this[ methodName ];
        if( typeof method != "function" )
            return undefined;
        var indirectIndex = this.getIndirectIndex();
        if( !this.indirectEventListeners[ methodName ] ) {
            this.indirectEventListeners[ methodName ] = new Function( "event",
                "try { event = Event.prep( event ); } catch( e ) {}" +
                "var o = indirectObjects[" + indirectIndex + "];" +
                "return o." + methodName + ".call( o, event );"
            );
        }
        return this.indirectEventListeners[ methodName ];
    }
}


/* string extensions */

Object.extend(String, {
    escapeJSChar: function( c ) {
        // try simple escaping
        switch( c ) {
            case "\\": return "\\\\";
            case "\"": return "\\\"";
            case "'":  return "\\'";
            case "\b": return "\\b";
            case "\f": return "\\f";
            case "\n": return "\\n";
            case "\r": return "\\r";
            case "\t": return "\\t";
        }
        
        // return raw bytes now ... should be UTF-8
        if( c >= " " )
            return c;
        
        // try \uXXXX escaping, but shouldn't make it for case 1, 2
        c = c.charCodeAt( 0 ).toString( 16 );
        switch( c.length ) {
            case 1: return "\\u000" + c;
            case 2: return "\\u00" + c;
            case 3: return "\\u0" + c;
            case 4: return "\\u" + c;
        }
        
        // should never make it here
        return "";
    },
    
    
    encodeEntity: function( c ) {
        switch( c ) {
            case "<": return "&lt;";
            case ">": return "&gt;";
            case "&": return "&amp;";
            case '"': return "&quot;";
            case "'": return "&apos;";
        }
        return c;
    },


    decodeEntity: function( c ) {
        switch( c ) {
            case "amp": return "&";
            case "quot": return '"';
            case "gt": return ">";
            case "lt": return "<";
        }
        var m = c.match( /^#(\d+)$/ );
        if( m && defined( m[ 1 ] ) )
            return String.fromCharCode( m[ 1 ] );
        m = c.match( /^#x([0-9a-f]+)$/i );
        if(  m && defined( m[ 1 ] ) )
            return String.fromCharCode( parseInt( hex, m[ 1 ] ) );
        return c;
    }
} );


Object.extend(String.prototype, {
    escapeJS: function() {
        return this.replace( /([^ -!#-\[\]-~])/g, function( m, c ) { return String.escapeJSChar( c ); } )
    },
    
    
    escapeJS2: function() {
        return this.replace( /([\u0000-\u0031'"\\])/g, function( m, c ) { return String.escapeJSChar( c ); } )
    },
    
    
    escapeJS3: function() {
        return this.replace( /[\u0000-\u0031'"\\]/g, function( m ) { return String.escapeJSChar( m ); } )
    },
    
    
    escapeJS4: function() {
        return this.replace( /./g, function( m ) { return String.escapeJSChar( m ); } )
    },
    
    
    encodeHTML: function() {
        return this.replace( /([<>&"])/g, function( m, c ) { return String.encodeEntity( c ) } );
    },


    decodeHTML: function() {
        return this.replace( /&(.*?);/g, function( m, c ) { return String.decodeEntity( c ) } );
    },
    
    
    cssToJS: function() {
        return this.replace( /-([a-z])/g, function( m, c ) { return c.toUpperCase() } );
    },
    
    
    jsToCSS: function() {
        return this.replace( /([A-Z])/g, function( m, c ) { return "-" + c.toLowerCase() } );
    },
    
    
    firstToLowerCase: function() {
        return this.replace( /^(.)/, function( m, c ) { return c.toLowerCase() } );
    },
    
        
    rgbToHex: function() {
        var c = this.match( /(\d+)\D+(\d+)\D+(\d+)/ );
        if( !c )
            return undefined;
        return "#" +
            finiteInt( c[ 1 ] ).toString( 16 ).pad( 2, "0" ) +
            finiteInt( c[ 2 ] ).toString( 16 ).pad( 2, "0" ) +
            finiteInt( c[ 3 ] ).toString( 16 ).pad( 2, "0" );
    },
    
    
    pad: function( length, padChar ) {
        var padding = length - this.length;
        if( padding <= 0 )
            return this;
        if( !defined( padChar ) )
            padChar = " ";
        var out = [];
        for( var i = 0; i < padding; i++ )
            out.push( padChar );
        out.push( this );
        return out.join( "" );
    },


    trim: function() {
        return this.replace( /^\s+|\s+$/g, "" );
    }

} );


/* extend array object */

Object.extend(Array, { 
    fromPseudo: function ( args ) {
        var out = [];
        for ( var i = 0; i < args.length; i++ )
            out.push( args[ i ] );
        return out;
    }
});


/* extend array object */

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


    first: function( callback, object ) {
        var length = this.length;
        for( var i = 0; i < length; i++ ) {
            var result = object
                ? callback.call( object, this[ i ], i, this )
                : callback( this[ i ], i, this );
            if( result )
                return this[ i ];
        }
        return null;
    },


    fitIndex: function( fromIndex, defaultIndex ) {
        if( !defined( fromIndex ) || fromIndex == null )
            fromIndex = defaultIndex;
        else if( fromIndex < 0 ) {
            fromIndex = this.length + fromIndex;
            if( fromIndex < 0 )
                fromIndex = 0;
        } else if( fromIndex >= this.length )
            fromIndex = this.length - 1;
        return fromIndex;
    },


    scramble: function() {
        for( var i = 0; i < this.length; i++ ) {
            var j = Math.floor( Math.random() * this.length );
            var temp = this[ i ];
            this[ i ] = this[ j ];
            this[ j ] = temp;
        }
    },
    
    
    add: function() {
        var a = arguments;
        for( var i = 0; i < a.length; i++ ) {
            var index = this.indexOf( a[ i ] );
            if( index < 0 ) 
                this.push( arguments[ i ] );
        }
        return this.length;
    },
        
    
    remove: function() {
        var a = arguments;
        for( var i = 0; i < a.length; i++ ) {
            var j = this.indexOf( a[ i ] );
            if( j >= 0 )
                this.splice( j, 1 );
        }
        return this.length;
    },


    /* javascript 1.5 array methods */
    /* http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array#Methods */

    every: function( callback, object ) {
        var length = this.length;
        for( var i = 0; i < length; i++ ) {
            var result = object
                ? callback.call( object, this[ i ], i, this )
                : callback( this[ i ], i, this );
            if( !result )
                return false;
        }
        return true;
    },


    filter: function( callback, object ) {
        var out = [];
        var length = this.length;
        for( var i = 0; i < length; i++ ) {
            var result = object
                ? callback.call( object, this[ i ], i, this )
                : callback( this[ i ], i, this );
            if( result )
                out.push( this[ i ] );
        }
        return out;
    },
    
    
    forEach: function( callback, object ) {
        var length = this.length;
        for( var i = 0; i < length; i++ ) {
            object
                ? callback.call( object, this[ i ], i, this )
                : callback( this[ i ], i, this );
        }
    },
    
    
    indexOf: function( value, fromIndex ) {
        fromIndex = this.fitIndex( fromIndex, 0 );
        for( var i = 0; i < this.length; i++ ) {
            if( this[ i ] === value )
                return i; 
        }
        return -1;
    },


    lastIndexOf: function( value, fromIndex ) {
        fromIndex = this.fitIndex( fromIndex, this.length - 1 );
        for( var i = fromIndex; i >= 0; i-- ) {
            if( this[ i ] == value )
                return i;
        }
        return -1;
    },


    some: function( callback, object ) {
        var length = this.length;
        for( var i = 0; i < length; i++ ) {
            var result = object
                ? callback.call( object, this[ i ], i, this )
                : callback( this[ i ], i, this );
            if( result )
                return true;
        }
        return false;
    },


    /* javascript 1.2 array methods */

    concat: function() {
        var a = arguments;
        var out = this.copy();
        for( i = 0; i < a.length; i++ ) {
            var b = a[ i ];
            for( j = 0; j < b.length; j++ )
                out.push( b[ j ] );
        }
        return out;
    },
    

    push: function() {
        var a = arguments;
        for( var i = 0; i < a.length; i++ )
            this[ this.length ] = a[ i ];
        return this.length;     
    },


    pop: function() {
        if( this.length == 0 )
            return undefined;
        var out = this[ this.length - 1 ];
        this.length--;
        return out;
    },
    
    
    unshift: function() {
        var a = arguments;
        for( var i = 0; i < a.length; i++ ) {
            this[ i + a.length ] = this[ i ];
            this[ i ] = a[ i ];
        }
        return this.length;     
    },
    
    
    shift: function() {
        if( this.length == 0 )
            return undefined;
        var out = this[ 0 ];
        for( var i = 1; i < this.length; i++ )
            this[ i - 1 ] = this[ i ];
        this.length--;
        return out;
    }
} );


/* date extensions */

Object.extend(Date, {
    /*  iso 8601 date format parser
        this was fun to write...
        thanks to: http://www.cl.cam.ac.uk/~mgk25/iso-time.html */

    matchISOString: new RegExp(
        "^([0-9]{4})" +                                                     // year
        "(?:-(?=0[1-9]|1[0-2])|$)(..)?" +                                   // month
        "(?:-(?=0[1-9]|[12][0-9]|3[01])|$)([0-9]{2})?" +                    // day of the month
        "(?:T(?=[01][0-9]|2[0-4])|$)T?([0-9]{2})?" +                        // hours
        "(?::(?=[0-5][0-9])|\\+|-|Z|$)([0-9]{2})?" +                        // minutes
        "(?::(?=[0-5][0-9]|60$|60[+|-|Z]|60.0+)|\\+|-|Z|$):?([0-9]{2})?" +  // seconds
        "(\.[0-9]+)?" +                                                     // fractional seconds
        "(Z|\\+[01][0-9]|\\+2[0-4]|-[01][0-9]|-2[0-4])?" +                  // timezone hours
        ":?([0-5][0-9]|60)?$"                                               // timezone minutes
    ),
    
    
    fromISOString: function( string ) {
        var t = this.matchISOString.exec( string );
        if( !t )
            return undefined;

        var year = finiteInt( t[ 1 ], 10 );
        var month = finiteInt( t[ 2 ], 10 ) - 1;
        var day = finiteInt( t[ 3 ], 10 );
        var hours = finiteInt( t[ 4 ], 10 );
        var minutes = finiteInt( t[ 5 ], 10 );
        var seconds = finiteInt( t[ 6 ], 10 );
        var milliseconds = finiteInt( Math.round( parseFloat( t[ 7 ] ) * 1000 ) );
        var tzHours = finiteInt( t[ 8 ], 10 );
        var tzMinutes = finiteInt( t[ 9 ], 10 );

        var date = new this( 0 );
        if( defined( t[ 8 ] ) ) {
            date.setUTCFullYear( year, month, day );
            date.setUTCHours( hours, minutes, seconds, milliseconds );
            var offset = (tzHours * 60 + tzMinutes) * 60000;
            if( offset )
                date = new this( date - offset );
        } else {
            date.setFullYear( year, month, day );
            date.setHours( hours, minutes, seconds, milliseconds );
        }

        return date;
    }
} );


Object.extend(Date.prototype, {
    getISOTimezoneOffset: function() {
        var offset = -this.getTimezoneOffset();
        var negative = false;
        if( offset < 0 ) {
            negative = true;
            offset *= -1;
        }
        var offsetHours = Math.floor( offset / 60 ).toString().pad( 2, "0" );
        var offsetMinutes = Math.floor( offset % 60 ).toString().pad( 2, "0" );
        return (negative ? "-" : "+") + offsetHours + ":" + offsetMinutes;
    },


    toISODateString: function() {
        var year = this.getFullYear();
        var month = (this.getMonth() + 1).toString().pad( 2, "0" );
        var day = this.getDate().toString().pad( 2, "0" );
        return year + "-" + month + "-" + day;
    },


    toUTCISODateString: function() {
        var year = this.getUTCFullYear();
        var month = (this.getUTCMonth() + 1).toString().pad( 2, "0" );
        var day = this.getUTCDate().toString().pad( 2, "0" );
        return year + "-" + month + "-" + day;
    },


    toISOTimeString: function() {
        var hours = this.getHours().toString().pad( 2, "0" );
        var minutes = this.getMinutes().toString().pad( 2, "0" );
        var seconds = this.getSeconds().toString().pad( 2, "0" );
        var milliseconds = this.getMilliseconds().toString().pad( 3, "0" );
        var timezone = this.getISOTimezoneOffset();
        return hours + ":" + minutes + ":" + seconds + "." + milliseconds + timezone;
    },


    toUTCISOTimeString: function() {
        var hours = this.getUTCHours().toString().pad( 2, "0" );
        var minutes = this.getUTCMinutes().toString().pad( 2, "0" );
        var seconds = this.getUTCSeconds().toString().pad( 2, "0" );
        var milliseconds = this.getUTCMilliseconds().toString().pad( 3, "0" );
        return hours + ":" + minutes + ":" + seconds + "." + milliseconds + "Z";
    },


    toISOString: function() {
        return this.toISODateString() + "T" + this.toISOTimeString();
    },


    toUTCISOString: function() {
        return this.toUTCISODateString() + "T" + this.toUTCISOTimeString();
    }
} );


/* ajax */

if( !defined( window.XMLHttpRequest ) ) {
    window.XMLHttpRequest = function() {
        var types = [
            "Microsoft.XMLHTTP",
            "MSXML2.XMLHTTP.5.0",
            "MSXML2.XMLHTTP.4.0",
            "MSXML2.XMLHTTP.3.0",
            "MSXML2.XMLHTTP"
        ];
        
        for( var i = 0; i < types.length; i++ ) {
            try {
                return new ActiveXObject( types[ i ] );
            } catch( e ) {}
        }
        
        return undefined;
    }
}
/*
DOM Library - Copyright 2005 Six Apart
$Id: dom.js 278 2009-12-10 08:02:45Z pkornilov $

Copyright (c) 2005, Six Apart, Ltd.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.

    * Neither the name of "Six Apart" nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/


/* Node class */

if(!window.Node)
    Node = {};

try {
    Object.extend(Node, {
        ELEMENT_NODE: 1,
        ATTRIBUTE_NODE: 2,
        TEXT_NODE: 3,
        CDATA_SECTION_NODE: 4,
        COMMENT_NODE: 8,
        DOCUMENT_NODE: 9,
        DOCUMENT_FRAGMENT_NODE: 11
    } );
} catch( e ) {}


/* DOM class */

if(!window.DOM)
    DOM = {};


Object.extend(DOM, {
    getElement: function( e ) {
        return (typeof e == "string" || typeof e == "number") ? document.getElementById( e ) : e;
    },


    addEventListener: function( e, eventName, func, useCapture ) {
        try {
            if( e.addEventListener )
                e.addEventListener( eventName, func, useCapture );
            else if( e.attachEvent )
                e.attachEvent( "on" + eventName, func );
            else
                e[ "on" + eventName ] = func;
        } catch( e ) {}
    },


    removeEventListener: function( e, eventName, func, useCapture ) {
        try {
            if( e.removeEventListener )
                e.removeEventListener( eventName, func, useCapture );
            else if( e.detachEvent )
                e.detachEvent( "on" + eventName, func );
            else
                e[ "on" + eventName ] = undefined;
        } catch( e ) {}
    },


    ready: function(f, frame) {
        if (frame) {
            win = frame.contentWindow;
        } else {
            win = window;
        }
        if (/(?!.*?compatible|.*?webkit)^mozilla|opera/i.test(navigator.userAgent) && !frame) {
            document.addEventListener('DOMContentLoaded', f, false);
        } else {
            var go = function() { win.document.body ? f() : win.setTimeout(go, 1); }
            go();
        }
    },


    focus: function( e ) {
        try {
            e = DOM.getElement( e );
            e.focus();
        } catch( e ) {}
    },


    blur: function( e ) {
        try {
            e = DOM.getElement( e );
            e.blur();
        } catch( e ) {}
    },
    

    /* style */
    
    getComputedStyle: function( e ) {
        if( e.currentStyle )
            return e.currentStyle;
        var style = {};
        var owner = DOM.getOwnerDocument( e );
        if( owner && owner.defaultView && owner.defaultView.getComputedStyle ) {            
            try {
                style = owner.defaultView.getComputedStyle( e, null );
            } catch( e ) {}
        }
        return style;
    },


    getStyle: function( e, p ) {
        var s = DOM.getComputedStyle( e );
        return s[ p ];
    },


    // given a window (or defaulting to current window), returns
    // object with .x and .y of client's usable area
    getClientDimensions: function( w ) {
        if( !w )
            w = window;

        var d = {};

        // most browsers
        if( w.innerHeight ) {
            d.x = w.innerWidth;
            d.y = w.innerHeight;
            return d;
        }

        // IE6, strict
        var de = w.document.documentElement;
        if( de && de.clientHeight ) {
            d.x = de.clientWidth;
            d.y = de.clientHeight;
            return d;
        }

        // IE, misc
        if( document.body ) {
            d.x = document.body.clientWidth;
            d.y = document.body.clientHeight;
            return d;
        }
        
        return undefined;
    },


    getDimensions: function( e ) {
        if( !e )
            return undefined;

        var style = DOM.getComputedStyle( e );

        return {
            offsetLeft: e.offsetLeft,
            offsetTop: e.offsetTop,
            offsetWidth: e.offsetWidth,
            offsetHeight: e.offsetHeight,
            clientWidth: e.clientWidth,
            clientHeight: e.clientHeight,
            
            offsetRight: e.offsetLeft + e.offsetWidth,
            offsetBottom: e.offsetTop + e.offsetHeight,
            clientLeft: finiteInt( style.borderLeftWidth ) + finiteInt( style.paddingLeft ),
            clientTop: finiteInt( style.borderTopWidth ) + finiteInt( style.paddingTop ),
            clientRight: e.clientLeft + e.clientWidth,
            clientBottom: e.clientTop + e.clientHeight
        };
    },


    getAbsoluteDimensions: function( e ) {
        var d = DOM.getDimensions( e );
        if( !d )
            return d;
        d.absoluteLeft = d.offsetLeft;
        d.absoluteTop = d.offsetTop;
        d.absoluteRight = d.offsetRight;
        d.absoluteBottom = d.offsetBottom;
        var bork = 0;
        while( e ) {
            try { // IE 6 sometimes gives an unwarranted error ("htmlfile: Unspecified error").
                e = e.offsetParent;
            } catch ( err ) {
                log( "In DOM.getAbsoluteDimensions: " + err.message ); 
                if ( ++bork > 25 )
                    return null;
            }
            if( !e )
                return d;
            d.absoluteLeft += e.offsetLeft;
            d.absoluteTop += e.offsetTop;
            d.absoluteRight += e.offsetLeft;
            d.absoluteBottom += e.offsetTop;
        }
        return d;
    },
    
    
    getIframeAbsoluteDimensions: function( e ) {
        var d = DOM.getAbsoluteDimensions( e );
        if( !d )
            return d;
        var iframe = DOM.getOwnerIframe( e );
        if( !defined( iframe ) )
            return d;
        
        var d2 = DOM.getIframeAbsoluteDimensions( iframe );
        var scroll = DOM.getWindowScroll( iframe.contentWindow );
        var left = d2.absoluteLeft - scroll.left;
        var top = d2.absoluteTop - scroll.top;
        
        d.absoluteLeft += left;
        d.absoluteTop += top;
        d.absoluteRight += left;
        d.absoluteBottom += top;
        
        return d;
    },
    
    
    setLeft: function( e, v ) { e.style.left = finiteInt( v ) + "px"; },
    setTop: function( e, v ) { e.style.top = finiteInt( v ) + "px"; },
    setRight: function( e, v ) { e.style.right = finiteInt( v ) + "px"; },
    setBottom: function( e, v ) { e.style.bottom = finiteInt( v ) + "px"; },
    setWidth: function( e, v ) { e.style.width = max( 0, finiteInt( v ) ) + "px"; },
    setHeight: function( e, v ) { e.style.height = max( 0, finiteInt( v ) ) + "px"; },
    setZIndex: function( e, v ) { e.style.zIndex = finiteInt( v ); },


    getWindowScroll: function( w ) {
        var s = {
            left: 0,
            top: 0
        };

        if (!w) w = window;
        var d = w.document;
        var de = d.documentElement;

        // most browsers
        if ( defined( w.pageXOffset ) ) {
            s.left = w.pageXOffset;
            s.top = w.pageYOffset;
        }

        // ie
        else if( de && defined( de.scrollLeft ) ) {
            s.left = de.scrollLeft;
            s.top = de.scrollTop;
        }

        // safari
        else if( defined( w.scrollX ) ) {
            s.left = w.scrollX;
            s.top = w.scrollY;
        }

        // opera
        else if( d.body && defined( d.body.scrollLeft ) ) {
            s.left = d.body.scrollLeft;
            s.top = d.body.scrollTop;
        }


        return s;
    },


    getAbsoluteCursorPosition: function( event ) {
        event = event || window.event;
        var s = DOM.getWindowScroll( window );
        return {
            x: s.left + event.clientX,
            y: s.top + event.clientY
        };
    },
    
    
    invisibleStyle: {
        display: "block",
        position: "absolute",
        left: 0,
        top: 0,
        width: 0,
        height: 0,
        margin: 0,
        border: 0,
        padding: 0,
        fontSize: "0.1px",
        lineHeight: 0,
        opacity: 0,
        MozOpacity: 0,
        filter: "alpha(opacity=0)"
    },
    
    
    makeInvisible: function( e ) {
        for( var p in this.invisibleStyle ) {
            e.style[ p ] = this.invisibleStyle[ p ];
        }
    },


    /* text and selection related methods */

    mergeTextNodes: function( n ) {
        var c = 0;
        while( n ) {
            if( n.nodeType == Node.TEXT_NODE && n.nextSibling && n.nextSibling.nodeType == Node.TEXT_NODE ) {
                n.nodeValue += n.nextSibling.nodeValue;
                n.parentNode.removeChild( n.nextSibling );
                c++;
            } else {
                if( n.firstChild )
                    c += DOM.mergeTextNodes( n.firstChild );
                n = n.nextSibling;
            }
        }
        return c;
    },
    
    
    selectElement: function( e ) {  
        var d = e.ownerDocument;  
        
        // internet explorer  
        if( d.body.createControlRange ) {  
            var r = d.body.createControlRange();  
            r.addElement( e );  
            r.select();  
        }  
    }, 
    
    
    /* dom methods */
    
    isImmutable: function( n ) {
        try {
            if( n.getAttribute( "contenteditable" ) == "false" )
                return true;
        } catch( e ) {}
        return false;
    },
    
    
    getImmutable: function( n ) {
        var immutable = null;
        while( n ) {
            if( DOM.isImmutable( n ) )
                immutable = n;
            n = n.parentNode;
        }
        return immutable;
    },


    getOwnerDocument: function( n ) {
        if( !n )
            return document;
        if( n.ownerDocument )
            return n.ownerDocument;
        if( n.getElementById )
            return n;
        return document;
    },


    getOwnerWindow: function( n ) {
        if( !n )
            return window;
        if( n.parentWindow )
            return n.parentWindow;
        var doc = DOM.getOwnerDocument( n );
        if( doc && doc.defaultView )
            return doc.defaultView;
        return window;
    },
    
    
    getOwnerIframe: function( n ) {
        if( !n )
            return undefined;
        var nw = DOM.getOwnerWindow( n );
        var nd = DOM.getOwnerDocument( n );
        var pw = nw.parent || nw.parentWindow;
        if( !pw )
            return undefined;
        var parentDocument = pw.document;
        var es = parentDocument.getElementsByTagName( "iframe" );
        for( var i = 0; i < es.length; i++ ) {
            var e = es[ i ];
            try {
                var d = e.contentDocument || e.contentWindow.document;
                if( d === nd )
                    return e;
            }catch(err) {};
        }
        return undefined;
    },


    filterElementsByClassName: function( es, className ) {
        var filtered = [];
        for( var i = 0; i < es.length; i++ ) {
            var e = es[ i ];
            if( DOM.hasClassName( e, className ) )
                filtered[ filtered.length ] = e;
        }
        return filtered;
    },
    
    
    filterElementsByAttribute: function( es, attr ) {
        if( !es )
            return [];
        if( !defined( attr ) || attr == null || attr == "" )
            return es;
        var filtered = [];
        for( var i = 0; i < es.length; i++ ) {
            var element = es[ i ];
            if( !element )
                continue;
            if( element.getAttribute && ( element.getAttribute( attr ) ) )
                filtered[ filtered.length ] = element;
        }
        return filtered;
    },


    filterElementsByTagName: function( es, tagName ) {
        if( tagName == "*" )
            return es;
        var filtered = [];
        tagName = tagName.toLowerCase();
        for( var i = 0; i < es.length; i++ ) {
            var e = es[ i ];
            if( e.tagName && e.tagName.toLowerCase() == tagName )
                filtered[ filtered.length ] = e;
        }
        return filtered;
    },


    getElementsByTagAndAttribute: function( root, tagName, attr ) {
        if( !root )
            root = document;
        var es = root.getElementsByTagName( tagName );
        return DOM.filterElementsByAttribute( es, attr );
    },
    
    
    getElementsByAttribute: function( root, attr ) {
        return DOM.getElementsByTagAndAttribute( root, "*", attr );
    },


    getElementsByAttributeAndValue: function( root, attr, value ) {
        var es = DOM.getElementsByTagAndAttribute( root, "*", attr );
        var filtered = [];
        for ( var i = 0; i < es.length; i++ )
            if ( es[ i ].getAttribute( attr ) == value )
                filtered.push( es[ i ] );
        return filtered;
    },
    

    getElementsByTagAndClassName: function( root, tagName, className ) {
        if( !root )
            root = document;
        var elements = root.getElementsByTagName( tagName );
        return DOM.filterElementsByClassName( elements, className );
    },


    getElementsByClassName: function( root, className ) {
        return DOM.getElementsByTagAndClassName( root, "*", className );
    },


    getAncestors: function( n, includeSelf ) {
        if( !n )
            return [];
        var as = includeSelf ? [ n ] : [];
        n = n.parentNode;
        while( n ) {
            as.push( n );
            n = n.parentNode;
        }
        return as;
    },
    
    
    getAncestorsByTagName: function( n, tagName, includeSelf ) {
        var es = DOM.getAncestors( n, includeSelf );
        return DOM.filterElementsByTagName( es, tagName );
    },
    
    
    getFirstAncestorByTagName: function( n, tagName, includeSelf ) {
        return DOM.getAncestorsByTagName( n, tagName, includeSelf )[ 0 ];
    },


    getAncestorsByClassName: function( n, className, includeSelf ) {
        var es = DOM.getAncestors( n, includeSelf );
        return DOM.filterElementsByClassName( es, className );
    },


    getFirstAncestorByClassName: function( n, className, includeSelf ) {
        return DOM.getAncestorsByClassName( n, className, includeSelf )[ 0 ];
    },


    getAncestorsByTagAndClassName: function( n, tagName, className, includeSelf ) {
        var es = DOM.getAncestorsByTagName( n, tagName, includeSelf );
        return DOM.filterElementsByClassName( es, className );
    },


    getFirstAncestorByTagAndClassName: function( n, tagName, className, includeSelf ) {
        return DOM.getAncestorsByTagAndClassName( n, tagName, className, includeSelf )[ 0 ];
    },


    getPreviousElement: function( n ) {
        n = n.previousSibling;
        while( n ) {
            if( n.nodeType == Node.ELEMENT_NODE )
                return n;
            n = n.previousSibling;
        }
        return null;
    },


    getNextElement: function( n ) {
        n = n.nextSibling;
        while( n ) {
            if( n.nodeType == Node.ELEMENT_NODE )
                return n;
            n = n.nextSibling;
        }
        return null;
    },


    isInlineNode: function( n ) {
        // text nodes are inline
        if( n.nodeType == Node.TEXT_NODE )
            return n;

        // document nodes are non-inline
        if( n.nodeType == Node.DOCUMENT_NODE )
            return false;

        // all nonelement nodes are inline
        if( n.nodeType != Node.ELEMENT_NODE )
            return n;

        // br elements are not inline
        if( n.tagName && n.tagName.toLowerCase() == "br" )
            return false;

        // examine the style property of the inline n
        var display = DOM.getStyle( n, "display" ); 
        if( display && display.indexOf( "inline" ) >= 0 ) 
            return n;
    },
    
    
    isTextNode: function( n ) {
        if( n.nodeType == Node.TEXT_NODE )
            return n;
    },
    
    
    isInlineTextNode: function( n ) {
        if( n.nodeType == Node.TEXT_NODE )
            return n;
        if( !DOM.isInlineNode( n ) )
            return null;
    },


    /* this and the following classname functions honor w3c case-sensitive classnames */

    getClassNames: function( e ) {
        if( !e || !e.className )
            return [];
        return e.className.split( /\s+/g );
    },


    hasClassName: function( e, className ) {
        if( !e || !e.className )
            return false;
        var cs = DOM.getClassNames( e );
        for( var i = 0; i < cs.length; i++ ) {
            if( cs[ i ] == className )
                return true;
        }
        return false;
    },


    addClassName: function( e, className ) {
        if( !e || !className )
            return false;
        var cs = DOM.getClassNames( e );
        for( var i = 0; i < cs.length; i++ ) {
            if( cs[ i ] == className )
                return true;
        }
        cs.push( className );
        e.className = cs.join( " " );
        return false;
    },


    removeClassName: function( e, className ) {
        var r = false;
        if( !e || !e.className || !className )
            return r;
        var cs = (e.className && e.className.length)
            ? e.className.split( /\s+/g )
            : [];
        var ncs = [];
        for( var i = 0; i < cs.length; i++ ) {
            if( cs[ i ] == className ) {
                r = true;
                continue;
            }
            ncs.push( cs[ i ] );
        }
        if( r )
            e.className = ncs.join( " " );
        return r;
    },
    
    
    /* tree manipulation methods */
    
    replaceWithChildNodes: function( n ) {
        var firstChild = n.firstChild;
        var parentNode = n.parentNode;
        while( n.firstChild )
            parentNode.insertBefore( n.removeChild( n.firstChild ), n );
        parentNode.removeChild( n );
        return firstChild;
    },
    
    
    /* factory methods */
    
    createInvisibleInput: function( d ) {
        if( !d )
            d = window.document;
        var e = document.createElement( "input" );
        e.setAttribute( "autocomplete", "off" );
        e.autocomplete = "off";
        DOM.makeInvisible( e );
        return e;
    },


    getMouseEventAttribute: function( event, a ) {
        if( !a )
            return;
        var es = DOM.getAncestors( event.target, true );
        for( var i = 0; i < es.length; i++ ) {
            try {
                var e = es[ i ]
                var v = e.getAttribute ? e.getAttribute( a ) : null;
                if( v ) {
                    event.attributeElement = e;
                    event.attribute = v;
                    return v;
                }
            } catch( e ) {}
        }
    },
    

    setElementAttribute: function( e, a, v ) {
        /* safari workaround
         * safari's setAttribute assumes you want to use a namespace
         * when you have a colon in your attribute
         */
        if ( navigator.userAgent.toLowerCase().match(/webkit/) ) {
            var at = e.attributes;
            for ( var i = 0; i < at.length; i++ )
                if ( at[ i ].name == a )
                    return at[ i ].nodeValue = v;
        } else
            e.setAttribute( a, v );
    },


    swapAttributes: function( e, tg, at ) {
        var ar = e.getAttribute( tg );
        if( !ar )
            return false;
        
        /* clone the node with all children */
        if ( e.tagName.toLowerCase() == 'script' ) {
            /* only clone and replace script tags */
            var cl = e.cloneNode( true );
            if ( !cl )
                return false;

            DOM.setElementAttribute( cl, at, ar );
            cl.removeAttribute( tg );
        
            /* replace new, old */
            return e.parentNode.replaceChild( cl, e );
        } else {
            DOM.setElementAttribute( e, at, ar );
            e.removeAttribute( tg );
        }
    },


    findPosX: function( e ) {
        var curleft = 0;

        if (e.offsetParent) {
            while (1) {
                curleft += e.offsetLeft;
                if (!e.offsetParent) {
                    break;
                }
                e = e.offsetParent;
            }
        } else if (e.x) {
            curleft += e.x;
        }

        return curleft;
    },


    findPosY: function( e ) {
        var curtop = 0;

        if (e.offsetParent) {
            while (1) {
                curtop += e.offsetTop;
                if (!e.offsetParent) {
                    break;
                }
                e = e.offsetParent;
            }
        } else if (e.y) {
            curtop += e.y;
        }

        return curtop;
    },
	
	getSelectedRange: function(node)
	{
		var start = 0,
			end = 0;
		if ('selectionStart' in node)
		{
			start = node.selectionStart;
			end = node.selectionEnd;
		}
		else if (node.createTextRange)
		{
			var range = document.selection.createRange(),
				dup = range.duplicate();
			
			if (range.parentElement() == node)
			{
				if (node.type == 'text') {
					start = -dup.moveStart('character', -100000);
					end = start + range.text.length;
				}
				else // textarea
				{
					var rex = /\r/g;
					dup.moveToElementText(node);
					dup.setEndPoint('EndToStart', range);
					start = dup.text.replace(rex, '').length;
					dup.setEndPoint('EndToEnd', range);
					end = dup.text.replace(rex, '').length;
					dup = document.selection.createRange();
					dup.moveToElementText(node);
					dup.moveStart('character', start);
					while (dup.move('character', -dup.compareEndPoints('StartToStart', range)))
					{
						start++;
					}
					dup.moveStart('character', end-start);
					while (dup.move('character', -dup.compareEndPoints('StartToEnd', range)))
					{
						end++;
					}
				}
			}
		}
		return {
			start: start,
			end: end
		}
	},
	
	setSelectedRange: function(node, start, end)
	{
		// see https://bugzilla.mozilla.org/show_bug.cgi?id=265159
		node.focus(); 
		if (node.setSelectionRange)
		{
			node.setSelectionRange(start, end);
			return;
		}
		// IE, "else" for opera 10
		else if (document.selection && document.selection.createRange)
		{
			var range = node.createTextRange();
			range.collapse(true);
			range.moveEnd('character', end);
			range.moveStart('character', start);
			range.select();
		}
	}
} );


$ = DOM.getElement;
var HTTPReq = new Object;

HTTPReq.create = function () {
    var xtr;
    var ex;

    if (typeof(XMLHttpRequest) != "undefined") {
        xtr = new XMLHttpRequest();
    } else {
        try {
            xtr = new ActiveXObject("Msxml2.XMLHTTP.4.0");
        } catch (ex) {
            try {
                xtr = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (ex) {
            }
        }
    }

    // let me explain this.  Opera 8 does XMLHttpRequest, but not setRequestHeader.
    // no problem, we thought:  we'll test for setRequestHeader and if it's not present
    // then fall back to the old behavior (treat it as not working).  BUT --- IE6 won't
    // let you even test for setRequestHeader without throwing an exception (you need
    // to call .open on the .xtr first or something)
    try {
        if (xtr && ! xtr.setRequestHeader)
            xtr = null;
    } catch (ex) { }

    return xtr;
};

// opts:
// url, onError, onData, method (GET or POST), data
// url: where to get/post to
// onError: callback on error
// onData: callback on data received
// method: HTTP method, GET by default
// data: what to send to the server (urlencoded)
HTTPReq.getJSON = function (opts) {
    var req = HTTPReq.create();
    if (! req) {
        if (opts.onError) opts.onError("noxmlhttprequest");
        return;
    }

    var state_callback = function () {
        if (req.readyState != 4) return;

        if (req.status != 200) {
            if (opts.onError) opts.onError(req.status ? "status: " + req.status : "no data");
            return;
        }

        var resObj;
        var e;
        try {
            eval("resObj = " + req.responseText + ";");
        } catch (e) {
        }

        if (e || ! resObj) {
            if (opts.onError)
                opts.onError("Error parsing response: \"" + req.responseText + "\"");

            return;
        }

        if (opts.onData)
            opts.onData(resObj);
    };

    req.onreadystatechange = state_callback;

    var method = opts.method || "GET";
    var data = opts.data || null;

    var url = opts.url;
    if (opts.method == "GET" && opts.data) {
        url += url.match(/\?/) ? "&" : "?";
        url += opts.data
    }

    url += url.match(/\?/) ? "&" : "?";
    url += "_rand=" + Math.random();

    req.open(method, url, true);

    // we should send null unless we're in a POST
    var to_send = null;

    if (method.toUpperCase() == "POST") {
        req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        to_send = data;
    }

    req.send(to_send);
};

HTTPReq.formEncoded = function (vars) {
    var enc = [];
    var e;
    for (var key in vars) {
	    enc.push(encodeURIComponent(key) + "=" + encodeURIComponent(vars[key]));
    }
    return enc.join("&");
};

// This file contains general-purpose LJ code
LiveJournal = {
	hooks: {} // The hook mappings
}

LiveJournal.register_hook = function (hook, func) {
    if (! LiveJournal.hooks[hook])
        LiveJournal.hooks[hook] = [];

    LiveJournal.hooks[hook].push(func);
};

// args: hook, params to pass to hook
LiveJournal.run_hook = function () {
    var a = arguments;

    var hookfuncs = LiveJournal.hooks[a[0]];
    if (!hookfuncs || !hookfuncs.length) return;

    var hookargs = [];

    for (var i = 1; i < a.length; i++) {
        hookargs.push(a[i]);
    }

    var rv = null;

    hookfuncs.forEach(function (hookfunc) {
        rv = hookfunc.apply(null, hookargs);
    });

    return rv;
};

LiveJournal.initPage = function () {
    // set up various handlers for every page
    LiveJournal.initInboxUpdate();
    AdEngine.init();

    // run other hooks
    LiveJournal.run_hook("page_load");
};

jQuery(LiveJournal.initPage);

// Set up a timer to keep the inbox count updated
LiveJournal.initInboxUpdate = function () {
    // Don't run if not logged in or this is disabled
    if (! Site || ! Site.has_remote || ! Site.inbox_update_poll) return;

    // Don't run if no inbox count
    var unread = $("LJ_Inbox_Unread_Count");
    if (! unread) return;

    // Update every five minutes
    window.setInterval(LiveJournal.updateInbox, 1000 * 60 * 5);
};

// Do AJAX request to find the number of unread items in the inbox
LiveJournal.updateInbox = function () {
    var postData = {
        "action": "get_unread_items"
    };

    var opts = {
        "data": HTTPReq.formEncoded(postData),
        "method": "POST",
        "onData": LiveJournal.gotInboxUpdate
    };

    opts.url = Site.currentJournal ? "/" + Site.currentJournal + "/__rpc_esn_inbox" : "/__rpc_esn_inbox";

    HTTPReq.getJSON(opts);
};

// We received the number of unread inbox items from the server
LiveJournal.gotInboxUpdate = function (resp) {
    if (! resp || resp.error) return;

    var unread = $("LJ_Inbox_Unread_Count");
    if (! unread) return;

    unread.innerHTML = resp.unread_count ? "  (" + resp.unread_count + ")" : "";
};

// Placeholder onclick event
LiveJournal.placeholderClick = function(link, html)
{
	// use replaceChild for no blink scroll effect
	link.parentNode.parentNode.replaceChild(jQuery(unescape(html))[0], link.parentNode);
	
	return false
}

// handy utilities to create elements with just text in them
function _textSpan () { return _textElements("span", arguments); }
function _textDiv  () { return _textElements("div", arguments);  }

function _textElements (eleType, txts) {
    var ele = [];
    for (var i = 0; i < txts.length; i++) {
        var node = document.createElement(eleType);
        node.innerHTML = txts[i];
        ele.push(node);
    }

    return ele.length == 1 ? ele[0] : ele;
};

LiveJournal.pollAnswerClick = function(e, data)
{
	if (!data.pollid || !data.pollqid) return false;
	
	var xhr = jQuery.post(LiveJournal.getAjaxUrl('poll'), {
			pollid   : data.pollid,
			pollqid  : data.pollqid,
			page     : data.page,
			pagesize : data.pagesize,
			action   : 'get_answers'
		}, function(data, status) {
			status == 'success' ?
				LiveJournal.pollAnswersReceived(data):
				LiveJournal.ajaxError(data);
	}, 'json');
	
	jQuery(e).hourglass(xhr);
	
	return false;
}

LiveJournal.pollAnswersReceived = function(answers)
{
	if (!answers || !answers.pollid || !answers.pollqid) return;
	
	if (answers.error) return LiveJournal.ajaxError(answers.error);
	
	var id = '#LJ_Poll_' + answers.pollid + '_' + answers.pollqid,
		to_remove = '.LJ_PollAnswerLink, .lj_pollanswer, .lj_pollanswer_paging',
		html = '<div class="lj_pollanswer">' + (answers.answer_html || '(No answers)') + '</div>';
	
	answers.paging_html && (html += '<div class="lj_pollanswer_paging">' + answers.paging_html + '</div>');
	
	jQuery(id).find(to_remove).remove()
		.end().prepend(html).find('.lj_pollanswer').ljAddContextualPopup();
}

// gets a url for doing ajax requests
LiveJournal.getAjaxUrl = function (action) {
    // if we are on a journal subdomain then our url will be
    // /journalname/__rpc_action instead of /__rpc_action
    return Site.currentJournal
        ? "/" + Site.currentJournal + "/__rpc_" + action
        : "/__rpc_" + action;
};

// generic handler for ajax errors
LiveJournal.ajaxError = function (err) {
    if (LJ_IPPU) {
        LJ_IPPU.showNote("Error: " + err);
    } else {
        alert("Error: " + err);
    }
};

LiveJournal.insertAdsMulti = function (params) {
  var i = 0;
  var containers = [];

  for (i = 0; i < params.length; i++) {
    if (! params[i].html || params[i].html == "<ul>\n</ul>") continue;
    AdEngine.insertAdResponse( params[i] );
    containers.push(document.getElementById(params[i].id));
  }

    // add the ad box style to the containers
    containers.forEach(function (container) {
      if (! container) return;

      DOM.addClassName(container.parentNode, "lj_content_ad");
      DOM.removeClassName(container.parentNode, "lj_inactive_ad");
    });
};

// given a URL, parse out the GET args and return them in a hash
LiveJournal.parseGetArgs = function (url) {
    var getArgsHash = {};

    var urlParts = url.split("?");
    if (!urlParts[1]) return getArgsHash;
    var getArgs = urlParts[1].split("&");
    
    for(var arg=0;arg<getArgs.length;arg++){
    	var pair = getArgs[arg].split("=");
        getArgsHash[pair[0]] = pair[1];

    }	    

    return getArgsHash;
};
/* 
AdEngine
$Id: AdEngine.js 226 2007-09-18 18:20:57Z janine $

Copyright (c) 2006, Six Apart, Ltd.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.

    * Neither the name of "Six Apart" nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

AdEngine = {

    /* called from window.onload ONLY on the logged out blog side (view) */
    init: function() {
        var es = document.getElementsByTagName( "script" );
        for ( var i = 0; i < es.length; i++ ) {
            var ar = es[ i ].getAttribute( "defersrc" );
            if( !ar )
                continue;
        
            var cl = es[ i ].cloneNode( true );
            if ( !cl )
                continue;

            cl.setAttribute( "src", ar );
            cl.removeAttribute( "defersrc" );
        
            /* replace new, old */
            try {
                es[ i ].parentNode.replaceChild( cl, es[ i ] );
            } catch (e) {}
        }
    },
    
    
    insertAdResponse: function( params ) {
        var e = document.getElementById( params.id );
        if( !e )
            return;
        if( params.html ) {
            var e2 = document.createElement( "div" );
            e2.innerHTML = params.html;
            e.innerHTML = ""; // clear old content
            e.appendChild( e2 );
        }
        if( params.js )
            return eval( "(" + params.js + ")" );
    },

    insertAdsMulti: function( params ) {
        var i = 0;
        for (i = 0; i < params.length; i++) {
            AdEngine.insertAdResponse( params[i] );
        }
    }

};
var ESN = new Object();

LiveJournal.register_hook("page_load", function () {
  ESN.initCheckAllBtns();
  ESN.initEventCheckBtns();
  ESN.initTrackBtns();
});

// When page loads, set up "check all" checkboxes
ESN.initCheckAllBtns = function () {
  var ntids  = $("ntypeids");
  var catids = $("catids");

  if (!ntids || !catids)
    return;

  ntidList  = ntids.value;
  catidList = catids.value;

  if (!ntidList || !catidList)
    return;

  ntids  = ntidList.split(",");
  catids = catidList.split(",");

  catids.forEach( function (catid) {
    ntids.forEach( function (ntypeid) {
      var className = "SubscribeCheckbox-" + catid + "-" + ntypeid;

      var cab = new CheckallButton();
      cab.init({
        "class": className,
          "button": $("CheckAll-" + catid + "-" + ntypeid),
          "parent": $("CategoryRow-" + catid)
          });
    });
  });
}

// set up auto show/hiding of notification methods
ESN.initEventCheckBtns = function () {
  var viewObjects = document.getElementsByTagName("*");
  var boxes = DOM.filterElementsByClassName(viewObjects, "SubscriptionInboxCheck") || [];

  boxes.forEach( function (box) {
    DOM.addEventListener(box, "click", ESN.eventChecked.bindEventListener());
  });
}

ESN.eventChecked = function (evt) {
  var target = evt.target;
  if (!target)
    return;

  var parentRow = DOM.getFirstAncestorByTagName(target, "tr", false);

  var viewObjects = parentRow.getElementsByTagName("*");
  var boxes = DOM.filterElementsByClassName(viewObjects, "NotificationOptions") || [];

  boxes.forEach( function (box) {
    box.style.visibility = target.checked ? "visible" : "hidden";
  });
}

// attach event handlers to all track buttons
ESN.initTrackBtns = function (node) {
    // don't do anything if no remote
    if (!Site.has_remote) return;

    node = node || document;
    var trackBtns = DOM.getElementsByTagAndClassName(node, 'img', 'TrackButton');

    trackBtns.forEach(function (trackBtn) {
        if (!trackBtn || !trackBtn.getAttribute) return;

        if (!trackBtn.getAttribute("lj_subid") && !trackBtn.getAttribute("lj_journalid")) return;
        if (trackBtn.getAttribute("lj_dtalkid") && !Site.remote_can_track_threads) return;

        DOM.addEventListener(trackBtn, 'click', ESN.trackBtnClickHandler.bindEventListener(trackBtn));
    });
};

ESN.trackBtnClickHandler = function (evt) {
    var trackBtn = evt.target;
    if (! trackBtn || trackBtn.tagName.toLowerCase() != "img") return true;

    Event.stop(evt);

    var btnInfo = {};

    ['arg1', 'arg2', 'etypeid', 'newentry_etypeid', 'newentry_token', 'newentry_subid',
     'journalid', 'subid', 'auth_token'].forEach(function (arg) {
        btnInfo[arg] = trackBtn.getAttribute("lj_" + arg);
    });

    // pop up little dialog to either track by inbox/email or go to more options
    var dlg = document.createElement("div");
    var title = _textDiv("Email me when");
    DOM.addClassName(title, "track_title");
    dlg.appendChild(title);

    var TrackCheckbox = function (title, checked) {
        var checkContainer = document.createElement("div");

        var newCheckbox = document.createElement("input");
        newCheckbox.type = "checkbox";
        newCheckbox.id = "newentrytrack" + Unique.id();
        var newCheckboxLabel = document.createElement("label");
        newCheckboxLabel.setAttribute("for", newCheckbox.id);
        newCheckboxLabel.innerHTML = title;

        checkContainer.appendChild(newCheckbox);
        checkContainer.appendChild(newCheckboxLabel);
        dlg.appendChild(checkContainer);

        newCheckbox.checked = checked ? true : false;

        return newCheckbox;
    };

    // global trackPopup so we can only have one
    if (ESN.trackPopup) {
        ESN.trackPopup.hide();
        ESN.trackPopup = null;
    }

    var saveChangesBtn = document.createElement("input");
    saveChangesBtn.type = "button";
    saveChangesBtn.value = "Save Changes";
    DOM.addClassName(saveChangesBtn, "track_savechanges");

    var trackingNewEntries  = Number(btnInfo['newentry_subid']) ? 1 : 0;
    var trackingNewComments = Number(btnInfo['subid']) ? 1 : 0;

    var newEntryTrackBtn;
    var commentsTrackBtn;

    if (trackBtn.getAttribute("lj_dtalkid")) {
        // this is a thread tracking button
        // always checked: either because they're subscribed, or because
        // they're going to subscribe.
        commentsTrackBtn = TrackCheckbox("someone replies in this comment thread", 1);
    } else {
        // entry tracking button
        newEntryTrackBtn = TrackCheckbox(LJ_cmtinfo["journal"] + " posts a new entry", trackingNewEntries);
        commentsTrackBtn = TrackCheckbox("someone comments on this post", trackingNewComments);
    }

    DOM.addEventListener(saveChangesBtn, "click", function () {
        ESN.toggleSubscriptions(btnInfo, evt, trackBtn, {
            newEntry: newEntryTrackBtn ? newEntryTrackBtn.checked : false,
            newComments: commentsTrackBtn.checked
        });
        if (ESN.trackPopup) ESN.trackPopup.hide();
    });

    var btnsContainer = document.createElement("div");
    DOM.addClassName(btnsContainer, "track_btncontainer");
    dlg.appendChild(btnsContainer);

    btnsContainer.appendChild(saveChangesBtn);

    var custTrackLink = document.createElement("a");
    custTrackLink.href = trackBtn.parentNode.href;
    btnsContainer.appendChild(custTrackLink);
    custTrackLink.innerHTML = "More Options";
    DOM.addClassName(custTrackLink, "track_moreopts");

    ESN.trackPopup = new LJ_IPPU.showNoteElement(dlg, trackBtn, 0);

    DOM.addEventListener(custTrackLink, "click", function (evt) {
        Event.stop(evt);
        document.location.href = trackBtn.parentNode.href;
        if (ESN.trackPopup) ESN.trackPopup.hide();
        return false;
    });

    return false;
}

// toggles subscriptions
ESN.toggleSubscriptions = function (subInfo, evt, btn, subs) {
    subInfo["subid"] = Number(subInfo["subid"]);
    if ((subInfo["subid"] && ! subs["newComments"])
        || (! subInfo["subid"] && subs["newComments"])) {
        ESN.toggleSubscription(subInfo, evt, btn, "newComments");
    }

    subInfo["newentry_subid"] = Number(subInfo["newentry_subid"]);
    if ((subInfo["newentry_subid"] && ! subs["newEntry"])
        || (! subInfo["newentry_subid"] && subs["newEntry"])) {
            var newentrySubInfo = new Object(subInfo);
            newentrySubInfo["subid"] = Number(btn.getAttribute("lj_newentry_subid"));
            ESN.toggleSubscription(newentrySubInfo, evt, btn, "newEntry");
    }
};

// (Un)subscribes to an event
ESN.toggleSubscription = function (subInfo, evt, btn, sub) {
    var action = "";
    var params = {
        auth_token: sub == "newEntry" ? subInfo.newentry_token : subInfo.auth_token
    };

    if (Number(subInfo.subid)) {
        // subscription exists
        action = "delsub";
        params.subid = subInfo.subid;
    } else {
        // create a new subscription
        action = "addsub";

        var param_keys;
        if (sub == "newEntry") {
            params.etypeid = subInfo.newentry_etypeid;
            param_keys = ["journalid"];
        } else {
            param_keys = ["journalid", "arg1", "arg2", "etypeid"];
        }

        param_keys.forEach(function (param) {
            if (Number(subInfo[param]))
                params[param] = parseInt(subInfo[param]);
        });
    }

    params.action = action;

    var reqInfo = {
        "method": "POST",
        "url":    LiveJournal.getAjaxUrl('esn_subs'),
        "data":   HTTPReq.formEncoded(params)
    };

    var gotInfoCallback = function (info) {
        if (! info) return LJ_IPPU.showNote("Error changing subscription", btn);

        if (info.error) return LJ_IPPU.showNote(info.error, btn);

        if (info.success) {
            if (info.msg)
                LJ_IPPU.showNote(info.msg, btn);

            if (info.subscribed) {
                if (info.subid)
                    DOM.setElementAttribute(btn, "lj_subid", info.subid);
                if (info.newentry_subid)
                    DOM.setElementAttribute(btn, "lj_newentry_subid", info.newentry_subid);


                DOM.setElementAttribute(btn, "title", 'Untrack This');

                // update subthread tracking icons
                var dtalkid = btn.getAttribute("lj_dtalkid");
                if (dtalkid)
                    ESN.updateThreadIcons(dtalkid, "on");
                else // not thread tracking button
                    btn.src = Site.imgprefix + "/btn_tracking.gif";
            } else {
                if (info["event_class"] == "LJ::Event::JournalNewComment")
                    DOM.setElementAttribute(btn, "lj_subid", 0);
                else if (info["event_class"] == "LJ::Event::JournalNewEntry")
                    DOM.setElementAttribute(btn, "lj_newentry_subid", 0);

                DOM.setElementAttribute(btn, "title", 'Track This');

                // update subthread tracking icons
                var dtalkid = btn.getAttribute("lj_dtalkid");
                if (dtalkid) {
                    // set state to "off" if no parents tracking this,
                    // otherwise set state to "parent"
                    var state = "off";
                    var parentBtn;
                    var parent_dtalkid = dtalkid;
                    while (parentBtn = ESN.getThreadParentBtn(parent_dtalkid)) {
                        parent_dtalkid = parentBtn.getAttribute("lj_dtalkid");
                        if (! parent_dtalkid) {
                            log("could not find parent_dtalkid");
                            break;
                        }

                        if (! Number(parentBtn.getAttribute("lj_subid")))
                            continue;
                        state = "parent";
                        break;
                    }

                    ESN.updateThreadIcons(dtalkid, state);
                } else {
                    // not thread tracking button
                    btn.src = Site.imgprefix + "/btn_track.gif";
                }
            }

            if (info.auth_token)
                DOM.setElementAttribute(btn, "lj_auth_token", info.auth_token);
            if (info.newentry_token)
                DOM.setElementAttribute(btn, "lj_newentry_token", info.newentry_token);
        }
    };

    reqInfo.onData = gotInfoCallback;
    reqInfo.onError = function (err) { LJ_IPPU.showNote("Error: " + err) };

    HTTPReq.getJSON(reqInfo);
};

// given a dtalkid, find the track button for its parent comment (if any)
ESN.getThreadParentBtn = function (dtalkid) {
    var cmtInfo = LJ_cmtinfo[dtalkid + ""];
    if (! cmtInfo) {
        log("no comment info");
        return null;
    }

    var parent_dtalkid = cmtInfo.parent;
    if (! parent_dtalkid)
        return null;

    return $("lj_track_btn_" + parent_dtalkid);
};

// update all the tracking icons under a parent comment
ESN.updateThreadIcons = function (dtalkid, tracking) {
    var btn = $("lj_track_btn_" + dtalkid);
    if (! btn) {
        log("no button");
        return;
    }

    var cmtInfo = LJ_cmtinfo[dtalkid + ""];
    if (! cmtInfo) {
        log("no comment info");
        return;
    }

    if (Number(btn.getAttribute("lj_subid")) && tracking != "on") {
        // subscription already exists on this button, don't mess with it
        return;
    }

    if (cmtInfo.rc && cmtInfo.rc.length) {
        // update children
        cmtInfo.rc.forEach(function (child_dtalkid) {
            window.setTimeout(function () {
                var state;
                switch (tracking) {
                case "on":
                    state = "parent";
                    break;
                case "off":
                    state = "off";
                    break;
                case "parent":
                    state = "parent";
                    break;
                default:
                    alert("Unknown tracking state " + tracking);
                    break;
                }
                ESN.updateThreadIcons(child_dtalkid, state);
            }, 300);
        });
    }

    // update icon
    var uri;
    switch (tracking) {
        case "on":
            uri = "/btn_tracking.gif";
            break;
        case "off":
            uri = "/btn_track.gif";
            break;
        case "parent":
            uri = "/btn_tracking_thread.gif";
            break;
        default:
            alert("Unknown tracking state " + tracking);
            break;
    }

    btn.src = Site.imgprefix + uri;
};

jQuery(function($){
	$('#settings_form').delegate('a.delete-group', 'click', function(e)
	{
		var group = this.href.match('&delete_group=(.*?)&')[1];
		$.post(location.href, {
			delete_group: group
		});
		
		$(this).parents('tr').eq(0).remove();
		
		e.preventDefault();
	});
});/*
  IPPU methods:
     init([innerHTML]) -- takes innerHTML as optional argument
     show() -- shows the popup
     hide() -- hides popup
     cancel() -- hides and calls cancel callback

  Content setters:
     setContent(innerHTML) -- set innerHTML
     setContentElement(element) -- adds element as a child of the popup

   Accessors:
     getElement() -- returns popup DIV element
     visible() -- returns whether the popup is visible or not

   Titlebar:
     setTitlebar(show) -- true: show titlebar / false: no titlebar
     setTitle(title) -- sets the titlebar text
     getTitlebarElement() -- returns the titlebar element
     setTitlebarClass(className) -- set the class of the titlebar

   Styling:
     setOverflow(overflow) -- sets ele.style.overflow to overflow
     addClass(className) -- adds class to popup
     removeClass(className) -- removes class to popup

   Browser Hacks:
     setAutoHideSelects(autohide) -- when the popup is shown should it find all the selects
                                on the page and hide them (and show them again) (for IE)

   Positioning/Sizing:
     setLocation(left, top) -- set popup location: will be pixels if units not specified
     setLeft(left) -- set left location
     setTop(top)   -- set top location
     setDimensions(width, height) -- set popup dimensions: will be pixels if units not specified
     setAutoCenter(x, y) -- what dimensions to auto-center
     center() -- centers popup on screen
     centerX() -- centers popup horizontally
     centerY() -- centers popup vertically
     setFixedPosition(fixed) -- should the popup stay fixed on the page when it scrolls?
     centerOnWidget(widget) -- center popup on this widget
     setAutoCenterCallback(callback) -- calls callback with this IPPU instance as a parameter
                                        for auto-centering. Some common built-in class methods
                                        you can use as callbacks are:
                                        IPPU.center
                                        IPPU.centerX
                                        IPPU.centerY

     moveForward(amount) -- increases the zIndex by one or amount if specified
     moveBackward(amount) -- decreases the zIndex by one or amount if specified

   Modality:
     setClickToClose(clickToClose) -- if clickToClose is true, clicking outside of the popup
                                      will close it
     setModal(modality) -- If modality is true, then popup will capture all mouse events
                     and optionally gray out the rest of the page. (overrides clickToClose)
     setOverlayVisible(visible) -- If visible is true, when this popup is on the page it
                                   will gray out the rest of the page if this is modal

   Callbacks:
     setCancelledCallback(callback) -- call this when the dialog is closed through clicking
                                       outside, titlebar close button, etc...
     setHiddenCallback(callback) -- called when the dialog is closed in any fashion

   Fading:
     setFadeIn(fadeIn) -- set whether or not to automatically fade the ippu in
     setFadeOut(fadeOut) -- set whether or not to automatically fade the ippu out
     setFadeSpeed(secs) -- sets fade speed

  Class Methods:
   Handy callbacks:
     IPPU.center
     IPPU.centerX
     IPPU.centerY
   Browser testing:
     IPPU.isIE() -- is the browser internet exploder?
     IPPU.ieSafari() -- is this safari?

////////////////////


ippu.setModalDenialCallback(IPPU.cssBorderFlash);


   private:
    Properties:
     ele -- DOM node of div
     shown -- boolean; if element is in DOM
     autoCenterX -- boolean; auto-center horiz
     autoCenterY -- boolean; auto-center vertical
     fixedPosition -- boolean; stay in fixed position when browser scrolls?
     titlebar -- titlebar element
     title -- string; text to go in titlebar
     showTitlebar -- boolean; whether or not to show titlebar
     content -- DIV containing user's specified content
     clickToClose -- boolean; clicking outside popup will close it
     clickHandlerSetup -- boolean; have we set up the click handlers?
     docOverlay -- DIV that overlays the document for capturing clicks
     modal -- boolean; capture all events and prevent user from doing anything
                       until dialog is dismissed
     visibleOverlay -- boolean; make overlay slightly opaque
     clickHandlerFunc -- function; function to handle document clicks
     resizeHandlerFunc -- function; function to handle document resizing
     autoCenterCallback -- function; what callback to call for auto-centering
     cancelledCallback -- function; called when dialog is cancelled
     setAutoHideSelects -- boolean; autohide all SELECT elements on the page when popup is visible
     hiddenSelects -- array; SELECT elements that have been hidden
     hiddenCallback -- funciton; called when dialog is hidden
     fadeIn, fadeOut, fadeSpeed -- fading settings
     fadeMode -- current fading mode (in, out) if there is fading going on

    Methods:
     updateTitlebar() -- create titlebar if it doesn't exist,
                         hide it if titlebar == false,
                         update titlebar text
     updateContent() -- makes sure all currently specified properties are applied
     setupClickCapture() -- if modal, create document-sized div overlay to capture click events
                            otherwise install document onclick handler
     removeClickHandlers() -- remove overlay, event handlers
     clickHandler() -- event handler for clicks
     updateOverlay() -- if we have an overlay, make sure it's where it should be and (in)visible
                        if it should be
     autoCenter() -- centers popup on screen according to autoCenterX and autoCenterY
     hideSelects() -- hide all select element on page
     showSelects() -- show all selects
     _hide () -- actually hides everything, called by hide(), which does fading if necessary
*/

// this belongs somewhere else:
function changeOpac(id, opacity) {
    var e =  $(id);
    if (e && e.style) {
        var object = e.style;
        if (object) {
            //reduce flicker
            if (IPPU.isSafari() && opacity >= 100)
                opacity = 99.99;

            // IE
            if (object.filters)
                object.filters.alpha.opacity = opacity * 100;

            object.opacity = opacity;
        }
    }
}

IPPU = new Class( Object, {
  setFixedPosition: function (fixed) {
    // no fixed position for IE
    if (IPPU.isIE())
      return;

    this.fixedPosition = fixed;
    this.updateContent();
  },

  clickHandler : function (evt) {
    if (!this.clickToClose) return;
    if (!this.visible()) return;

    evt = Event.prep(evt);
    var target = evt.target;
    // don't do anything if inside the popup
    if (DOM.getAncestorsByClassName(target, "ippu", true).length > 0) return;
    this.cancel();
  },

  setCancelledCallback : function (callback) {
    this.cancelledCallback = callback;
  },

  cancel : function () {
    if (this.cancelledCallback)
      this.cancelledCallback();
    this.hide();
  },

  setHiddenCallback: function (callback) {
    this.hiddenCallback = callback;
  },

  setupClickCapture : function () {
    if (!this.visible() || this.clickHandlerSetup){return;}
    if (!this.clickToClose && !this.modal) {return;}

    this.clickHandlerFunc = this.clickHandler.bindEventListener(this);

    if (this.modal) {
      // create document-sized div to capture events
      if (this.overlay) return; // wtf? shouldn't exist yet
      this.overlay = document.createElement("div");
      this.overlay.style.left = "0px";
      this.overlay.style.top = "0px";
      this.overlay.style.margin = "0px";
      this.overlay.style.padding = "0px";
      
      this.overlay.style.backgroundColor = "#000000";
      this.overlay.style.zIndex="900";
      if (IPPU.isIE()){
      		this.overlay.style.filter="progid:DXImageTransform.Microsoft.Alpha(opacity=50)";
		this.overlay.style.position="absolute";
		this.overlay.style.width=document.body.scrollWidth;
		this.overlay.style.height=document.body.scrollHeight;
      }
      else{
      	this.overlay.style.position = "fixed";
      }

      this.ele.parentNode.insertBefore(this.overlay, this.ele);
      this.updateOverlay();

      DOM.addEventListener(this.overlay, "click", this.clickHandlerFunc);
    } else {
      // simple document onclick handler
      DOM.addEventListener(document, "click", this.clickHandlerFunc);
    }

    this.clickHandlerSetup = true;
  },

  updateOverlay : function () {
    if (this.overlay) {
      var cd = DOM.getClientDimensions();
      this.overlay.style.width = (cd.x - 1) + "px";
      if(!IPPU.isIE()){
      	this.overlay.style.height = (cd.y - 1) + "px";
      }	
      if (this.visibleOverlay) {
        this.overlay.backgroundColor = "#000000";
        changeOpac(this.overlay, 0.50);
      } else {
        this.overlay.backgroundColor = "#FFFFFF";
        changeOpac(this.overlay, 0.0);
      }
    }
  },

  resizeHandler : function (evt) {
    this.updateContent();
  },

  removeClickHandlers : function () {
    if (!this.clickHandlerSetup) return;

    var myself = this;
    var handlerFunc = function (evt) {
      myself.clickHandler(evt);
    };

    DOM.removeEventListener(document, "click", this.clickHandlerFunc, false);

    if (this.overlay) {
      DOM.removeEventListener(this.overlay, "click", this.clickHandlerFunc, true);
      this.overlay.parentNode.removeChild(this.overlay);
      this.overlay = undefined;
    }

    this.clickHandlerFunc = undefined;
    this.clickHandlerSetup = false;
  },

  setClickToClose : function (clickToClose) {
    this.clickToClose = clickToClose;

    if (!this.clickHandlerSetup && clickToClose && this.visible()) {
      // popup is already visible, need to set up click handler
      var setupClickCaptureCallback = this.setupClickCapture.bind(this);
      window.setTimeout(setupClickCaptureCallback, 100);
    } else if (!clickToClose && this.clickHandlerSetup) {
      this.removeClickHandlers();
    }

    this.updateContent();
  },

  setModal : function (modal) {
    var changed = (this.modal == modal);

    // if it's modal, we don't want click-to-close
    if (modal)
      this.setClickToClose(false);

    this.modal = modal;
    if (changed) {
      this.removeClickHandlers();
      this.updateContent();
    }
  },

  setOverlayVisible : function (vis) {
    this.visibleOverlay = vis;
    this.updateContent();
  },

  updateContent : function () {
    this.autoCenter();
    this.updateTitlebar();
    this.updateOverlay();
    if (this.titlebar)
      this.setTitlebarClass(this.titlebar.className);

    var setupClickCaptureCallback = this.setupClickCapture.bind(this);
    window.setTimeout(setupClickCaptureCallback, 100);

    if (this.fixedPosition && this.ele.style.position != "fixed")
      this.ele.style.position = "fixed";
    else if (!this.fixedPosition && this.ele.style.position == "fixed")
      this.ele.style.position = "absolute";
  },

  getTitlebarElement : function () {
    return this.titlebar;
  },

  setTitlebarClass : function (className) {
    if (this.titlebar)
      this.titlebar.className = className;
  },

  setOverflow : function (overflow) {
    if (this.ele)
      this.ele.style.overflow = overflow;
  },

  visible : function () {
    return this.shown;
  },

  setTitlebar : function (show) {
    this.showTitlebar = show;

    if (show) {
      if (!this.titlebar) {
        // titlebar hasn't been created. Create it.
        var tbar = document.createElement("div");
        if (!tbar) return;
        tbar.style.width = "100%";

        if (this.title) tbar.innerHTML = this.title;
        this.ele.insertBefore(tbar, this.content);
        this.titlebar = tbar;

      }
    } else if (this.titlebar) {
      this.ele.removeChild(this.titlebar);
      this.titlebar = false;
    }
  },

  setTitle : function (title) {
    this.title = title;
    this.updateTitlebar();
  },

  updateTitlebar : function() {
    if (this.showTitlebar && this.titlebar && this.title != this.titlebar.innerHTML) {
      this.titlebar.innerHTML = this.title;
    }
  },

  addClass : function (className) {
    DOM.addClassName(this.ele, className);
  },

  removeClass : function (className) {
    DOM.removeClassName(this.ele, className);
  },

  setAutoCenterCallback : function (callback) {
    this.autoCenterCallback = callback;
  },

  autoCenter : function () {
    if (!this.visible || !this.visible()) return;

    if (this.autoCenterCallback) {
      this.autoCenterCallback(this);
      return;
    }

    if (this.autoCenterX)
      this.centerX();

    if (this.autoCenterY)
      this.centerY();
  },

  center : function () {
    this.centerX();
    this.centerY();
  },

  centerOnWidget : function (widget, offsetTop, offsetLeft) {
        offsetTop = offsetTop || 0;
        offsetLeft = offsetLeft || 0;
        this.setAutoCenter(false, false);
        this.setAutoCenterCallback(null);
  var wd = DOM.getAbsoluteDimensions(widget);
    var ed = DOM.getAbsoluteDimensions(this.ele);
    var newleft = (wd.absoluteRight - wd.offsetWidth / 2 - ed.offsetWidth / 2) + offsetLeft;
    var newtop = (wd.absoluteBottom - wd.offsetHeight / 2 - ed.offsetHeight / 2) + offsetTop;

        newleft = newleft < 0 ? 0 : newleft;
        newtop  = newtop  < 0 ? 0 : newtop;
    DOM.setLeft(this.ele, newleft);
    DOM.setTop(this.ele, newtop);
  },

  centerX : function () {
    if (!this.visible || !this.visible()) return;

    var cd = DOM.getClientDimensions();
    var newleft = cd.x / 2 - DOM.getDimensions(this.ele).offsetWidth / 2;

    // If not fixed position, center relative to the left of the page
    if (!this.fixedPosition) {
        var wd = DOM.getWindowScroll();
        newleft += wd.left;
    }

   DOM.setLeft(this.ele, newleft);
  },

  centerY : function () {
    if (!this.visible || !this.visible()) return;

    var cd = DOM.getClientDimensions();
    var newtop = cd.y / 2 - DOM.getDimensions(this.ele).offsetHeight / 2;

    // If not fixed position, center relative to the top of the page
    if (!this.fixedPosition) {
        var wd = DOM.getWindowScroll();
        newtop += wd.top;
    }

    DOM.setTop(this.ele, newtop);
  },

  setAutoCenter : function (autoCenterX, autoCenterY) {
    this.autoCenterX = autoCenterX || false;
    this.autoCenterY = autoCenterY || false;

    if (!autoCenterX && !autoCenterY) {
        this.setAutoCenterCallback(null);
        return;
    }

    this.autoCenter();
  },

  setDimensions : function (width, height) {
    width = width + "";
    height = height + "";
    if (width.match(/^\d+$/)) width += "px";
    if (height.match(/^\d+$/)) height += "px";

    this.ele.style.width  = width;
    this.ele.style.height = height;
  },

  moveForward : function (howMuch) {
      if (!howMuch) howMuch = 1;
      if (! this.ele) return;

      this.ele.style.zIndex += howMuch;
  },

  moveBackward : function (howMuch) {
      if (!howMuch) howMuch = 1;
      if (! this.ele) return;

      this.ele.style.zIndex -= howMuch;
  },

  setLocation : function (left, top) {
      this.setLeft(left);
      this.setTop(top);
  },

  setTop : function (top) {
   if (typeof top != 'string') top += 'px';
     this.ele.style.top = top;
  },

  setLeft : function (left) {
	if (typeof left != 'string') left += 'px';
    this.ele.style.left = left;
  },

  getElement : function () {
    return this.ele;
  },

  setContent : function (html) {
    this.content.innerHTML = html;
  },

  setContentElement : function (element) {
      // remove child nodes
      while (this.content.firstChild) {
          this.content.removeChild(this.content.firstChild);
      };

    this.content.appendChild(element);
  },

  setFadeIn : function (fadeIn) {
      this.fadeIn = fadeIn;
  },

  setFadeOut : function (fadeOut) {
      this.fadeOut = fadeOut;
  },

  setFadeSpeed : function (fadeSpeed) {
      this.fadeSpeed = fadeSpeed;
  },

  show : function () {
    this.shown = true;

    if (this.fadeIn) {
        var opp = 0.01;

        changeOpac(this.ele, opp);
    }

    document.body.appendChild(this.ele);
    this.ele.style.position = "absolute";
    if (this.autoCenterX || this.autoCenterY) this.center();

    this.updateContent();

    if (!this.resizeHandlerFunc) {
      this.resizeHandlerFunc = this.resizeHandler.bindEventListener(this);
      DOM.addEventListener(window, "resize", this.resizeHandlerFunc, false);
    }

    if (this.fadeIn)
        this.fade("in");

    this.hideSelects();
  },

  fade : function (mode, callback) {
      var opp;
      var delta;

      var steps = 10.0;

      if (mode == "in") {
          delta = 1 / steps;
          opp = 0.1;
      } else {
          if (this.ele.style.opacity)
          opp = finiteFloat(this.ele.style.opacity);
          else
          opp = 0.99;

          delta = -1 / steps;
      }

      var fadeSpeed = this.fadeSpeed;
      if (!fadeSpeed) fadeSpeed = 1;

      var fadeInterval = steps / fadeSpeed * 5;

      this.fadeMode = mode;

      var self = this;
      var fade = function () {
          opp += delta;

          // did someone start a fade in the other direction? if so,
          // cancel this fade
          if (self.fadeMode && self.fadeMode != mode) {
              if (callback)
                  callback.call(self, []);

              return;
          }

          if (opp <= 0.1) {
              if (callback)
                  callback.call(self, []);

              self.fadeMode = null;

              return;
          } else if (opp >= 1.0) {
              if (callback)
                  callback.call(self, []);

              self.fadeMode = null;

              return;
          } else {
              changeOpac(self.ele, opp);
              window.setTimeout(fade, fadeInterval);
          }
      };

      fade();
  },

  hide : function () {
    if (! this.visible()) return;

    if (this.fadeOut && this.ele) {
        this.fade("out", this._hide.bind(this));
    } else {
        this._hide();
    }
  },

  _hide : function () {
    if (this.hiddenCallback)
      this.hiddenCallback();

    this.shown = false;
    this.removeClickHandlers();

    if (this.ele)
    document.body.removeChild(this.ele);

    if (this.resizeHandlerFunc)
      DOM.removeEventListener(window, "resize", this.resizeHandlerFunc);

    this.showSelects();
  },

  // you probably want this for IE being dumb
  // (IE thinks select elements are cool and puts them in front of every element on the page)
  setAutoHideSelects : function (autohide) {
    this.autoHideSelects = autohide;
    this.updateContent();
  },

  hideSelects : function () {
    if (!this.autoHideSelects || !IPPU.isIE()) return;
    var sels = document.getElementsByTagName("select");
    var ele;
    for (var i = 0; i < sels.length; i++) {
      ele = sels[i];
      if (!ele) continue;

      // if this element is inside the ippu, skip it
      if (DOM.getAncestorsByClassName(ele, "ippu", true).length > 0) continue;

      if (ele.style.visibility != 'hidden') {
        ele.style.visibility = 'hidden';
        this.hiddenSelects.push(ele);
      }
    }
  },

  showSelects : function () {
    if (! this.autoHideSelects) return;
    var ele;
    while (ele = this.hiddenSelects.pop())
      ele.style.visibility = '';
  },

  init: function (html) {
    var ele = document.createElement("div");
    this.ele = ele;
    this.shown = false;
    this.autoCenterX = false;
    this.autoCenterY = false;
    this.titlebar = null;
    this.title = "";
    this.showTitlebar = false;
    this.clickToClose = false;
    this.modal = false;
    this.clickHandlerSetup = false;
    this.docOverlay = false;
    this.visibleOverlay = false;
    this.clickHandlerFunc = false;
    this.resizeHandlerFunc = false;
    this.fixedPosition = false;
    this.autoCenterCallback = null;
    this.cancelledCallback = null;
    this.autoHideSelects = false;
    this.hiddenCallback = null;
    this.fadeOut = false;
    this.fadeIn = false;
    this.hiddenSelects = [];
    this.fadeMode = null;

    ele.style.position = "absolute";
	ele.style.top = 0;
    ele.style.zIndex   = "1000";

    // plz don't remove thx
    DOM.addClassName(ele, "ippu");

    // create DIV to hold user's content
    this.content = document.createElement("div");

    this.content.innerHTML = html;

    this.ele.appendChild(this.content);
  }
});

// class methods
IPPU.center = function (obj) {
  obj.centerX();
  obj.centerY();
};

IPPU.centerX = function (obj) {
  obj.centerX();
};

IPPU.centerY = function (obj) {
  obj.centerY();
};

IPPU.isIE = function () {
    var UA = navigator.userAgent.toLowerCase();
    if (UA.indexOf('msie') != -1) return true;
    return false;
};

IPPU.isSafari = function () {
    var UA = navigator.userAgent.toLowerCase();
    if (UA.indexOf('safari') != -1) return true;
    return false;
};
LJ_IPPU = new Class ( IPPU, {
  init: function(title) {
    if (!title)
      title = "";

    LJ_IPPU.superClass.init.apply(this, []);

    this.uniqId = this.generateUniqId();
    this.cancelThisFunc = this.cancel.bind(this);

    this.setTitle(title);
    this.setTitlebar(true);
    this.setTitlebarClass("lj_ippu_titlebar");

    this.addClass("lj_ippu");
    this.setAutoCenterCallback(IPPU.center);
    this.setDimensions(514, "auto");
    //this.setOverflow("hidden");

    this.setFixedPosition(true);
    this.setClickToClose(true);
    this.setAutoHideSelects(true);
 },

  setTitle: function (title) {
    var titlebarContent = "\
      <div style='float:right; padding-right: 8px'>" +
      "<img src='" + Site.imgprefix + "/CloseButton.gif' width='15' height='15' id='" + this.uniqId + "_cancel' /></div>" + title;

    LJ_IPPU.superClass.setTitle.apply(this, [titlebarContent]);
    
      
  },

  generateUniqId: function() {
    var theDate = new Date();
    return "lj_ippu_" + theDate.getHours() + theDate.getMinutes() + theDate.getMilliseconds();
  },

  show: function() {
    LJ_IPPU.superClass.show.apply(this);
    var setupCallback = this.setup_lj_ippu.bind(this);
    this.timerSetup = window.setTimeout(setupCallback, 300);
  },

  setup_lj_ippu: function (evt) {
    var cancelCallback = this.cancelThisFunc;
   //DOM.addEventListener($(this.uniqId + "_cancel"), "click", cancelCallback, true);
   $(this.uniqId + "_cancel").onclick = function(){
	    cancelCallback();
    };
  },

  hide: function() {
    clearInterval(this.timerSetup);
    LJ_IPPU.superClass.hide.apply(this);
  }
} );

// Class method to show a popup to show a note to the user
// note = message to show
// underele = element to display the note underneath
LJ_IPPU.showNote = function (note, underele, timeout, style) {
    var noteElement = document.createElement("div");
    noteElement.innerHTML = note;

    return LJ_IPPU.showNoteElement(noteElement, underele, timeout, style);
};

LJ_IPPU.showErrorNote = function (note, underele, timeout) {
    return LJ_IPPU.showNote(note, underele, timeout, "ErrorNote");
};

LJ_IPPU.showNoteElement = function (noteEle, underele, timeout, style) {
    var notePopup = new IPPU();
    notePopup.init();

    var inner = document.createElement("div");
    DOM.addClassName(inner, "Inner");
    inner.appendChild(noteEle);
    notePopup.setContentElement(inner);

    notePopup.setTitlebar(false);
    notePopup.setFadeIn(true);
    notePopup.setFadeOut(true);
    notePopup.setFadeSpeed(4);
    notePopup.setDimensions("auto", "auto");
    if (!style) style = "Note";
    notePopup.addClass(style);

    var dim;
    if (underele) {
        // pop up the box right under the element
        dim = DOM.getAbsoluteDimensions(underele);
        if (!dim) return;
    }

    var bounds = DOM.getClientDimensions();
    if (!bounds) return;

    if (!dim) {
        // no element specified to pop up on, show in the middle
        // notePopup.setModal(true);
        // notePopup.setOverlayVisible(true);
        notePopup.setAutoCenter(true, true);
        notePopup.show();
    } else {
        // default is to auto-center, don't want that
        notePopup.setAutoCenter(false, false);
        notePopup.setLocation(dim.absoluteLeft, dim.absoluteBottom + 4);
        notePopup.show();

        var popupBounds = DOM.getAbsoluteDimensions(notePopup.getElement());
        if (popupBounds.absoluteRight > bounds.x) {
            notePopup.setLocation(bounds.x - popupBounds.offsetWidth - 30, dim.absoluteBottom + 4);
        }
    }

    notePopup.setClickToClose(true);
    notePopup.moveForward();

    if (! defined(timeout)) {
        timeout = 5000;
    }

    if (timeout) {
        window.setTimeout(function () {
            if (notePopup)
                notePopup.hide();
        }, timeout);
    }

    return notePopup;
};

LJ_IPPU.textPrompt = function (title, prompt, callback) {
    title += '';
    var notePopup = new LJ_IPPU(title);

    var inner = document.createElement("div");
    DOM.addClassName(inner, "ljippu_textprompt");

    // label
    if (prompt)
        inner.appendChild(_textDiv(prompt));

    // text field
    var field = document.createElement("textarea");
    DOM.addClassName(field, "htmlfield");
    field.cols = 40;
    field.rows = 5;
    inner.appendChild(field);

    // submit btn
    var btncont = document.createElement("div");
    DOM.addClassName(btncont, "submitbtncontainer");
    var btn = document.createElement("input");
    DOM.addClassName(btn, "submitbtn");
    btn.type = "button";
    btn.value = "Insert";
    btncont.appendChild(btn);
    inner.appendChild(btncont);

    notePopup.setContentElement(inner);

    notePopup.setAutoCenter(true, true);
    notePopup.setDimensions("60%", "auto");
    notePopup.show();
    field.focus();

    DOM.addEventListener(btn, "click", function (e) {
        notePopup.hide();
        if (callback)
            callback.apply(null, [field.value]);
    });
}
// LiveJournal javascript standard interface routines

// create a little animated hourglass at (x,y) with a unique-ish ID
// returns the element created
Hourglass = new Class( Object, {
  init: function(widget, classname) {
    this.ele = document.createElement("img");
    if (!this.ele) return;

    var imgprefix = Site ? Site.imgprefix : '';

    this.ele.src = imgprefix ? imgprefix + "/hourglass.gif" : "/img/hourglass.gif";
    this.ele.style.position = "absolute";

    DOM.addClassName(this.ele, classname);

    if (widget)
      this.hourglass_at_widget(widget);
  },

  hourglass_at: function (x, y) {
    this.ele.width = 17;
    this.ele.height = 17;
    this.ele.style.top = (y - 8) + "px";
    this.ele.style.left = (x - 8) + "px";

    // unique ID
    this.ele.id = "lj_hourglass" + x + "." + y;

    document.body.appendChild(this.ele);
  },

  add_class_name: function (classname) {
      if (this.ele)
      DOM.addClassName(this.ele, classname);
  },

  hourglass_at_widget: function (widget) {
    var dim = DOM.getAbsoluteDimensions(widget);
    var x = dim.absoluteLeft;
    var y = dim.absoluteTop;
    var w = dim.absoluteRight - x;
    var h = dim.absoluteBottom - y;
    if (w && h) {
      x += w/2;
      y += h/2;
    }
    this.hourglass_at(x, y);
  },

  hide: function () {
    if (this.ele) {
      try {
        document.body.removeChild(this.ele);
      } catch (e) {}
    }
  }

} );
LJWidget = new Class(Object, {
    // replace the widget contents with an ajax call to render with params
    updateContent: function (params) {
        if (! params) params = {};
        this._show_frame = params["showFrame"];

        if ( params["method"] ) method = params["method"];
        params["_widget_update"] = 1;

        if (this.doAjaxRequest(params)) {
            // hilight the widget to show that its updating
            this.hilightFrame();
        }
    },

    // returns the widget element
    getWidget: function () {
        return $(this.widgetId);
    },

    // do a simple post to the widget
    doPost: function (params) {
        if (! params) params = {};
        this._show_frame = params["showFrame"];
        var postParams = {};

        var classPrefix = this.widgetClass;
        classPrefix = "Widget[" + classPrefix.replace(/::/g, "_") + "]_";

        for (var k in params) {
            var class_k = k;
            if (! k.match(/^Widget\[/) && k != 'lj_form_auth' && ! k.match(/^_widget/)) {
                class_k = classPrefix + k;
            }

            postParams[class_k] = params[k];
        }

        postParams["_widget_post"] = 1;

        this.doAjaxRequest(postParams);
    },

    doPostAndUpdateContent: function (params) {
        if (! params) params = {};

        params["_widget_update"] = 1;

        this.doPost(params);
    },

    // do an ajax post of the form passed in
    postForm: function (formElement) {
      if (! formElement) return false;

      var params = {};

      for (var i=0; i < formElement.elements.length; i++) {
        var element = formElement.elements[i];
        var name = element.name;
        var value = element.value;

        params[name] = value;
      }

      this.doPost(params);
    },

    ///////////////// PRIVATE METHODS ////////////////////

    init: function (id, widgetClass, authToken) {
        LJWidget.superClass.init.apply(this, arguments);
        this.widgetId = id;
        this.widgetClass = widgetClass;
        this.authToken = authToken;
    },

    hilightFrame: function () {
        if (this._show_frame != 1) return;
        if (this._frame) return;

        var widgetEle = this.getWidget();
        if (! widgetEle) return;

        var widgetParent = widgetEle.parentNode;
        if (! widgetParent) return;

        var enclosure = document.createElement("fieldset");
        enclosure.style.borderColor = "red";
        var title = document.createElement("legend");
        title.innerHTML = "Updating...";
        enclosure.appendChild(title);

        widgetParent.appendChild(enclosure);
        enclosure.appendChild(widgetEle);

        this._frame = enclosure;
    },

    removeHilightFrame: function () {
        if (this._show_frame != 1) return;

        var widgetEle = this.getWidget();
        if (! widgetEle) return;

        if (! this._frame) return;

        var par = this._frame.parentNode;
        if (! par) return;

        par.appendChild(widgetEle);
        par.removeChild(this._frame);

        this._frame = null;
    },

    method: "POST",
    endpoint: "widget",
    requestParams: {},

    doAjaxRequest: function (params) {
        if (! params) params = {};

        if (this._ajax_updating) return false;
        this._ajax_updating = true;

        params["_widget_id"]     = this.widgetId;
        params["_widget_class"]  = this.widgetClass;

        params["auth_token"]  = this.authToken;


        if ($('_widget_authas')) {
            params["authas"] = $('_widget_authas').value;
        }

        var reqOpts = {
            method:  this.method,
            data:    HTTPReq.formEncoded(params),
            url:     LiveJournal.getAjaxUrl(this.endpoint),
            onData:  this.ajaxDone.bind(this),
            onError: this.ajaxError.bind(this)
        };

        for (var k in params) {
            reqOpts[k] = params[k];
        }

        HTTPReq.getJSON(reqOpts);

        return true;
    },

    ajaxDone: function (data) {
        this._ajax_updating = false;
        this.removeHilightFrame();
 	
	if(data["_widget_body"]){	
		if(data["_widget_body"].match(/ajax:.[^"]+/)){
			this.authToken=data["_widget_body"].match(/ajax:.[^"]+/)[0];
		}
	}

        if (data.auth_token) {
            this.authToken = data.auth_token;
        }

        if (data.errors && data.errors != '') {
            return this.ajaxError(data.errors);
        }

        if (data.error) {
            return this.ajaxError(data.error);
        }

        // call callback if one exists
        if (this.onData) {
             this.onData(data);
        }

        if (data["_widget_body"]) {
            // did an update request, got the new body back
            var widgetEle = this.getWidget();
            if (! widgetEle) {
              // widget is gone, ignore
              return;
            }

            widgetEle.innerHTML = data["_widget_body"];

            if (this.onRefresh) {
                this.onRefresh();
            }
        }
	
    },

    ajaxError: function (err) {
        this._ajax_updating = false;

        if (this.onError) {
            // use class error handler
            this.onError(err);
        } else {
            // use generic error handler
            LiveJournal.ajaxError(err);
        }
    }
});

LJWidget.widgets = [];

LJWidgetIPPU = new Class(LJWidget, {
    init: function (opts, reqParams) {
        var title = opts.title;
        var widgetClass = opts.widgetClass;
        var authToken = opts.authToken;
        var nearEle = opts.nearElement;
        var not_view_close = opts.not_view_close;

        if (! reqParams) reqParams = {};
        this.reqParams = reqParams;

        // construct a container ippu for this widget
        var ippu = new LJ_IPPU(title, nearEle);
        this.ippu = ippu;
        var c = document.createElement("div");
        c.id = "LJWidgetIPPU_" + Unique.id();
        ippu.setContentElement(c);

        if (opts.width && opts.height)
          ippu.setDimensions(opts.width, opts.height);

        if (opts.overlay) {
            if (IPPU.isIE()) {
                this.ippu.setModal(true);
                this.ippu.setOverlayVisible(true);
                this.ippu.setClickToClose(false);
            } else {
                this.ippu.setModal(true);
                this.ippu.setOverlayVisible(true);
            }
        }

        if (opts.center) ippu.center();
        ippu.show();
        if (not_view_close) ippu.titlebar.getElementsByTagName('img')[0].style.display = 'none';

        var loadingText = document.createElement("div");
        loadingText.style.fontSize = '1.5em';
        loadingText.style.fontWeight = 'bold';
        loadingText.style.margin = '5px';
        loadingText.style.textAlign = 'center';

        loadingText.innerHTML = "Loading...";

        this.loadingText = loadingText;

        c.appendChild(loadingText);

        // id, widgetClass, authToken
        var widgetArgs = [c.id, widgetClass, authToken]
        LJWidgetIPPU.superClass.init.apply(this, widgetArgs);

        if (!widgetClass)
            return null;

        this.widgetClass = widgetClass;
        this.authToken = authToken;
        this.title = title;
        this.nearEle = nearEle;

        window.setInterval(this.animateLoading.bind(this), 20);

        this.loaded = false;

        // start request for this widget now
        this.loadContent();
        return this;
    },

    animateCount: 0,

    animateLoading: function (i) {
      var ele = this.loadingText;

      if (this.loaded || ! ele) {
        window.clearInterval(i);
        return;
      }

      this.animateCount += 0.05;
      var intensity = ((Math.sin(this.animateCount) + 1) / 2) * 255;
      var hexColor = Math.round(intensity).toString(16);

      if (hexColor.length == 1) hexColor = "0" + hexColor;
      hexColor += hexColor + hexColor;

      ele.style.color = "#" + hexColor;
      this.ippu.center();
    },

    // override doAjaxRequest to add _widget_ippu = 1
    doAjaxRequest: function (params) {
      if (! params) params = {};
      params['_widget_ippu'] = 1;
      if(document.getElementById("LJ__Setting__InvisibilityGuests_invisibleguests_self")){
      	params['Widget[IPPU_SettingProd]_LJ__Setting__InvisibilityGuests_invisibleguests']=
	      (document.getElementById("LJ__Setting__InvisibilityGuests_invisibleguests_self").checked==true)?(1):((document.getElementById("LJ__Setting__InvisibilityGuests_invisibleguests_anon").checked==true)?(2):(0))
      }
      LJWidgetIPPU.superClass.doAjaxRequest.apply(this, [params]);
    },

    close: function () {
      this.ippu.hide();
    },

    loadContent: function () {
      var reqOpts = this.reqParams;
      this.updateContent(reqOpts);
    },

    method: "POST",

    // request finished
    onData: function (data) {
      this.loaded = true;
    },

    render: function (params) {

    }
});

LJWidgetIPPU_AddAlias = new Class(LJWidgetIPPU, {
  init: function (opts, params) {
    opts.widgetClass = "IPPU::AddAlias";
    this.width = opts.width; // Use for resizing later
    this.height = opts.height; // Use for resizing later
    this.alias = opts.alias;  
    LJWidgetIPPU_AddAlias.superClass.init.apply(this, arguments);
  },

  addvgifttocart: function (evt, form) {
    var alias = form["Widget[IPPU_AddAlias]_alias"].value + "";
    var foruser = form["Widget[IPPU_AddAlias]_foruser"].value + "";

    this.doPost({
        alias:          alias,
        foruser:            foruser
    });

    Event.stop(evt);
  },

  onData: function (data) {
	if (!data.res || !data.res.success) {
		return;
	}
	this.ippu.hide();
	var userLJ = data.res.journalname,
		userClassName = 'ljuser-name_' + data.res.journalname,
		searchProfile = DOM.getElementsByClassName(document, userClassName),
		i = -1, supSign;
	while (searchProfile[++i]) {
		var ljuser_node = searchProfile[i];
		if (DOM.hasClassName(ljuser_node, 'with-alias-value')) {
			var alias_value = ljuser_node.nextSibling;
			if (!alias_value || alias_value.tagName != 'SPAN' || alias_value.className != 'alias-value') {
				alias_value = null;
			}
			if (data.res.alias) {
				if (!alias_value) {
					alias_value = document.createElement('span');
					alias_value.className = 'alias-value';
					alias_value[/*@cc_on'innerText'||@*/'textContent'] = ' — ' + data.res.alias;
					ljuser_node.parentNode.insertBefore(alias_value, ljuser_node.nextSibling);
				}
				alias_value[/*@cc_on'innerText'||@*/'textContent'] = ' — ' + data.res.alias;
			} else if (alias_value) { // delete
				ljuser_node.parentNode.removeChild(alias_value);
			}
		} else if (!DOM.hasClassName(ljuser_node, 'with-alias')) {
			DOM.addClassName(searchProfile[i],'with-alias')
			supSign=document.createElement('span');
			DOM.addClassName(supSign,'useralias-value');
			supSign.innerHTML='*';
			searchProfile[i].getElementsByTagName('a')[1].appendChild(supSign);
		}else{
			if(!data.res.alias){
				DOM.removeClassName(searchProfile[i],'with-alias')
				supSign=DOM.getElementsByClassName(searchProfile[i],'useralias-value')[0];
				searchProfile[i].getElementsByTagName('a')[1].removeChild(supSign);
			}
		}
		searchProfile[i].getElementsByTagName('a')[1].setAttribute('title',data.res.alias);
	}
	//Changing button. Only on profile page
	var edit_node = DOM.getElementsByClassName(document, 'profile_addalias');
	if (edit_node.length) {
		if (data.res.alias) {
			edit_node[0].style.display = 'none';
			edit_node[1].style.display = 'block';
			edit_node[1].firstChild.alias = data.res.alias;
		} else {
			edit_node[0].style.display = 'block';
			edit_node[1].style.display = 'none';
		}
	}
	
	if(ContextualPopup.cachedResults[data.res.username]) {
		ContextualPopup.cachedResults[data.res.username].alias_title = data.res.alias ? 'Edit Note' : 'Add Note';
		ContextualPopup.cachedResults[data.res.username].alias = data.res.alias;
	}
  },

  onError: function (msg) {
    LJ_IPPU.showErrorNote("Error: " + msg);
  },

  onRefresh: function () {
	var form = $("addalias_form"),
		input = form['Widget[IPPU_AddAlias]_alias'],
		delete_btn = form['Widget[IPPU_AddAlias]_aliasdelete'],
		t = this;
	input.focus();
	
	if (delete_btn) {
		delete_btn.onclick=function(){
			input.value = '';
		}
		input.onkeyup =
		input.onpaste =
		input.oninput = function() {
			// save button disabled
			form['Widget[IPPU_AddAlias]_aliaschange'].disabled = !this.value;
		}
	}
	
	DOM.addEventListener(form, 'submit', function(e) { t.addvgifttocart(e, form) });
//    $('Widget[IPPU_AddAlias]_whom').value = this.whom;
//    AutoCompleteFriends($('Widget[IPPU_AddAlias]_whom'));
  },

  cancel: function (e) {
    this.close();
  }
});


Aliases = {}
function addAlias(target, ptitle, ljusername, oldalias, callback) {
    if (! ptitle) return true;
	
	new LJWidgetIPPU_AddAlias({
        title: ptitle,
        width: 440,
        height: 180,
		authToken: Aliases.authToken,
		callback: callback
        }, {
	    alias: target.alias||oldalias,
            foruser: ljusername
        });

    return false;
}


var ContextualPopup =
{
	popupDelay  : 500,
	hideDelay   : 250,
	
	cachedResults  : {},
	currentRequests: {},
	mouseInTimer   : null,
	mouseOutTimer  : null,
	currentId      : null,
	hourglass      : null,
	
	setup: function()
	{
		// don't do anything if no remote
		if (!Site.ctx_popup) return;
		
		jQuery(document.body)
			.mouseover(ContextualPopup.mouseOver)
			.ljAddContextualPopup();
	},
	
	searchAndAdd: function(node)
	{
		if (!Site.ctx_popup) return;
		
		// attach to all ljuser head icons
		var rex_userid = /\?userid=(\d+)/,
			rex_userpic = /(userpic\..+\/\d+\/\d+)|(\/userpic\/\d+\/\d+)/,
			ljusers = jQuery('span.ljuser>a>img', node),
			i = -1, userid, ljuser, parent;
		
		// use while for speed
		while (ljusers[++i])
		{
			var ljuser = ljusers[i], parent = ljuser.parentNode;
			if (parent.href && (userid = parent.href.match(rex_userid))) {
				ljuser.userid = userid[1];
			} else if (parent.parentNode.getAttribute('lj:user')) {
				ljuser.username = parent.parentNode.getAttribute('lj:user');
			} else {
				continue;
			}
			DOM.addClassName(ljuser, 'ContextualPopup');
		}
		
		ljusers = node.getElementsByTagName('img');
		i = -1;
		while (ljusers[++i])
		{
			ljuser = ljusers[i];
			if (ljuser.src.match(rex_userpic)) {
				ljuser.up_url = ljuser.src;
				DOM.addClassName(ljuser, 'ContextualPopup');
			}
		}
	},
	
	mouseOver: function(e)
	{
		var target = e.target,
			ctxPopupId = target.username || target.userid || target.up_url,
			t = ContextualPopup;
		
		clearTimeout(t.mouseInTimer);
		
		if (target.tagName == 'IMG' && ctxPopupId) {
			// if we don't have cached data background request it
			if (!t.cachedResults[ctxPopupId]) {
				t.getInfo(target, ctxPopupId);
			}
			
			// doesn't display alt as tooltip
			if (jQuery.browser.msie && target.title !== undefined) {
				target.title = '';
			}
			
			if (t.ippu) {
				clearTimeout(t.mouseOutTimer);
				t.mouseOutTimer = null;
				// show other popup
				if (t.current_target != target) {
					t.showPopup(ctxPopupId, target);
				}
			}
			// start timer if it's not running
			else {
				t.mouseInTimer = setTimeout(function()
				{
					t.showPopup(ctxPopupId, target);
				}, t.popupDelay);
			}
		} else if (t.ippu) {
			// we're inside a ctxPopElement, cancel the mouseout timer
			if (jQuery(target).closest('.ContextualPopup').length) {
				clearTimeout(t.mouseOutTimer);
				t.mouseOutTimer = null;
			}
			// did the mouse move out?
			else if (t.mouseOutTimer === null) {
				t.mouseOutTimer = setTimeout(function()
				{
					t.mouseOut();
				}, t.hideDelay);
			}
		}
	},
	
	mouseOut: function()
	{
		clearTimeout(ContextualPopup.mouseOutTimer);
		
		ContextualPopup.mouseOutTimer =
		ContextualPopup.currentId =
		ContextualPopup.current_target = null;
		
		ContextualPopup.hidePopup();
	},
	
	constructIPPU: function (ctxPopupId)
	{
		if (ContextualPopup.ippu) {
			ContextualPopup.ippu.hide();
			ContextualPopup.ippu = null;
		}
		ContextualPopup.ippu =
		{
			element: jQuery('<div class="ContextualPopup"></div>'),
			show: function()
			{
				document.body.appendChild(this.element[0]);
			},
			hide: function()
			{
				this.element.remove();
			}
		}
		
		ContextualPopup.renderPopup(ctxPopupId);
	},
	
	showPopup: function(ctxPopupId, ele)
	{
		ContextualPopup.current_target = ele;
		ContextualPopup.currentId = ctxPopupId;
		var data = ContextualPopup.cachedResults[ctxPopupId];
		
		if (data && data.noshow) return;
		
		ContextualPopup.constructIPPU(ctxPopupId);
		var ippu = ContextualPopup.ippu;
		
		// pop up the box right under the element
		ele = jQuery(ele);
		var ele_offset = ele.offset(),
			left = ele_offset.left,
			top = ele_offset.top + ele.height();
		
		// hide the ippu content element, put it on the page,
		// get its bounds and make sure it's not going beyond the client
		// viewport. if the element is beyond the right bounds scoot it to the left.
		var pop_ele = ippu.element;
		pop_ele.css('visibility', 'hidden');
		
		// put the content element on the page so its dimensions can be found
		ippu.show();
		
		ContextualPopup.calcPosition(pop_ele, left, top);
		
		// finally make the content visible
		pop_ele.css('visibility', 'visible');
	},
	
	//calc with viewport
	calcPosition: function(pop_ele, left, top)
	{
		var $window = jQuery(window);
		
		left = Math.min(left,  $window.width() + $window.scrollLeft() - pop_ele.outerWidth(true));
		top = Math.min(top, $window.height() + $window.scrollTop() - pop_ele.outerHeight(true));
		
		pop_ele.css({
			left: left,
			top: top
		});
	}
}

// if the popup was not closed by us catch it and handle it
ContextualPopup.popupClosed = function () {
    ContextualPopup.mouseOut();
}

ContextualPopup.renderPopup = function(ctxPopupId)
{
	var ippu = ContextualPopup.ippu;
	
	if (!ippu || !ctxPopupId) {
		return;
	}
	
	var data = ContextualPopup.cachedResults[ctxPopupId];
	
	if (!data) {
		ippu.element.append('<div class="Inner">Loading...</div>');
		return;
	} else if (!data.username || !data.success || data.noshow) {
		ippu.hide();
		return;
	}
	
	var inner = jQuery('<div class="Inner"/>');
	// if "Loading..." text
	var last_inner_height;
	if (ippu.element[0].firstChild) {
		last_inner_height = ippu.element[0].firstChild.offsetHeight;
		ippu.element.height(ippu.element.height());
		ippu.element.css('overflow', 'hidden');
	}
	
	var bar = document.createElement('span');
	bar.innerHTML = '&nbsp;| ';
	
	// userpic
	if (data.url_userpic && data.url_userpic != ctxPopupId) {
		jQuery(
			'<div class="Userpic">'+
				'<a href="'+data.url_allpics+'">'+
					'<img src="'+data.url_userpic+'" width="'+data.userpic_w+'" height="'+data.userpic_h+'"/>'+
				'</a>'+
			'</div>'
		)
		.appendTo(inner);
	}
	
	var content = document.createElement('div');
	content.className = 'Content';
	
	inner.append(content);
	
	// relation
	var label, username = data.display_username;
	if (data.is_comm) {
		if (data.is_member)
			label = data.ml_you_member.replace('[[username]]', username);
		else if (data.is_friend)
			labelL = data.ml_you_watching.replace('[[username]]', username);
		else
			label = username;
	} else if (data.is_syndicated) {
		if (data.is_friend)
				label = data.ml_you_subscribed.replace('[[username]]', username);
		else
			label = username;
	} else {
		if (data.is_requester) {
			label = data.ml_this_is_you;
		} else {
			label = username + ' ';
			
			if (data.is_friend_of) {
				if (data.is_friend)
					label += data.ml_mutual_friend;
				else
					label += data.ml_lists_as_friend;
			} else if (data.is_friend) {
				label += data.ml_your_friend;
			}
		}
	}
	jQuery('<div/>', {
		'class': 'Relation',
		text: label
	})
	.appendTo(content);
	
	// add site-specific content here
	var extraContent = LiveJournal.run_hook('ctxpopup_extrainfo', data);
	extraContent && content.appendChild(extraContent);
	
	// aliases
	if (!data.is_requester && data.is_logged_in) {
		if (data.alias_enable) {
			if (data.alias) {
				content.insertBefore(
					document.createTextNode(data.alias),
					content.firstChild.nextSibling
				);
			}
			
			jQuery('<a/>', {
				href: Site.siteroot + '/manage/notes.bml',
				text: data.alias_title,
				click: function(e)
				{
					e.preventDefault();
					addAlias(this, data.alias_title, data.username, data.alias || '');
				}
			})
			.appendTo(content);
		} else {
			jQuery(
				'<span class="alias-unavailable">'+
					'<a href="http://www.ljdev10.livejournal.ru/manage/account">'+
						'<img src="'+Site.statprefix+'/horizon/upgrade-paid-icon.gif" width="13" height="16" alt=""/>'+
					'</a> '+
					'<a href="'+Site.siteroot+'/support/faqbrowse.bml?faqid=295">'+data.alias_title+'</a>'+
				'</span>'
			)
			.appendTo(content)
		}
		
		content.appendChild(document.createElement('br'));
	}
	
	// member of community
	if (data.is_logged_in && data.is_comm) {
		jQuery('<a/>', {
			href: data.is_member ? data.ml_leave : data.url_joincomm,
			text: data.is_member ? data.ml_leave : data.ml_join_community,
			click: function(e)
			{
				e.preventDefault();
				ContextualPopup.changeRelation(data, ctxPopupId, data.is_member ? 'leave' : 'join', e);
			}
		})
		.appendTo(content);
		content.appendChild(document.createElement('br'));
	}
	
	// send message
	if (data.is_logged_in && data.is_person && ! data.is_requester && data.url_message) {
		jQuery('<a/>', {
			href: data.url_message,
			text: data.ml_send_message
		})
		.appendTo(content);
		content.appendChild(document.createElement('br'));
	}
	
	// add/remove friend link
	if (data.is_logged_in && !data.is_requester) {
		jQuery('<a/>', {
			href: data.url_addfriend,
			click: function(e)
			{
				e.preventDefault();
				ContextualPopup.changeRelation(data, ctxPopupId, data.is_friend ? 'removeFriend' : 'addFriend', e);
			},
			text: function()
			{
				if (data.is_comm)
					return data.is_friend ? data.ml_stop_community : data.ml_watch_community;
				else if (data.is_syndicated)
					return data.is_friend ? data.ml_unsubscribe_feed : data.ml_subscribe_feed;
				else
					return data.is_friend ? data.ml_remove_friend : data.ml_add_friend;
			}
		})
		.appendTo(content);
		content.appendChild(document.createElement('br'));
	}
	
	// vgift;
	if ((data.is_person || data.is_comm) && !data.is_requester && data.can_receive_vgifts) {
		jQuery('<a/>', {
			href: Site.siteroot + '/shop/vgift.bml?to=' + data.username,
			text: data.ml_send_gift
		})
		.appendTo(content);
		content.appendChild(document.createElement('br'));
	}
	
	if (data.is_logged_in && !data.is_requester && !data.is_comm && !data.is_syndicated) {
		// ban/unban
		jQuery('<a/>', {
			href: Site.siteroot + '/manage/banusers.bml',
			text: data.is_banned ? data.ml_unban : data.ml_ban,
			click: function(e)
			{
				e.preventDefault();
				ContextualPopup.changeRelation(data, ctxPopupId, data.is_banned ? 'setUnban' : 'setBan', e);
			}
		})
		.appendTo(content);
		
		// report a bot
		if (!Site.remote_is_suspended) {
			content.appendChild(bar.cloneNode(true));
			
			jQuery('<a/>', {
				href: Site.siteroot + '/abuse/bots.bml?user=' + data.username,
				text: data.ml_report
			})
			.appendTo(content);
		}
		
		content.appendChild(document.createElement('br'));
	}
	
	// ban user from all maintained communities
	if (!data.is_requester && !data.is_comm && !data.is_syndicated && data.have_communities) {
		jQuery('<a/>', {
			href: Site.siteroot + '/manage/banusers.bml',
			text: data.is_banned_everywhere ? data.unban_everywhere_title : data.ban_everywhere_title,
			click: function(e)
			{
				e.preventDefault();
				var action = data.is_banned_everywhere ? 'unbanEverywhere' : 'banEverywhere';
				ContextualPopup.changeRelation(data, ctxPopupId, action, e);
			}
		})
		.appendTo(content);
		content.appendChild(document.createElement('br'));
	}
	
	// view label
	content.appendChild(document.createTextNode(data.ml_view));
	
	// journal
	if (data.is_person || data.is_comm || data.is_syndicated) {
		jQuery('<a/>', {
			href: data.url_journal,
			text: function()
			{
				if (data.is_person)
					return data.ml_journal;
				else if (data.is_comm)
					return data.ml_community;
				else if (data.is_syndicated)
					return data.ml_feed;
			}
		})
		.appendTo(content)
		
		content.appendChild(bar.cloneNode(true));
	}
	
	// profile
	jQuery('<a/>', {
		href: data.url_profile,
		text: data.ml_profile
	})
	.appendTo(content);
	
	// clearing div
	jQuery('<div class="ljclear">&nbsp;</div>')
	.appendTo(content);
	
	ippu.element.html(inner);
	
	//calc position with viewport
	if (last_inner_height) {
		var $window = jQuery(window),
			top = parseInt(ippu.element[0].style.top),
			diff = ippu.element[0].firstChild.offsetHeight - last_inner_height,
			new_top = Math.min(top, $window.height() + $window.scrollTop() - ippu.element.outerHeight(true) - diff);
		top != new_top && ippu.element.css('top', new_top);
		ippu.element.css('overflow', 'visible');
	}
}

// ajax request to change relation
ContextualPopup.changeRelation = function (info, ctxPopupId, action, e) {
	var changedRelation = function(data)
	{
		if (data.error) {
			return ContextualPopup.showNote(data.error);
		}
		
		if (ContextualPopup.cachedResults[ctxPopupId]) {
			jQuery.extend(ContextualPopup.cachedResults[ctxPopupId], data);
		}
		
		// if the popup is up, reload it
		ContextualPopup.renderPopup(ctxPopupId);
	}
	
	var xhr = jQuery.post(LiveJournal.getAjaxUrl('changerelation'),
				{
					target: info.username,
					action: action,
					auth_token: info[action + '_authtoken']
				},
				function(data)
				{
					ContextualPopup.hourglass = null;
					changedRelation(data);
				},
				'json'
			);
	
	ContextualPopup.hideHourglass();
	ContextualPopup.hourglass = jQuery(e).hourglass(xhr)[0];
	// so mousing over hourglass doesn't make ctxpopup think mouse is outside
	ContextualPopup.hourglass.add_class_name('lj_hourglass ContextualPopup');
	
	return false;
}

// create a little popup to notify the user of something
ContextualPopup.showNote = function (note, ele) {
    if (ContextualPopup.ippu) {
        // pop up the box right under the element
        ele = ContextualPopup.ippu.element[0];
    }

    LJ_IPPU.showNote(note, ele);
}

ContextualPopup.hidePopup = function (ctxPopupId) {
	ContextualPopup.hideHourglass();
	
    // destroy popup for now
    if (ContextualPopup.ippu) {
        ContextualPopup.ippu.hide();
        ContextualPopup.ippu = null;
    }
}

// do ajax request of user info
ContextualPopup.getInfo = function(target, popup_id)
{
	var t = this;
	if (t.currentRequests[popup_id]) {
		return;
	}
	t.currentRequests[popup_id] = 1;
	
	jQuery.ajax({
		url: LiveJournal.getAjaxUrl('ctxpopup'),
		data: {
			user: target.username || '',
			userid: target.userid || 0,
			userpic_url: target.up_url || '',
			mode: 'getinfo'
		},
		dataType: 'json',
		success: function(data)
		{
			t.cachedResults[String(data.userid)] =
			t.cachedResults[data.username] =
			t.cachedResults[data.url_userpic] = data;
			
			// non default userpic
			if (target.up_url) {
				t.cachedResults[target.up_url] = data;
			}
			
			if (data.error) {
				!data.noshow && t.showNote(data.error, target);
				return;
			}
			
			t.currentRequests[popup_id] = null;
			
			if (t.currentId == popup_id) {
				t.renderPopup(popup_id);
			}
		},
		error: function()
		{
			t.currentRequests[popup_id] = null;
		}
	});
}

ContextualPopup.hideHourglass = function () {
    if (ContextualPopup.hourglass) {
        ContextualPopup.hourglass.hide();
        ContextualPopup.hourglass = null;
    }
}

// when page loads, set up contextual popups
jQuery(ContextualPopup.setup);
Expander = function(){
    this.__caller__;    // <a> HTML element from where Expander was called
    this.url;           // full url of thread to be expanded
    this.id;            // id of the thread
    this.stored_caller;
    this.iframe;        // iframe, where the thread will be loaded
    this.is_S1;         // bool flag, true == journal is in S1, false == in S2
}
Expander.Collection={};
Expander.make = function(el,url,id,is_S1){
    var local = (new Expander).set({__caller__:el,url:url.replace(/#.*$/,''),id:id,is_S1:!!is_S1});
    local.get();
}

Expander.prototype.set = function(options){
    for(var opt in options){
        this[opt] = options[opt];
    }
    return this;
}

Expander.prototype.getCanvas = function(id,context){
    return context.document.getElementById('ljcmt'+id);
}

Expander.prototype.parseLJ_cmtinfo = function(context,callback){
    var map={}, node, j;
    var LJ = context.LJ_cmtinfo;
    if(!LJ)return false;
    for(j in LJ){
        if(/^\d*$/.test(j) && (node = this.getCanvas(j,context))){
            map[j] = {info:LJ[j],canvas:node};
            if(typeof callback == 'function'){
                callback(j,map[j]);
            }
        }
    }
    return map;
}

Expander.prototype.loadingStateOn = function(){
    this.stored_caller = this.__caller__.cloneNode(true);
    this.__caller__.setAttribute('already_clicked','already_clicked');
    this.__caller__.onclick = function(){return false}
    this.__caller__.style.color = '#ccc';
}

Expander.prototype.loadingStateOff = function(){
    if(this.__caller__){
        // actually, the <a> element is removed from main window by
        // copying comment from ifame, so this code is not executed (?)
        this.__caller__.removeAttribute('already_clicked','already_clicked');
        if(this.__caller__.parentNode) this.__caller__.parentNode.replaceChild(this.stored_caller,this.__caller__);
    }
    var obj = this;
    // When frame is removed immediately, IE raises an error sometimes
    window.setTimeout(function(){obj.killFrame()},100);
}

Expander.prototype.killFrame = function(){
    document.body.removeChild(this.iframe);
}

Expander.prototype.isFullComment = function(comment){
    return !!Number(comment.info.full);
}

Expander.prototype.killDuplicate = function(comments){
    var comment;
    var id,id_,el,el_;
    for(var j in comments){
        if(!/^\d*$/.test(j))continue;
        el_ = comments[j].canvas;
        id_ = el_.id;
        id = id_.replace(/_$/,'');
        el = document.getElementById(id);
        if(el!=null){
            //in case we have a duplicate;
            el_.parentNode.removeChild(el_);
        }else{
            el_.id = id;
            window.ContextualPopup && ContextualPopup.searchAndAdd(el_);
            window.setupAjax && setupAjax(el_);
            window.ESN && ESN.initTrackBtns(el_);
        }
    }
}

Expander.prototype.getS1width = function(canvas){
  //TODO:  may be we should should add somie ID to the spacer img instead of searching it
  //yet, this works until we have not changed the spacers url = 'dot.gif');
  var img, imgs;
  imgs = canvas.getElementsByTagName('img');
  for(var j=0;j<imgs.length;j++){
    img=imgs[j];
    if(/dot\.gif$/.test(img.src)){
        if (img.width) { return Number(img.width); }
        break;
    }
  }
  return false;
}

Expander.prototype.setS1width = function(canvas,w){
  var img, imgs;
  imgs = canvas.getElementsByTagName('img');
  for(var j=0;j<imgs.length;j++){
    img=imgs[j];
    if(/dot\.gif$/.test(img.src)){
        img.setAttribute('width',w);
        break;
    }
  }
}

Expander.prototype.onLoadHandler = function(iframe){
        var doc = iframe.contentDocument || iframe.contentWindow;
        doc = doc.document||doc;
        var obj = this;
        var win = doc.defaultView||doc.parentWindow;
        var comments_intersection={};
        var comments_page = this.parseLJ_cmtinfo(window);
        var comments_iframe = this.parseLJ_cmtinfo(win,function(id,new_comment){
                                    if(id in comments_page){
                                        comments_page[id].canvas.id = comments_page[id].canvas.id+'_';
                                        comments_intersection[id] = comments_page[id];
                                        // copy comment from iframe to main window if
                                        // 1) the comment is collapsed in main window and is full in iframe
                                        // 2) or this is the root comment of this thread (it may be full in
                                        //     main window too, it's copied so that to remove "expand" link from it)
                                        if((!obj.isFullComment(comments_page[id]) && obj.isFullComment(new_comment)) || (id===obj.id)){
                                            var w;
                                            if(obj.is_S1){
                                                w =obj.getS1width(comments_page[id].canvas);
                                            }
                                            comments_page[id].canvas.innerHTML = new_comment.canvas.innerHTML;
                                            if(obj.is_S1 && w!==false){
                                                    obj.setS1width(comments_page[id].canvas,w);
                                            }
                                            //TODO: may be this should be uncommented
                                            //comments_page[id].canvas.className = new_comment.canvas.className;
                                            LJ_cmtinfo[id].full=1;
                                            LJ_cmtinfo[id].expanded=1;
                                        }
                                    }//if(id in comments_page){
                                });
       this.killDuplicate(comments_intersection);
       this.loadingStateOff();
       return true;
}


//just for debugging
Expander.prototype.toString = function(){
    return '__'+this.id+'__';
}


Expander.prototype.get = function(){
    if(this.__caller__.getAttribute('already_clicked')){
        return false;
    }
    this.loadingStateOn();

    var iframe;
    if(/*@cc_on !@*/0){
        // branch for IE
        Expander.Collection[this.id] = this;
        iframe = document.createElement('<iframe onload="Expander.Collection['+this.id+'].onLoadHandler(this)">');
    }else{
        // branch for all other browsers
        iframe = document.createElement('iframe');
        iframe.onload = function(obj){return function(){
                            obj.onLoadHandler(iframe);
                        }}(this);
    }
    iframe.style.height='1px';
    iframe.style.width='1px';
    iframe.style.display = 'none';
    iframe.src = this.url;
    iframe.id = this.id;
    document.body.appendChild(iframe);
    this.iframe=iframe;
    return true;
}
/*
JavaSript Object Notation (JSON)
$Id$

Copyright (c) 2005-2006, Six Apart, Ltd.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.

    * Neither the name of "Six Apart" nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

/* TODO delete. Bug in detection of native window.JSON().
JSON = {
    parse: function( string ) {
        string = string.replace( /=/g, "\\u3D" );
        string = string.replace( /\(/g, "\\u28" );
        try {
            return eval( "(" + string + ")" );
        } catch( e ) {}
        return undefined;
    }
}
*/

Boolean.prototype.toJSON = function() {
    return this.toString();
}


Number.prototype.toJSON = function() {
    return isFinite( this ) ? this.toString() : "0";
}


Date.prototype.toJSON = function() {
    return this.toUTCISOString
        ? this.toUTCISOString().toJSON()
        : this.toString().toJSON();
}


String.prototype.toJSON = function() {
    return '"' + this.escapeJS() + '"';
}


RegExp.prototype.toJSON = function() {
    return this.toString().toJSON();
}


Function.prototype.toJSON = function() {
    return this.toString().toJSON();
}


Array.prototype.toJSON = function( root ) {
    // crude recursion detection
    if( !root )
        root = this;
    else if( root == this )
        return "[]";
    
    var out = [ "[" ];
    for( var i = 0; i < this.length; i++ ) {
        if( out.length > 1 )
            out.push( "," );
        if( typeof this[ i ] == "undefined" || this[ i ] == null )
            out.push( "null" );
        else if( !this[ i ].toJSON )
            out.push( "{}" );
        else
            out.push( this[ i ].toJSON( root ) );
    }
    out.push( "]" );
    return out.join( "" );
}


Object.toJSON = function( root ) {
    // crude recursion detection
    if( !root )
        root = this;
    else if( root == this )
        return "{}";
    
    var out = [ "{" ];
    for( var i in this ) {
        if( typeof this[ i ] == "undefined" )
            continue;
        if( out.length > 1 )
            out.push( "," );
        out.push( i.toJSON() );
        if( this[ i ] == null )
            out.push( ":null" );
        else if( typeof this[ i ] == "function" )
            continue;
        else if( !this[ i ].toJSON )
            out.push( ":{}" );
        else
            out.push( ":", this[ i ].toJSON( root ) );
    }
    out.push( "}" );
    return out.join( "" );
}
/*
Template - Copyright 2005 Six Apart
$Id: template.js 35 2006-02-18 00:46:55Z mischa $

Copyright (c) 2005, Six Apart, Ltd.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.

    * Neither the name of "Six Apart" nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/


/* core template object */

Template = new Class( Object, {
    beginToken: "[#",
    endToken: "#]",
    
    
    init: function( source ) {
        if( source )
            this.compile( source );
    },
    
    
    compile: function( source ) {
        var statements = [
            "context.open();",
            "with( context.vars ) {"
        ];
        
        var start = 0, end = -this.endToken.length;
        while( start < source.length ) {
            end += this.endToken.length;
            
            // plaintext
            start = source.indexOf( this.beginToken, end );
            if( start < 0 )
                start = source.length;
            if( start > end )
                statements.push( "context.write( ", source.substring( end, start ).toJSON(), " );" );
            start += this.beginToken.length;
            
            // code
            if( start >= source.length )
                break;
            end = source.indexOf( this.endToken, start );
            if( end < 0 )
                throw "Template parsing error: Unable to find matching end token (" + this.endToken + ").";
            var length = (end - start);
            
            // empty tag
            if( length <= 0 )
                continue;
            
            // comment
            else if( length >= 4 &&
                source.charAt( start ) == "-" && source.charAt( start + 1 ) == "-" &&
                source.charAt( end - 1 ) == "-" && source.charAt( end - 2 ) == "-" )
                continue;
            
            // write
            else if( source.charAt( start ) == "=" )
                statements.push( "context.write( ", source.substring( start + 1, end ), " );" );
            
            // filters
            else if( source.charAt( start ) == "|" ) {
                start += 1;

                // find the first whitespace
                var afterfilters = source.substring(start,end).search(/\s/);
                
                var filters;
                if (afterfilters > 0) {
                    // allow pipes or commas to seperate filters
                    // split the string, reverse and rejoin to reverse it
                    filters = source.substring(start,start + afterfilters).replace(/,|\|/g,"").split('');
                    afterfilters += 1; // data starts after whitespace and filter list
                } else {
                    // default to escapeHTML
                    filters = ["h"];
                }
                // we have to do them in reverse order
                filters = filters.reverse();
               
                // start with our original filter number
                var numfilters = filters.length;
                
                // add the text between [#|  #]
                filters.push(source.substring( start + afterfilters, end ));
                
                // adjust each filter into a function call
                // eg. u ( h ( H ( blah ) ) )
                for (i=0; i<numfilters; i++) {
                    filters[i] = "context.f."+filters[i]+"( ";
                    filters.push(" )");
                }
                
                statements.push( "context.write( " + filters.join('') + " );");
            }
            
            // evaluate
            else
                statements.push( source.substring( start, end ) );
        }
        
        statements.push( "} return context.close();" );

        this.exec = new Function( "context", statements.join( "\n" ) );
    },
    
    
    exec: function( context ) {
        return "";
    }
} );


/* static members */

Template.templates = {};


/* context object */

Template.Context = new Class( Object, {
    init: function( vars, templates ) {
        this.vars = vars || {};
        this.templates = templates || Template.templates;
        this.stack = [];
        this.out = [];
        this.f = Template.Filter;
    },
    
    
    include: function( name ) {
        return this.templates[ name ].exec( this );
    },


    write: function() {
        this.out.push.apply( this.out, arguments );
    },


    writeln: function() {
        this.write.apply( this, arguments );
        this.write( "\n" );
    },

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


    getOutput: function() {
        return this.out.join( "" );
    },
    
    
    open: function() {
        this.stack.push( this.out );
        this.out = [];
    },
    
    
    close: function() {
        var result = this.getOutput();
        this.out = this.stack.pop() || [];
        return result;
    }
   
} );

/* filters */

Template.Filter = {

    // escapeHTML
    h: function(obj) {
        var div = document.createElement('div');
        var textNode = document.createTextNode(obj);
        div.appendChild(textNode);
        return (div.innerHTML);
    },

    // unescapeHTML
    H: function(obj) {
        return (unescape(obj));
    },

    // encodeURL
    u: function(obj) {
        return (escape(obj).replace(/\//g,"%2F"));
    }

};

UserpicSelect = new Class (LJ_IPPU, {
  init: function () {
    UserpicSelect.superClass.init.apply(this, ["Choose Userpic"]);

    this.setDimensions("550px", "441px");

    this.selectedPicid = null;
    this.displayPics = null;
    this.dataLoaded = false;
    this.imgScale = 1;

    this.picSelectedCallback = null;

    var template = new Template( UserpicSelect.top );
    var templates = { body: template };
    this.setContent(template.exec( new Template.Context( {}, templates ) ));
    this.setHiddenCallback(this.hidden.bind(this));
  },

  show: function() {
    UserpicSelect.superClass.show.apply(this, []);

    if (!this.dataLoaded) {
      this.setStatus("Loading...");
      this.loadPics();
      this.dataLoaded = true;
    } else {
      this.redraw();
    }
  },

  // hide the hourglass when window is closed
  hidden: function () {
    if (this.hourglass)
      this.hourglass.hide();
  },

  // set a callback to be called when the "select" button is clicked
  setPicSelectedCallback: function (callback) {
    this.picSelectedCallback = callback;
  },

  // called when the "select" button is clicked
  closeButtonClicked: function (evt) {
      if (this.picSelectedCallback) {
          var selectedKws = [];
          if (this.selectedPicid) {
              var kws = this.pics.pics[this.selectedPicid+""].keywords;
              if (kws && kws.length) selectedKws = kws;
          }

          this.picSelectedCallback(this.selectedPicid, selectedKws);
      }

    this.hide();
  },

  setStatus: function(status) {
      this.setField({'status': status});
  },

  setField: function(vars) {
    var template = new Template( UserpicSelect.dynamic );
    var userpics_template = new Template( UserpicSelect.userpics );

    var templates = {
      body: template,
      userpics: userpics_template
    };

    if (!vars.pics)
      vars.pics = this.pics || {};

    if (!vars.status)
      vars.status = "";

    vars.imgScale = this.imgScale;

    $("ups_dynamic").innerHTML = (template.exec( new Template.Context( vars, templates ) ));

    if (!vars.pics.ids)
      return;

    // we redrew the window so reselect the current selection, if any
    if (this.selectedPicid)
      this.selectPic(this.selectedPicid);

    var ST = new SelectableTable();
    ST.init({
        "table": $("ups_userpics_t"),
            "selectedClass": "ups_selected_cell",
            "selectableClass": "ups_cell",
            "multiple": false,
            "selectableItem": "cell"
            });

    var self = this;

    ST.addWatcher(function (data) {
        var selectedCell = data[0];

        if (!selectedCell) {
            // clear selection
            self.selectPic(null);
        } else {
            // find picid and select it
            var parentCell = DOM.getFirstAncestorByClassName(selectedCell, "ups_cell", true);
            if (!parentCell) return;

            var picid = parentCell.getAttribute("lj_ups:picid");
            if (!picid) return;

            self.selectPic(picid);
        }
    });

    DOM.addEventListener($("ups_closebutton"), "click", this.closeButtonClicked.bindEventListener(this));

    // set up image scaling buttons
    var scalingSizes = [3,2,1];
    var baseSize = 25;
    var scalingBtns = $("ups_scaling_buttons");
    this.scalingBtns = [];

    if (scalingBtns) {
        scalingSizes.forEach(function (scaleSize) {
            var scaleBtn = document.createElement("img");

            scaleBtn.style.width = scaleBtn.width = scaleBtn.style.height = scaleBtn.height = baseSize - scaleSize * 5;

            scaleBtn.src = Site.imgprefix + "/imgscale.png";
            DOM.addClassName(scaleBtn, "ups_scalebtn");

            self.scalingBtns.push(scaleBtn);

            DOM.addEventListener(scaleBtn, "click", function (evt) {
                Event.stop(evt);

                self.imgScale = scaleSize;
                self.scalingBtns.forEach(function (otherBtn) {
                    DOM.removeClassName(otherBtn, "ups_scalebtn_selected");
                });

                DOM.addClassName(scaleBtn, "ups_scalebtn_selected");

                self.redraw();
            });

            scalingBtns.appendChild(scaleBtn);

            if (self.imgScale == scaleSize)
                DOM.addClassName(scaleBtn, "ups_scalebtn_selected");
        });
    }
  },

  kwmenuChange: function(evt) {
    this.selectPic($("ups_kwmenu").value);
  },

  selectPic: function(picid) {
    if (this.selectedPicid) {
        DOM.removeClassName($("ups_upicimg" + this.selectedPicid), "ups_selected");
        DOM.removeClassName($("ups_cell" + this.selectedPicid), "ups_selected_cell");
    }

    this.selectedPicid = picid;

    if (picid) {
        // find the current pic and cell
        var picimg =  $("ups_upicimg" + picid);
        var cell   =  $("ups_cell" + picid);

        if (!picimg || !cell)
            return;

        // hilight the userpic
        DOM.addClassName(picimg, "ups_selected");

        // hilight the cell
        DOM.addClassName(cell, "ups_selected_cell");

        // enable the select button
        $("ups_closebutton").disabled = false;

        // select the current selectedPicid in the dropdown
        this.setDropdown();
    } else {
        $("ups_closebutton").disabled = true;
    }
  },

  // filter by keyword/comment
  filterPics: function(evt) {
    var searchbox = $("ups_search");

    if (!searchbox)
      return;

    var filter = searchbox.value.toLocaleUpperCase();
    var pics = this.pics;

    if (!filter) {
      this.setPics(pics);
      return;
    }

    // if there is a filter and there is selected text in the field assume that it's
    // inputcomplete text and ignore the rest of the selection.
    if (searchbox.selectionStart && searchbox.selectionStart > 0)
      filter = searchbox.value.substr(0, searchbox.selectionStart).toLocaleUpperCase();

    var newpics = {
      "pics": [],
      "ids": []
    };

    for (var i=0; i<pics.ids.length; i++) {
      var picid = pics.ids[i];
      var pic = pics.pics[picid];

      if (!pic)
        continue;

      for (var j=0; j < pic.keywords.length; j++) {
        var kw = pic.keywords[j];

        var piccomment = "";
        if (pic.comment)
          piccomment = pic.comment.toLocaleUpperCase();

        if(kw.toLocaleUpperCase().indexOf(filter) != -1 || // matches a keyword
           (piccomment && piccomment.indexOf(filter) != -1) || // matches comment
           (pic.keywords.join(", ").toLocaleUpperCase().indexOf(filter) != -1)) { // matches comma-seperated list of keywords

          newpics.pics[picid] = pic;
          newpics.ids.push(picid);
          break;
        }
      }
    }

    if (this.pics != newpics)
      this.setPics(newpics);

    // if we've filtered down to one pic and we don't currently have a selected pic, select it
    if (newpics.ids.length == 1 && !this.selectedPicid)
      this.selectPic(newpics.ids[0]);
  },

  setDropdown: function(pics) {
    var menu = $("ups_kwmenu");

    for (var i=0; i < menu.length; i++)
      menu.remove(i);

    menu.length = 0;

    if (!pics)
      pics = this.pics;

    if (!pics || !pics.ids)
      return;

    for (var i=0; i < pics.ids.length; i++) {
      var picid = pics.ids[i];
      var pic = pics.pics[picid];

      if (!pic)
        continue;

      var sel = false;
      var self = this;

      pic.keywords.forEach(function (kw) {
          // add to dropdown
          var picopt = document.createElement("option");
          picopt.text = kw;
          picopt.value = picid;

          if (! sel) {
              picopt.selected = self.selectedPicid ? self.selectedPicid == picid : false;
              sel = picopt.selected;
          }

          Try.these(
                    function () { menu.add(picopt, 0); },    // everything else
                    function () { menu.add(picopt, null); }  // IE
                    );
      });
    }
  },

  picsReceived: function(picinfo) {
    if (picinfo && picinfo.alert) { // got an error
      this.handleError(picinfo.alert);
      return;
    }

    if (!picinfo || !picinfo.ids || !picinfo.pics || !picinfo.ids.length)
      return;

    var piccount = picinfo.ids.length;

    // force convert integers to strings
    for (var i=0; i < piccount; i++) {
      var picid = picinfo.ids[i];

      var pic = picinfo.pics[picid];

      if (!pic)
        continue;

      if (pic.comment)
        pic.comment += "";

      for (var j=0; j < pic.keywords.length; j++)
        pic.keywords[j] += "";
    }

    // set default scaling size based on how many pics there are
    if (piccount < 30) {
        this.imgScale = 1;
    } else if (piccount < 60) {
        this.imgScale = 2;
    } else {
        this.imgScale = 3;
    }

    this.pics = picinfo;

    this.setPics(picinfo);
    this.redraw();

    if (this.hourglass)
      this.hourglass.hide();
  },

  redraw: function () {
    this.setStatus();

    if (!this.pics)
      return;

    this.setPics(this.pics);

    if (this.hourglass)
      this.hourglass.hide();

    var keywords = [], comments = [];
    for (var i=0; i < this.pics.ids.length; i++) {
      var picid = this.pics.ids[i];
      var pic = this.pics.pics[picid];

      for (var j=0; j < pic.keywords.length; j++)
        keywords.push(pic.keywords[j]);

      comments.push(pic.comment);
    }

    var searchbox = $("ups_search");
    var compdata = new InputCompleteData(keywords.concat(comments));
    var whut = new InputComplete(searchbox, compdata);

    DOM.addEventListener(searchbox, "keydown",  this.filterPics.bind(this));
    DOM.addEventListener(searchbox, "keyup",    this.filterPics.bind(this));
    DOM.addEventListener(searchbox, "focus",    this.filterPics.bind(this));

    try {
      searchbox.focus();
    } catch(e) {}

    DOM.addEventListener($("ups_kwmenu"), "change", this.kwmenuChange.bindEventListener(this));
  },

  setPics: function(pics) {
    if (this.displayPics == pics)
      return;

    this.displayPics = pics;

    this.setField({'pics': pics});
    this.setDropdown(pics);
  },

  handleError: function(err) {
    log("Error: " + err);
    this.hourglass.hide();
  },

  loadPics: function() {
    this.hourglass = new Hourglass($("ups_userpics"));
    var reqOpts = {};
    reqOpts.url = Site.currentJournal ? "/" + Site.currentJournal + "/__rpc_userpicselect" : "/__rpc_userpicselect";
    reqOpts.onData = this.picsReceived.bind(this);
    reqOpts.onError = this.handleError.bind(this);
    HTTPReq.getJSON(reqOpts);
  }
});

// Templates
UserpicSelect.top = "\
      <div class='ups_search'>\
       <span class='ups_searchbox'>\
         Search: <input type='text' id='ups_search'>\
         Select: <select id='ups_kwmenu'><option value=''></option></select>\
         </span>\
      </div>\
      <div id='ups_dynamic'></div>";

UserpicSelect.dynamic = "\
       [# if (status) { #] <div class='ups_status'>[#| status #]</div> [# } #]\
         <div class='ups_userpics' id='ups_userpics'>\
           [#= context.include( 'userpics' ) #]\
           &nbsp;\
         </div>\
      <div class='ups_closebuttonarea'>\
       <input type='button' id='ups_closebutton' value='Select' disabled='true'  />\
       <span id='ups_scaling_buttons'>\
       </span>\
      </div>";

UserpicSelect.userpics = "\
[# if(pics && pics.ids) { #] \
     <table class='ups_table' cellpadding='0' cellspacing='0' id='ups_userpics_t'> [# \
       var rownum = 0; \
       for (var i=0; i<pics.ids.length; i++) { \
          var picid = pics.ids[i]; \
          var pic = pics.pics[picid]; \
\
          if (!pic) \
            continue; \
\
          var pickws = pic.keywords; \
          if (i%2 == 0) { #] \
            <tr class='ups_row ups_row[#= rownum++ % 2 + 1 #]'> [# } #] \
\
            <td class='ups_cell'  \
                           lj_ups:picid='[#= picid #]' id='ups_cell[#= picid #]'> \
              <div class='ups_container'> \
              <img src='[#= pic.url #]' width='[#= finiteInt(pic.width/imgScale) #]' \
                 height='[#= finiteInt(pic.height/imgScale) #]' id='ups_upicimg[#= picid #]' class='ups_upic' /> \
               </div> \
\
              <b>[#| pickws.join(', ') #]</b> \
             [# if(pic.comment) { #]<br/>[#= pic.comment #][# } #] \
              <div class='ljclear'>&nbsp;</div>\
            </td> \
\
            [# if (i%2 == 1 || i == pics.ids.length - 1) { #] </tr> [# } \
        } #] \
     </table> \
  [# } #] \
";

// Copied here from entry.js
function insertViewThumbs() {
    var lj_userpicselect = $('lj_userpicselect');
    lj_userpicselect.innerHTML = 'View Thumbnails';
}

/* input completion library */

/* TODO:
    -- test on non-US keyboard layouts (too much use of KeyCode)
    -- lazy data model (xmlhttprequest, or generic callbacks)
    -- drop-down menu?
    -- option to disable comma-separated mode (or explicitly ask for it)
*/

/*
  Copyright (c) 2005, Six Apart, Ltd.
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:

  * Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.

  * Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the following disclaimer
  in the documentation and/or other materials provided with the
  distribution.

  * Neither the name of "Six Apart" nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/


/* ***************************************************************************

  Class: InputCompleteData

  About: An InputComplete object needs a data source to auto-complete
          from.  This is that model.  You can create one from an
          array, or create a lazy version that gets its data over the
          network, on demand.  You will probably not use this class'
          methods directly, as they're called by the InputComplete
          object.

          The closer a word is to the beginning of the array, the more
          likely it will be recommended as the word the user is typing.

          If you pass the string "ignorecase" as the second argument in
          the constructor, then the case of both the user's input and
          the data in the array will be ignored when looking for a match.

  Constructor:

    var model = new InputCompleteData ([ "foo", "bar", "alpha" ]);

*************************************************************************** */

var InputCompleteData = new Class ( Object, {
    init: function () {
        if (arguments[0] instanceof Array) {
            this.source = [];

            // copy the user-provided array (which is sorted most
            // likely to least likely) into our internal form, which
            // is opposite, with most likely at the end.
            var arg = arguments[0];
            for (var i=arg.length-1; i>=0; i--) {
                this.source.length++;
                this.source[this.source.length-1] = arg[i];
            }
        }

        this.ignoreCase = 0;
        if (arguments[1] == "ignorecase") {
            this.ignoreCase = 1;
        }
    },

    // method: given prefix, returns best suffix, or null if no answer
    bestFinish: function (pre) {
        if (! pre || pre.length == 0)
            return null;

        if (! this.source)
            return null;

        var i;
        for (i=this.source.length-1; i>=0; i--) {
            var item = this.source[i];

            var itemToCompare = item;
            var preToCompare = pre;
            if (this.ignoreCase) {
                item += '';
                pre += '';
                itemToCompare = item.toLowerCase();
                preToCompare = pre.toLowerCase();
            }

            if (itemToCompare.substring(0, pre.length) == preToCompare) {
                var suff = item.substring(pre.length, item.length);
                return suff;
            }
        }

        return null;
    },

    // method: given a piece of data, learn it, and prioritize it for future completions
    learn: function (word) {
        if (!word) return false;
        if (!this.source) return false;
        this.source[this.source.length++] = word;

        if (this.onModelChange)
            this.onModelChange();
    },

    getItems: function () {
        if (!this.source) return [];

        // return only unique items to caller
        var uniq = [];
        var seen = {};
        for (i=this.source.length-1; i>=0; i--) {
            var item = this.source[i];
            if (! seen[item]) {
                seen[item] = 1;
                uniq.length++;
                uniq[uniq.length - 1] = item;
            }
        }

        return uniq;
    },

    dummy: 1
});

/* ***************************************************************************

  Class: InputComplete

  About:

  Constructor:

*************************************************************************** */

var InputComplete = new Class( Object, {
    init: function () {
        var opts = arguments[0];
        var ele;
        var model;
        var debug;

        if (arguments.length == 1) {
            ele = opts["target"];
            model = opts["model"];
            debug = opts["debug"];
        } else {
            ele = arguments[0];
            model = arguments[1];
            debug = arguments[2];
        }

        this.ele   = ele;
        this.model = model;
        this.debug = debug;

        // no model?  don't setup object.
        if (! ele) {
            this.disabled = true;
            return;
        }

        // return false if auto-complete won't work anyway
        if (! (("selectionStart" in ele) || (document.selection && document.selection.createRange)) ) {
            this.disabled = true;
            return false;
        }

        DOM.addEventListener(ele, "focus",   InputComplete.onFocus.bindEventListener(this));
        DOM.addEventListener(ele, "keydown", InputComplete.onKeyDown.bindEventListener(this));
        DOM.addEventListener(ele, "keyup",   InputComplete.onKeyUp.bindEventListener(this));
        DOM.addEventListener(ele, "blur",    InputComplete.onBlur.bindEventListener(this));
    },

    dbg: function (msg) {
        if (this.debug) {
            this.debug(msg);
        }
    },

    // returns the word currently being typed, or null
    wordInProgress: function () {
        var sel = this.getSelectedRange();
        if (!sel) return null;

        var cidx = sel.selectionStart; // current indx
        var sidx = cidx;  // start of word index
        while (sidx > 0 && this.ele.value.charAt(sidx) != ',') {
            sidx--;
        }
        var skipStartForward = function (chr) { return (chr == "," || chr == " "); }

        while (skipStartForward(this.ele.value.charAt(sidx))) {
            sidx++;
        }

        return this.ele.value.substring(sidx, this.ele.value.length);
    },

    // appends some selected text after the care
    addSelectedText: function (chars) {
        var sel = this.getSelectedRange();
        this.ele.value = this.ele.value + chars;
        this.setSelectedRange(sel.selectionStart, this.ele.value.length);
    },

    moveCaretToEnd: function () {
        var len = this.ele.value.length;
        this.setSelectedRange(len, len);
    },

    getSelectedRange: function () {
        var ret = {};
        var ele = this.ele;

        if ("selectionStart" in ele) {
            ret.selectionStart = ele.selectionStart;
            ret.selectionEnd   = ele.selectionEnd;
            return ret;
        }

        if (document.selection && document.selection.createRange) {
            var range = document.selection.createRange();
            ret.selectionStart = InputComplete.IEOffset(range, "StartToStart");
            ret.selectionEnd   = InputComplete.IEOffset(range, "EndToEnd");
            return ret;
        }

        return null;
    },

    setSelectedRange: function (sidx, eidx) {
        var ele = this.ele;

        // preferred to setting selectionStart and end
        if (ele.setSelectionRange) {
            ele.focus();
            ele.setSelectionRange(sidx, eidx);
            return true;
        }

        // IE
        if (document.selection && document.selection.createRange) {
            ele.focus();
            var sel = document.selection.createRange ();
            sel.moveStart('character', -ele.value.length);
            sel.moveStart('character', sidx);
            sel.moveEnd('character', eidx - sidx);
            sel.select();
            return true;
        }

        // mozilla
        if ("selectionStart" in ele) {
            ele.selectionStart = sidx;
            ele.selectionEnd   = eidx;
            return true;
        }

        return false;
    },

    // returns true if caret is at end of line, or everything to the right
    // of us is selected
    caretAtEndOfNotSelected: function (sel) {
        sel = sel || this.getSelectedRange();
        var len = this.ele.value.length;
        return sel.selectionEnd == len;
    },

    disable: function () {
        this.disabled = true;
    },

    dummy: 1
});

InputComplete.onKeyDown = function (e) {
    if (this.disabled) return;

    var code = e.keyCode || e.which;

    this.dbg("onKeyDown, code="+code+", shift="+e.shiftKey);
    
    // if comma, but not with a shift which would be "<".  (FIXME: what about other keyboards layouts?)
    //FIXME: may be there is a stable cross-browser way to detect so-called other keyboard layouts - but i don't know anything easier than ... (see onKeyUp changes in tis revision)
    /*if ((code == 188 || code == 44) && ! e.shiftKey && this.caretAtEndOfNotSelected()) {
        this.moveCaretToEnd();
        return Event.stop(e);
    }*/

    return true;
};

InputComplete.onKeyUp = function (e) {
    if (this.disabled) return;

    var val = this.ele.value;

    var code = e.keyCode || e.which;
    this.dbg("keyUp = " + code);
    
    
    // ignore tab, backspace, left, right, delete, and enter
    if (code == 9 || code == 8 || code == 37 || code == 39 || code == 46 || code == 13)
       return false;

    var sel = this.getSelectedRange();

    var ss = sel.selectionStart;
    var se = sel.selectionEnd;

    this.dbg("keyUp, got ss="+ss +  ", se="+se+", val.length="+val.length);

    // only auto-complete if we're at the end of the line
    if (se != val.length) return false;

    var chr = String.fromCharCode(code);

    this.dbg("keyUp, got chr="+chr);
    //if (code == 188 || chr == ",") {
    if(/,$/.test(val)){	
        if (! this.caretAtEndOfNotSelected(sel)) {
            return false;
        }

        this.dbg("hit comma! .. value = " + this.ele.value);

        this.ele.value = this.ele.value.replace(/[\s,]+$/, "") + ", ";
        this.moveCaretToEnd();

        return Event.stop(e);
    }


    var inProg = this.wordInProgress();
    if (!inProg) return true;

    var rest = this.model.bestFinish(inProg);

    if (rest && rest.length > 0) {
        this.addSelectedText(rest);
    }
};

InputComplete.onBlur = function (e) {
    if (this.disabled) return;

    var tg = e.target;
    var list = tg.value;

    var noendjunk = list.replace(/[\s,]+$/, "");
    if (noendjunk != list) {
        tg.value = list = noendjunk;
    }

    var tags = list.split(",");
    for (var i =0; i<tags.length; i++) {
        var tag = tags[i].replace(/^\s+/,"").replace(/\s+$/,"");
        if (tag.length) {
            this.model.learn(tag);
        }
    }
};

InputComplete.onFocus = function (e) {
    if (this.disabled) return;
};


InputComplete.IEOffset = function ( range, compareType ) {
    if (this.disabled) return;

    var range2 = range.duplicate();
    range2.collapse( true );
    var parent = range2.parentElement();
    var length = range2.text.length;
    range2.move("character", -parent.value.length);

    var delta = max( 1, finiteInt( length * 0.5 ) );
    range2.collapse( true );
    var offset = 0;
    var steps = 0;

    // bail after 10k iterations in case of borkage
    while( (test = range2.compareEndPoints( compareType, range )) != 0 ) {
        if( test < 0 ) {
            range2.move( "character", delta );
            offset += delta;
        } else {
            range2.move( "character", -delta );
            offset -= delta;
        }
        delta = max( 1, finiteInt( delta * 0.5 ) );
        steps++;
        if( steps > 1000 )
            throw "unable to find textrange endpoint in " + steps + " steps";
    }

    return offset;
};
// datasource base class, the "M" in MVC
// subclass this and override theData to provide your data

DataSource = new Class(Object, {

  init: function (initialData) {
    DataSource.superClass.init.apply(this, arguments);
    this.watchers = [];
    this.theData = defined(initialData) ? initialData : [];
    this.sortField = "";
    this.sortType = "";
    this.sortDesc = false;
  },

  addWatcher: function (callback) {
    this.watchers.add(callback);
  },

  removeWatcher: function (callback) {
    this.watchers.remove(callback);
  },

  // call this if updating data and not using _setData
  _updated: function () {
    this.callWatchers();
  },

  callWatchers: function () {
    for (var i = 0; i < this.watchers.length; i++)
      this.watchers[i].apply(this, [this.data()]);
  },

  setData: function (theData) {
    this.theData = theData;

    if (this.sortField)
      this.sortDataBy(this.sortField, this.sortType, this.sortDesc);

    this._setData(theData);
  },

  _setData: function (theData) {
    this.theData = theData;
    this.callWatchers();
    return theData;
  },

  data: function () {
    return this.theData;
  },

  sortBy: function () {
    return this.sortField;
  },

  sortInverted: function () {
    return this.sortDesc;
  },

  // mimic some array functionality
  push: function (data) {
    this.theData.push(data);
    this.callWatchers();
  },

  pop: function () {
    var val = this.theData.pop();
    this.callWatchers();
    return val;
  },

  indexOf: function (value) {
    return this.theData.indexOf(value);
  },

  remove: function (value) {
    this.theData.remove(value);
    this.callWatchers();
  },

  empty: function () {
    this.theData = [];
    this.callWatchers();
  },

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

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

  allData: function () {
    var theData = this.theData;

    if (this.dataField && theData)
      theData = theData[this.dataField];

    return theData;
  },

  sortDataBy: function (field, type, invert) {
    this.sortField = field;
    this.sortDesc = invert;
    this.sortType = type;

    if (!field || !this.theData || !this.theData.sort)
      return;

    var sorted = this.theData.sort(function (a, b) {
      var ad = a[""+field], bd = b[""+field];
      ad = ad ? ad : "";
      bd = bd ? bd : "";

      switch(type) {

      case "string":
        var aname = ad.toUpperCase(), bname = bd.toUpperCase();

        if (aname < bname)
          return -1;
        else if (aname > bname)
          return 1;
        else
          return 0;

      case "isodate":
        var datA = Date.fromISOString(ad) || new Date(0);
        var datB = Date.fromISOString(bd) || new Date(0);

        return ((datA - datB) || 0);

      default:
      case "numeric":
        return ad - bd;

      }
    });

    if (invert)
      sorted.reverse();

    this._setData(sorted);
  }

});
/*
  This is a datasource you can attach to a table. It will enable
  the selection of rows or cells in the table.

  The data in the datasource is elements that are selected.

  $id:$
*/

SelectableTable = new Class(DataSource, {

    // options:
    //   table: what table element to attach to
    //   selectableClass: if you only want elements with a certain class to be selectable,
    //       specifiy this class with selectableClass
    //   multiple: can more than one thing be selected at once? default is true
    //   selectedClass: class to apply to selected elements
    //   checkboxClass: since there are frequently checkboxes associated with selectable elements,
    //       you can specify the class of your checkboxes to make them stay in sync
    //   selectableItem: What type of elements can be selected. Values are "cell" or "row"
    init: function (opts) {
        SelectableTable.superClass.init.apply(this, []);

        var table = opts.table;
        var selectableClass = opts.selectableClass;
        var multiple = opts.multiple;
        var selectedClass = opts.selectedClass
        var checkboxClass = opts.checkboxClass
        var selectableItem = opts.selectableItem;

        selectableItem = selectableItem == "cell" ? "cell" : "row";

        if (!defined(multiple)) multiple = true;

        this.table = table;
        this.selectableClass = selectableClass;
        this.multiple = multiple;
        this.selectedClass = opts.selectedClass;
        this.checkboxClass = opts.checkboxClass;

        this.selectedElements = [];

        // if it's not a table, die
        if (!table || !table.tagName || table.tagName.toLowerCase() != "table") return null;

        // get selectable items
        var tableElements = table.getElementsByTagName("*");

        var selectableElements;

        if (selectableItem == "cell") {
            selectableElements = DOM.filterElementsByTagName(tableElements, "td");
        } else {
            selectableElements = DOM.filterElementsByTagName(tableElements, "tr");
        }

        var self = this;
        selectableElements.forEach(function(ele) {
            // if selectableClass is defined and this element doesn't have the class, skip it
            if (selectableClass && !DOM.hasClassName(ele, selectableClass)) return;

            // attach click handler to every element inside the element
            var itemElements = ele.getElementsByTagName("*");
            for (var i = 0; i < itemElements.length; i++) {
                self.attachClickHandler(itemElements[i], ele);
            }

            // attach click handler to the element itself
            self.attachClickHandler(ele, ele);
        });
    },

    // stop our handling of this event
    stopHandlingEvent: function (evt) {
        if (!evt) return;

        // w3c
        if (evt.stopPropagation)
        evt.stopPropagation();

        // ie
        try {
            event.cancelBubble = true;
        } catch(e) {}
    },

    // attach a click handler to this element
    attachClickHandler: function (ele, parent) {
        if (!ele) return;

        var self = this;

        var rowClicked = function (evt) {
            // if it was a control-click, they're probably trying to open a new tab or something.
            // let's not handle it
            if (evt && (evt.ctrlKey || evt.metaKey)) return false;

            var tagName = ele.tagName.toLowerCase();

            // if this is a link or has an onclick handler,
            // return true and tell other events to return true
            if ((ele.href && tagName != "img") || ele.onclick) {
                self.stopHandlingEvent(evt);
                return true;
            }

            // if this is the child of a link, propagate the event up
            var ancestors = DOM.getAncestors(ele, true);
            for (var i = 0; i < ancestors.length; i++) {
                var ancestor = ancestors[i];
                if (ancestor.href && ancestor.tagName.toLowerCase() != "img") {
                    return true;
                }
            }

            // if this is an input or select element, skip it
            if ((tagName == "select" || tagName == "input") && parent.checkbox != ele) {
                self.stopHandlingEvent(evt);
                return true;
            }

            // toggle selection of this parent element
            if (self.selectedElements.indexOf(parent) != -1) {
                if (self.selectedClass) DOM.removeClassName(parent, self.selectedClass);

                self.selectedElements.remove(parent);
            } else {
                if (self.selectedClass) DOM.addClassName(parent, self.selectedClass);

                if (self.multiple) {
                    self.selectedElements.push(parent);
                } else {
                    if (self.selectedClass && self.selectedElements.length > 0) {
                        var oldParent = self.selectedElements[0];
                        if (oldParent) {
                            DOM.removeClassName(oldParent, self.selectedClass);
                            if (oldParent.checkbox) oldParent.checkbox.checked = "";
                        }
                    }

                    self.selectedElements = [parent];
                }
            }

            // update our data
            self.setData(self.selectedElements);

            // if there's a checkbox associated with this parent, set it's value
            // to the parent selected value
            if (parent.checkbox) parent.checkbox.checked = (self.selectedElements.indexOf(parent) != -1) ? "on" : '';
            if (parent.checkbox == ele) { self.stopHandlingEvent(evt); return true; }

            // always? not sure
            if (evt)
                Event.stop(evt);
        }

        // if this is a checkbox we need to keep in sync, set up its event handler
        if (this.checkboxClass && ele.tagName.toLowerCase() == "input"
            && ele.type == "checkbox" && DOM.hasClassName(ele, this.checkboxClass)) {

            parent.checkbox = ele;

            // override default event handler for the checkbox
            DOM.addEventListener(ele, "click", function (evt) {
                return true;
            });
        }

        // attach a method to the row so other people can programatically
        // select it.
        ele.rowClicked = rowClicked;

        DOM.addEventListener(ele, "click", rowClicked);
    }

});
// x_core.js, X v3.15.2, Cross-Browser.com DHTML Library
// Copyright (c) 2004 Michael Foster, Licensed LGPL (gnu.org)

// global vars still duplicated in xlib.js - I still don't know what I'm going to do about this
var xVersion='3.15.2',xNN4,xOp7,xOp5or6,xIE4Up,xIE4,xIE5,xMac,xUA=navigator.userAgent.toLowerCase();
if (window.opera){
  xOp7=(xUA.indexOf('opera 7')!=-1 || xUA.indexOf('opera/7')!=-1);
  if (!xOp7) xOp5or6=(xUA.indexOf('opera 5')!=-1 || xUA.indexOf('opera/5')!=-1 || xUA.indexOf('opera 6')!=-1 || xUA.indexOf('opera/6')!=-1);
}
else if (document.all && xUA.indexOf('msie')!=-1) {
  xIE4Up=parseInt(navigator.appVersion)>=4;
  xIE4=xUA.indexOf('msie 4')!=-1;
  xIE5=xUA.indexOf('msie 5')!=-1;
}
else if (document.layers) {xNN4=true;}
xMac=xUA.indexOf('mac')!=-1;

function xGetElementById(e) {
  if(typeof(e)!='string') return e;
  if(document.getElementById) e=document.getElementById(e);
  else if(document.all) e=document.all[e];
  else e=null;
  return e;
}
function xParent(e,bNode){
  if (!(e=xGetElementById(e))) return null;
  var p=null;
  if (!bNode && xDef(e.offsetParent)) p=e.offsetParent;
  else if (xDef(e.parentNode)) p=e.parentNode;
  else if (xDef(e.parentElement)) p=e.parentElement;
  return p;
}
function xDef() {
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])=='undefined') return false;}
  return true;
}
function xStr(s) {
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])!='string') return false;}
  return true;
}
function xNum(n) {
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])!='number') return false;}
  return true;
}
function xShow(e) {
  if(!(e=xGetElementById(e))) return;
  if(e.style && xDef(e.style.visibility)) e.style.visibility='visible';
}
function xHide(e) {
  if(!(e=xGetElementById(e))) return;
  if(e.style && xDef(e.style.visibility)) e.style.visibility='hidden';
}
function xZIndex(e,uZ) {
  if(!(e=xGetElementById(e))) return 0;
  if(e.style && xDef(e.style.zIndex)) {
    if(xNum(uZ)) e.style.zIndex=uZ;
    uZ=parseInt(e.style.zIndex);
  }
  return uZ;
}
function xColor(e,sColor) {
  if(!(e=xGetElementById(e))) return '';
  var c='';
  if(e.style && xDef(e.style.color)) {
    if(xStr(sColor)) e.style.color=sColor;
    c=e.style.color;
  }
  return c;
}
function xBackground(e,sColor,sImage) {
  if(!(e=xGetElementById(e))) return '';
  var bg='';
  if(e.style) {
    if(xStr(sColor)) {
      if(!xOp5or6) e.style.backgroundColor=sColor;
      else e.style.background=sColor;
    }
    if(xStr(sImage)) e.style.backgroundImage=(sImage!='')? 'url('+sImage+')' : null;
    if(!xOp5or6) bg=e.style.backgroundColor;
    else bg=e.style.background;
  }
  return bg;
}
function xMoveTo(e,iX,iY) {
  xLeft(e,iX);
  xTop(e,iY);
}
function xLeft(e,iX) {
  if(!(e=xGetElementById(e))) return 0;
  var css=xDef(e.style);
  if (css && xStr(e.style.left)) {
    if(xNum(iX)) e.style.left=iX+'px';
    else {
      iX=parseInt(e.style.left);
      if(isNaN(iX)) iX=0;
    }
  }
  else if(css && xDef(e.style.pixelLeft)) {
    if(xNum(iX)) e.style.pixelLeft=iX;
    else iX=e.style.pixelLeft;
  }
  return iX;
}
function xTop(e,iY) {
  if(!(e=xGetElementById(e))) return 0;
  var css=xDef(e.style);
  if(css && xStr(e.style.top)) {
    if(xNum(iY)) e.style.top=iY+'px';
    else {
      iY=parseInt(e.style.top);
      if(isNaN(iY)) iY=0;
    }
  }
  else if(css && xDef(e.style.pixelTop)) {
    if(xNum(iY)) e.style.pixelTop=iY;
    else iY=e.style.pixelTop;
  }
  return iY;
}
function xPageX(e) {
  if (!(e=xGetElementById(e))) return 0;
  var x = 0;
  while (e) {
    if (xDef(e.offsetLeft)) x += e.offsetLeft;
    e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
  return x;
}
function xPageY(e) {
  if (!(e=xGetElementById(e))) return 0;
  var y = 0;
  while (e) {
    if (xDef(e.offsetTop)) y += e.offsetTop;
    e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
//  if (xOp7) return y - document.body.offsetTop; // v3.14, temporary hack for opera bug 130324
  return y;
}
function xOffsetLeft(e) {
  if (!(e=xGetElementById(e))) return 0;
  if (xDef(e.offsetLeft)) return e.offsetLeft;
  else return 0;
}
function xOffsetTop(e) {
  if (!(e=xGetElementById(e))) return 0;
  if (xDef(e.offsetTop)) return e.offsetTop;
  else return 0;
}
function xScrollLeft(e) {
  var offset=0;
  if (!(e=xGetElementById(e))) {
    if(document.documentElement && document.documentElement.scrollLeft) offset=document.documentElement.scrollLeft;
    else if(document.body && xDef(document.body.scrollLeft)) offset=document.body.scrollLeft;
  }
  else { if (xNum(e.scrollLeft)) offset = e.scrollLeft; }
  return offset;
}
function xScrollTop(e) {
  var offset=0;
  if (!(e=xGetElementById(e))) {
    if(document.documentElement && document.documentElement.scrollTop) offset=document.documentElement.scrollTop;
    else if(document.body && xDef(document.body.scrollTop)) offset=document.body.scrollTop;
  }
  else { if (xNum(e.scrollTop)) offset = e.scrollTop; }
  return offset;
}
function xHasPoint(ele, iLeft, iTop, iClpT, iClpR, iClpB, iClpL) {
  if (!xNum(iClpT)){iClpT=iClpR=iClpB=iClpL=0;}
  else if (!xNum(iClpR)){iClpR=iClpB=iClpL=iClpT;}
  else if (!xNum(iClpB)){iClpL=iClpR; iClpB=iClpT;}
  var thisX = xPageX(ele), thisY = xPageY(ele);
  return (iLeft >= thisX + iClpL && iLeft <= thisX + xWidth(ele) - iClpR &&
          iTop >=thisY + iClpT && iTop <= thisY + xHeight(ele) - iClpB );
}
function xResizeTo(e,uW,uH) {
  xWidth(e,uW);
  xHeight(e,uH);
}
function xWidth(e,uW) {
  if(!(e=xGetElementById(e))) return 0;
  if (xNum(uW)) {
    if (uW<0) uW = 0;
    else uW=Math.round(uW);
  }
  else uW=-1;
  var css=xDef(e.style);
  if(css && xDef(e.offsetWidth) && xStr(e.style.width)) {
    if(uW>=0) xSetCW(e, uW);
    uW=e.offsetWidth;
  }
  else if(css && xDef(e.style.pixelWidth)) {
    if(uW>=0) e.style.pixelWidth=uW;
    uW=e.style.pixelWidth;
  }
  return uW;
}
function xHeight(e,uH) {
  if(!(e=xGetElementById(e))) return 0;
  if (xNum(uH)) {
    if (uH<0) uH = 0;
    else uH=Math.round(uH);
  }
  else uH=-1;
  var css=xDef(e.style);
  if(css && xDef(e.offsetHeight) && xStr(e.style.height)) {
    if(uH>=0) xSetCH(e, uH);
    uH=e.offsetHeight;
  }
  else if(css && xDef(e.style.pixelHeight)) {
    if(uH>=0) e.style.pixelHeight=uH;
    uH=e.style.pixelHeight;
  }
  return uH;
}
function xGetCS(ele,sP){return parseInt(document.defaultView.getComputedStyle(ele,'').getPropertyValue(sP));}
function xSetCW(ele,uW){
  var pl=0,pr=0,bl=0,br=0;
  if(xDef(document.defaultView) && xDef(document.defaultView.getComputedStyle)){
    pl=xGetCS(ele,'padding-left');
    pr=xGetCS(ele,'padding-right');
    bl=xGetCS(ele,'border-left-width');
    br=xGetCS(ele,'border-right-width');
  }
  else if(xDef(ele.currentStyle,document.compatMode)){
    if(document.compatMode=='CSS1Compat'){
      pl=parseInt(ele.currentStyle.paddingLeft);
      pr=parseInt(ele.currentStyle.paddingRight);
      bl=parseInt(ele.currentStyle.borderLeftWidth);
      br=parseInt(ele.currentStyle.borderRightWidth);
    }
  }
  else if(xDef(ele.offsetWidth,ele.style.width)){ // ?
    ele.style.width=uW+'px';
    pl=ele.offsetWidth-uW;
  }
  if(isNaN(pl)) pl=0; if(isNaN(pr)) pr=0; if(isNaN(bl)) bl=0; if(isNaN(br)) br=0;
  var cssW=uW-(pl+pr+bl+br);
  if(isNaN(cssW)||cssW<0) return;
  else ele.style.width=cssW+'px';
}
function xSetCH(ele,uH){
  var pt=0,pb=0,bt=0,bb=0;
  if(xDef(document.defaultView) && xDef(document.defaultView.getComputedStyle)){
    pt=xGetCS(ele,'padding-top');
    pb=xGetCS(ele,'padding-bottom');
    bt=xGetCS(ele,'border-top-width');
    bb=xGetCS(ele,'border-bottom-width');
  }
  else if(xDef(ele.currentStyle,document.compatMode)){
    if(document.compatMode=='CSS1Compat'){
      pt=parseInt(ele.currentStyle.paddingTop);
      pb=parseInt(ele.currentStyle.paddingBottom);
      bt=parseInt(ele.currentStyle.borderTopWidth);
      bb=parseInt(ele.currentStyle.borderBottomWidth);
    }
  }
  else if(xDef(ele.offsetHeight,ele.style.height)){ // ?
    ele.style.height=uH+'px';
    pt=ele.offsetHeight-uH;
  }
  if(isNaN(pt)) pt=0; if(isNaN(pb)) pb=0; if(isNaN(bt)) bt=0; if(isNaN(bb)) bb=0;
  var cssH=uH-(pt+pb+bt+bb);
  if(isNaN(cssH)||cssH<0) return;
  else ele.style.height=cssH+'px';
}
function xClip(e,iTop,iRight,iBottom,iLeft) {
  if(!(e=xGetElementById(e))) return;
  if(e.style) {
    if (xNum(iLeft)) e.style.clip='rect('+iTop+'px '+iRight+'px '+iBottom+'px '+iLeft+'px)';
    else e.style.clip='rect(0 '+parseInt(e.style.width)+'px '+parseInt(e.style.height)+'px 0)';
  }
}
function xClientWidth() {
  var w=0;
  if(xOp5or6) w=window.innerWidth;
  else if(!window.opera && document.documentElement && document.documentElement.clientWidth)
    w=document.documentElement.clientWidth;
  else if(document.body && document.body.clientWidth)
    w=document.body.clientWidth;
  else if(xDef(window.innerWidth,window.innerHeight,document.height)) {
    w=window.innerWidth;
    if(document.height>window.innerHeight) w-=16;
  }
  return w;
}
function xClientHeight() {
  var h=0;
  if(xOp5or6) h=window.innerHeight;
  else if(!window.opera && document.documentElement && document.documentElement.clientHeight)
    h=document.documentElement.clientHeight;
  else if(document.body && document.body.clientHeight)
    h=document.body.clientHeight;
  else if(xDef(window.innerWidth,window.innerHeight,document.width)) {
    h=window.innerHeight;
    if(document.width>window.innerWidth) h-=16;
  }
  return h;
}
function xInnerHtml(e, sHtml) {
  if(!(e=xGetElementById(e))) return '';
  if (xStr(e.innerHTML)) {
    if (xStr(sHtml)) e.innerHTML = sHtml;
    else return e.innerHTML;
  }
}
    var lastDiv;
    lastDiv = 'qrdiv';

    var Site;
    if (! Site) Site = new Object()

    function quickreply(dtid, pid, newsubject) {
        // Mac IE 5.x does not like dealing with
        // nextSibling since it does not support it
        if (xIE4Up && xMac) { return true; }

        // on IE, cancel the bubble of the event up to the page. other
        // browsers don't seem to bubble events up registered this way.
        var ev = window.event;
        if (ev) {
            if (ev.stopPropagation)
               ev.stopPropagation();
            if (ev.cancelBubble != "undefined")
                ev.cancelBubble = true;
        }

        var targetname = "ljqrt" + dtid;

        var ptalkid = xGetElementById('parenttalkid');
        var rto = xGetElementById('replyto');
        var dtid_field = xGetElementById('dtid');
        var qr_div = xGetElementById('qrdiv');
        var cur_div = xGetElementById(targetname);
        var qr_form_div  = xGetElementById('qrformdiv');
        var qr_form = xGetElementById('qrform');
        var subject = xGetElementById('subject');

        // Is this a dumb browser?
        if( !ptalkid || !rto || !dtid_field || !qr_div || !cur_div || !qr_form || 
            !qr_form_div || !subject) {
            return true;
        }

        ptalkid.value = pid;
        dtid_field.value = dtid;
        rto.value = pid;

        if (lastDiv == 'qrdiv') {
            if (! showQRdiv(qr_div)) {
               return true;
            }

            // Only one swap
            if (! swapnodes(qr_div, cur_div)) {
                return true;
            }
        } else if (lastDiv != dtid) {
            var last_div = xGetElementById(lastDiv);
            // Two swaps
            if ((last_div != cur_div) && ! (swapnodes(last_div, cur_div) && swapnodes(qr_div, last_div))) {
                return true;
            }
        }

        lastDiv = targetname;

        if(!subject.value || subject.value == subject.defaultValue || subject.value.substr(0, 4) == 'Re: ') {
          subject.value = newsubject;
          subject.defaultValue = newsubject;
        }

        if(cur_div.className) {
          qr_form_div.className = cur_div.className;
        } else {
          qr_form_div.className = "";
        }

        var qr_body = qr_form.body;  // the textarea of the qr_form
        if (qr_body) {
            // have to set a timeout because most browsers won't let you focus
            // on an element that's still in the process of being created.
            // so lame.
            window.setTimeout(function () { qr_body.focus() }, 250);
        }

        // So it does not follow the link
        return false;
    }

    function regEvent (target, evt, func) {
      if (! target) { return; }
      if (target.attachEvent)
        target.attachEvent("on"+evt, func);
      if (target.addEventListener)
        target.addEventListener(evt, func, false);
    }

    function moreopts()
    {
        var qr_form = xGetElementById('qrform');
        var basepath = xGetElementById('basepath');
        var dtid = xGetElementById('dtid');
        var pidform = xGetElementById('parenttalkid');

        // do not do the default form action (post comment) if something is broke
        if (!qr_form || !basepath || !dtid || !pidform) return false;

        var replyto = Number(dtid.value);
        var pid = Number(pidform.value);

        if(replyto > 0 && pid > 0) {
          //a reply to a comment
          qr_form.action = basepath.value + "replyto=" + replyto;
        } else {
          qr_form.action = basepath.value + "mode=reply";
        }

        // we changed the form action so submit ourselves
        // and don't use the default form action
        qr_form.submit();
        return false;
    }

   function submitform()
   {
        var submitmore = xGetElementById('submitmoreopts');
        var submit = xGetElementById('submitpost');
        if (!submitmore || !submit) return false;

        submit.disabled = true;
        submitmore.disabled = true;

        // New top-level comments
        var dtid = xGetElementById('dtid');
        if (!Number(dtid.value)) {
            dtid.value =+ 0;
        }

        var qr_form = xGetElementById('qrform');
        qr_form.action = Site.siteroot + '/talkpost_do.bml';
        qr_form.submit();

        // don't do default form action
        return false;
   }

   function swapnodes (orig, to_swap) {
        var orig_pn = xParent(orig, true);
        var next_sibling = orig.nextSibling;
        var to_swap_pn = xParent(to_swap, true);
        if (! to_swap_pn) {
            return false;
        }

        to_swap_pn.replaceChild(orig, to_swap);
        orig_pn.insertBefore(to_swap, next_sibling);
        return true;
   }

   function checkLength() {
        var qr_form = xGetElementById('qrform');
        if (!qr_form) return true;
        var textbox = qr_form.body;
        if (textbox.value.length > 4300) {
             alert('Sorry, but your comment of ' + textbox.value.length + ' characters exceeds the maximum character length of 4300.  Please try shortening it and then post again.');
             return false;
        }
        return true;
   }

    // Maintain entry through browser navigations.
    function save_entry() {
        var qr_form = xGetElementById('qrform');
        if (!qr_form) return false;
        var qr_body = qr_form.body;
        var qr_subject = xGetElementById('subject');
        var do_spellcheck = xGetElementById('do_spellcheck');
        var qr_dtid = xGetElementById('dtid');
        var qr_ptid = xGetElementById('parenttalkid');
        var qr_upic = xGetElementById('prop_picture_keyword');

        var qr_saved_body = xGetElementById('saved_body');
        var qr_saved_subject = xGetElementById('saved_subject');
        var saved_do_spellcheck = xGetElementById('saved_spell');
        var qr_saved_dtid = xGetElementById('saved_dtid');
        var qr_saved_ptid = xGetElementById('saved_ptid');
        var qr_saved_upic = xGetElementById('saved_upic');

        qr_saved_body.value = qr_body.value;
        qr_saved_subject.value = qr_subject.value;
        if(do_spellcheck) {
          saved_do_spellcheck.value = do_spellcheck.checked;
        }

        qr_saved_dtid.value = qr_dtid.value;
        qr_saved_ptid.value = qr_ptid.value;

        if (qr_upic) { // if it was in the form
            qr_saved_upic.value = qr_upic.selectedIndex;
        }

        return false;
    }

    // Restore saved_entry text across platforms.
    function restore_entry() {
        setTimeout(
            function () {

                var saved_body = xGetElementById('saved_body');
                if (!saved_body || saved_body.value == "") return false;

                var dtid = xGetElementById('saved_dtid');
                if (! dtid) return false;
                var ptid = xGetElementById('saved_ptid');
                ptid.value = parseInt( ptid.value );

                quickreply(dtid.value, ptid.value, saved_body.value);

                var qr_form = xGetElementById('qrform');
                if (!qr_form) return false;
                var body = qr_form.body
                body.value = saved_body.value;

                // Some browsers require we explicitly set this after the div has moved
                // and is now no longer hidden
                var qr_saved_subject = xGetElementById('saved_subject');
                var qr_saved_spell = xGetElementById('saved_spell');
                var qr_saved_dtid = xGetElementById('saved_dtid');
                var qr_saved_ptid = xGetElementById('saved_ptid');
                var qr_saved_upic = xGetElementById('saved_upic');

                var subject = xGetElementById('subject');
                if (! subject) return false;
                subject.value = qr_saved_subject.value

                var prop_picture_keyword = xGetElementById('prop_picture_keyword');
                if (prop_picture_keyword) { // if it was in the form
                    prop_picture_keyword.selectedIndex = qr_saved_upic.value;
                }

                var spell_check = xGetElementById('do_spellcheck');
                if (! spell_check) return false;
                if (qr_saved_spell.value == 'true') {
                    spell_check.checked = true;
                } else {
                    spell_check.checked = false;
                }

            }, 100);
        return false;
    }

    function showQRdiv(qr_div) {
        if (! qr_div) {
            qr_div = xGetElementById('qrdiv');
            if (! qr_div) {
                return false;
            }
        } else if (qr_div.style && xDef(qr_div.style.display)) {
            qr_div.style.display='inline';
            return true;
        } else {
            return false;
        }
    }

    //after the functions have been defined, register them
    LiveJournal.register_hook('page_load', restore_entry);
    regEvent(window, 'unload', save_entry);
// called by S2:
function setStyle (did, attr, val) {
    if (! document.getElementById) return;
    var de = document.getElementById(did);
    if (! de) return;
    if (de.style)
        de.style[attr] = val
}

// called by S2:
function setInner (did, val) {
    if (! document.getElementById) return;
    var de = document.getElementById(did);
    if (! de) return;
    de.innerHTML = val;
}

// called by S2:
function hideElement (did) {
    if (! document.getElementById) return;
    var de = document.getElementById(did);
    if (! de) return;
    de.style.display = 'none';
}

// called by S2:
function setAttr (did, attr, classname) {
    if (! document.getElementById) return;
    var de = document.getElementById(did);
    if (! de) return;
    de.setAttribute(attr, classname);
}

// called from Page:
function multiformSubmit (form, txt) {
    var sel_val = form.mode.value;
    if (!sel_val) {
        alert(txt.no_action);
        return false;
    }

    if (sel_val.substring(0, 4) == 'all:') { // mass action
        return;
    }

    var i = -1, has_selected = false; // at least one checkbox
    while (form[++i]) {
        if (form[i].name.substring(0, 9) == 'selected_' && form[i].checked) {
            has_selected = true;
            break;
        }
    }
    if (!has_selected) {
        alert(txt.no_comments);
        return false;
    }

    if (sel_val == 'delete' || sel_val == 'deletespam') {
        return confirm(txt.conf_delete);
    }
}

// hsv to rgb
// h, s, v = [0, 1), [0, 1], [0, 1]
// r, g, b = [0, 255], [0, 255], [0, 255]
function hsv_to_rgb (h, s, v)
{
    if (s == 0) {
	v *= 255;
	return [v,v,v];
    }

    h *= 6;
    var i = Math.floor(h);
    var f = h - i;
    var p = v * (1 - s);
    var q = v * (1 - s * f);
    var t = v * (1 - s * (1 - f));

    v = Math.floor(v * 255 + 0.5);
    t = Math.floor(t * 255 + 0.5);
    p = Math.floor(p * 255 + 0.5);
    q = Math.floor(q * 255 + 0.5);

    if (i == 0) return [v,t,p];
    if (i == 1) return [q,v,p];
    if (i == 2) return [p,v,t];
    if (i == 3) return [p,q,v];
    if (i == 4) return [t,p,v];
    return [v,p,q];
}

var curPopup = null;
var curPopup_id = 0;

function killPopup () {
    if (!curPopup)
        return true;

    var popup = curPopup;
    curPopup = null;

    var opp = 1.0;

    var fade = function () {
        opp -= 0.15;

        if (opp <= 0.1) {
            popup.parentNode.removeChild(popup);
        } else {
            popup.style.filter = "alpha(opacity=" + Math.floor(opp * 100) + ")";
            popup.style.opacity = opp;
            window.setTimeout(fade, 20);
        }
    };
    fade();

    return true;
}

function deleteComment (ditemid) {
    killPopup();

    var form = $('ljdelopts' + ditemid),
        todel = $('ljcmt' + ditemid),
        opt_delthread = opt_delauthor =
        is_deleted = is_error = false,
        pulse = 0;

    var postdata = 'confirm=1';
    if (form){ 
    	if (form.ban && form.ban.checked) postdata += '&ban=1';
    	if (form.spam && form.spam.checked) postdata += '&spam=1';
    	if (form.delthread && form.delthread.checked) {
        	postdata += '&delthread=1';
        	opt_delthread = true;
   	 }
    	if (form.delauthor && form.delauthor.checked) {
        	postdata += '&delauthor=1';
        	opt_delauthor = true;
    	}
    }
    postdata += '&lj_form_auth=' + LJ_cmtinfo.form_auth;
    var curJournal=(Site.currentJournal!="")?(Site.currentJournal):(LJ_cmtinfo.journal);
    var opts = {
        url: LiveJournal.getAjaxUrl('delcomment')+'?mode=js&journal=' + curJournal + '&id=' + ditemid,
        data: postdata,
        method: 'POST',
        onData: function(data) {
            is_deleted = !!data;
            is_error = !is_deleted;
        },
        onError: function() {
          alert('Error deleting ' + ditemid);
          is_error = true;
        }
    }

    HTTPReq.getJSON(opts);

    var flash = function () {
        var rgb = hsv_to_rgb(0, Math.cos((pulse + 1) / 2), 1);
        pulse += 3.14159 / 5;
        var color = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")";

        todel.style.border = "2px solid " + color;
        if (is_error) {
            todel.style.border = "";
            // and let timer expire
        } else if (is_deleted) {
            removeComment(ditemid, opt_delthread);
            if (opt_delauthor) {
                for (var item in LJ_cmtinfo) {
                    if (LJ_cmtinfo[item].u == LJ_cmtinfo[ditemid].u) {
                        removeComment(item);
                    }
                }
            }
        } else {
            window.setTimeout(flash, 50);
        }
    };

    window.setTimeout(flash, 5);
}

function removeComment (ditemid, killChildren) {
    var todel = document.getElementById("ljcmt" + ditemid);
    if (todel) {
        todel.style.display = 'none';

        var userhook = window["userhook_delete_comment_ARG"];
        if (userhook)
            userhook(ditemid);
    }
    if (killChildren) {
        var com = LJ_cmtinfo[ditemid];
        for (var i = 0; i < com.rc.length; i++) {
            removeComment(com.rc[i], true);
        }
    }
}

function docClicked () {
    killPopup();

  // we didn't handle anything, who are we kidding
}

function createDeleteFunction (ae, dItemid) {
    return function (e) {
		e = jQuery.event.fix(e || window.event);

        var finalHeight = 115;

        if (e.shiftKey || (curPopup && curPopup_id != dItemid)) {
            killPopup();
        }

        var doIT = 0;
        // immediately delete on shift key
        if (e.shiftKey) {
            doIT = 1;
			deleteComment(dItemid);
        } else {
            if (! LJ_cmtinfo)
                return true;

            var com = LJ_cmtinfo[dItemid];
            var remoteUser = LJ_cmtinfo["remote"];
            if (!com || !remoteUser)
                return true;
            var canAdmin = LJ_cmtinfo["canAdmin"];
			
			var pos_offset = jQuery(ae).position(),
				offset = jQuery(ae).offset(),
				pos_x = e.pageX + pos_offset.left - offset.left,
				top = e.pageY + pos_offset.top - offset.top + 5,
				left = Math.max(pos_x + 5 - 250, 5),
				$window = jQuery(window);
			
			//calc with viewport
			if ($window.scrollLeft() > left + offset.left - pos_offset.left) {
				left = $window.scrollLeft() + pos_offset.left - offset.left;
			}
			
			if (curPopup && curPopup_id == dItemid) {
				//calc with viewport
				top = Math.min(top, $window.height() + $window.scrollTop() - jQuery(curPopup).outerHeight() + pos_offset.top - offset.top);
				curPopup.style.left = left + 'px';
				curPopup.style.top = top + 'px';
				
				return Event.stop(e);
			}
			
			var de = jQuery('<div class="ljcmtmanage" style="text-align:left;position:absolute;visibility:hidden;width:250px;left:0;top:0;z-index:3"></div>')
						.click(function(e){
							e.stopPropagation()
						});
			
            var inHTML = "<form style='display: inline' id='ljdelopts" + dItemid + "'><span style='font-face: Arial; font-size: 8pt'><b>Delete comment?</b><br />";
            var lbl;
            if (com.u != "" && com.u != remoteUser && canAdmin) {
                lbl = "ljpopdel" + dItemid + "ban";
                inHTML += "<input type='checkbox' name='ban' id='" + lbl + "'> <label for='" + lbl + "'>Ban <b>" + com.u + "</b> from commenting</label><br />";
            } else {
                finalHeight -= 15;
            }

            if (remoteUser != com.u) {
                lbl = "ljpopdel" + dItemid + "spam";
                inHTML += "<input type='checkbox' name='spam' id='" + lbl + "'> <label for='" + lbl + "'>Mark this comment as spam</label><br />";
            } else {
                finalHeight -= 15;
            }

            if (com.rc && com.rc.length && canAdmin) {
                lbl = "ljpopdel" + dItemid + "thread";
                inHTML += "<input type='checkbox' name='delthread' id='" + lbl + "'> <label for='" + lbl + "'>Delete thread (all subcomments)</label><br />";
            } else {
                finalHeight -= 15;
            }
            if (canAdmin&&com.u) {
                lbl = "ljpopdel" + dItemid + "author";
                inHTML += "<input type='checkbox' name='delauthor' id='" + lbl + "'> <label for='" + lbl + "'>Delete all <b>" + (com.u == remoteUser ? 'my' : com.u) + "</b> comments in this post</label><br />";
            } else {
                finalHeight -= 15;
            }

            inHTML += "<input type='button' value='Delete' onclick='deleteComment(" + dItemid + ");' /> <input type='button' value='Cancel' onclick='killPopup()' /></span><br /><span style='font-face: Arial; font-size: 8pt'><i>shift-click to delete without options</i></span></form>";
			
			de.html(inHTML).insertAfter(ae);
			
			//calc with viewport
			top = Math.min(top, $window.height() + $window.scrollTop() - de.outerHeight() + pos_offset.top - offset.top);
			
			de.css({
				left: left,
				top: top,
				height: 10,
				visibility: 'visible',
				overflow: 'hidden'
			});
			
			curPopup = de[0];
			curPopup_id = dItemid;
			
			var height = 10;
			var grow = function () {
				height += 7;
				if (height > finalHeight) {
					de.height('auto');
				} else {
					de.height(height);
					window.setTimeout(grow, 20);
				}
			}
			grow();
		}
		Event.stop(e);
	}
}

function poofAt (pos) {
    var de = document.createElement("div");
    de.style.position = "absolute";
    de.style.background = "#FFF";
    de.style.overflow = "hidden";
    var opp = 1.0;

    var top = pos.y;
    var left = pos.x;
    var width = 5;
    var height = 5;
    document.body.appendChild(de);

    var fade = function () {
        opp -= 0.15;
        width += 10;
        height += 10;
        top -= 5;
        left -= 5;

        if (opp <= 0.1) {
            de.parentNode.removeChild(de);
        } else {
            de.style.left = left + "px";
            de.style.top = top + "px";
            de.style.height = height + "px";
            de.style.width = width + "px";
            de.style.filter = "alpha(opacity=" + Math.floor(opp * 100) + ")";
            de.style.opacity = opp;
            window.setTimeout(fade, 20);
        }
    };
    fade();
}

function updateLink (ae, resObj, clickTarget) {
    ae.href = resObj.newurl;
    var userhook = window["userhook_" + resObj.mode + "_comment_ARG"];
    var did_something = 0;

    if (clickTarget && clickTarget.src && clickTarget.src == resObj.oldimage) {
        clickTarget.src = resObj.newimage;
        did_something = 1;
    }

    if (userhook) {
        userhook(resObj.id);
        did_something = 1;
    }

    // if all else fails, at least remove the link so they're not as confused
    if (! did_something) {
        if (ae && ae.style)
            ae.style.display = 'none';
        if (clickTarget && clickTarget.style)
            clickTarget.style.dispay = 'none';
    }

}

var tsInProg = {}  // dict of { ditemid => 1 }
function createModerationFunction(ae, dItemid)
{
	return function(e)
	{
		var e = jQuery.event.fix(e || window.event);
			pos = { x: e.pageX, y: e.pageY },
			postUrl = ae.href.replace(/.+talkscreen\.bml/, LiveJournal.getAjaxUrl('talkscreen')),
			hourglass = jQuery(e).hourglass()[0];
		
		var xhr = jQuery.post(postUrl + '&jsmode=1',
			{
				confirm: 'Y',
				lj_form_auth: LJ_cmtinfo.form_auth
			},
			function(json)
			{
				tsInProg[dItemid] = 0;
				var comms_ary = [dItemid]
				var map_comms = function(id)
				{
					var i = -1, new_id;
					while(new_id = LJ_cmtinfo[id].rc[++i])
					{
						if (LJ_cmtinfo[new_id].full) {
							comms_ary.push(new_id);
							map_comms(String(new_id));
						}
					}
				}
				
				// check rc for no comments page
				if (LJ_cmtinfo[dItemid].rc) {
					if (/mode=(un)?freeze/.test(ae.href)) {
						map_comms(dItemid);
					}
					var ids = '#ljcmt' + comms_ary.join(',#ljcmt');
				} else {
					var rpcRes;
					eval(json);
					updateLink(ae, rpcRes, ae.getElementsByTagName('img')[0]);
					// /tools/recent_comments.bml
					if (document.getElementById('ljcmtbar'+dItemid)) {
						var ids = '#ljcmtbar'+dItemid;
					}
					// ex.: portal/
					else {
						hourglass.hide();
						poofAt(pos);
						return;
					}
				}
				
				// modified jQuery.fn.load
				jQuery.ajax({
					url: location.href,
					type: 'GET',
					dataType: 'html',
					complete: function(res, status) {
						// If successful, inject the HTML into all the matched elements
						if (status == 'success' || status == 'notmodified') {
							// Create a dummy div to hold the results
							var nodes = jQuery('<div/>')
								// inject the contents of the document in, removing the scripts
								// to avoid any 'Permission Denied' errors in IE
								.append(res.responseText.replace(/<script(.|\s)*?\/script>/gi, ''))
								// Locate the specified elements
								.find(ids)
								.each(function(){
									var id = this.id.replace(/[^0-9]/g, '');
									if (LJ_cmtinfo[id].expanded) {
										var expand = this.innerHTML.match(/Expander\.make\(.+?\)/)[0];
										(function(){
											eval(expand);
										}).apply(document.createElement('a'));
									} else {
										jQuery('#'+this.id).replaceWith(this);
										setupAjax(this);
									}
								});
							hourglass.hide();
							poofAt(pos);
						}
					}
				});
			}
		);
		
		return false;
	}
}

function setupAjax (node) {
    var links = node ? node.getElementsByTagName('a') : document.links,
        rex_id = /id=(\d+)/,
        i = -1, ae;
    
    while (links[++i]) {
        ae = links[i];
        if (ae.href.indexOf('talkscreen.bml') != -1) {
            var reMatch = rex_id.exec(ae.href);
            if (!reMatch) continue;

            var id = reMatch[1];
            if (!document.getElementById('ljcmt' + id)) continue;

            ae.onclick = createModerationFunction(ae, id);
        } else if (ae.href.indexOf('delcomment.bml') != -1) {
            if (LJ_cmtinfo && LJ_cmtinfo.disableInlineDelete) continue;

            var reMatch = rex_id.exec(ae.href);
            if (!reMatch) continue;

            var id = reMatch[1];
            if (!document.getElementById('ljcmt' + id)) continue;

            ae.onclick = createDeleteFunction(ae, id);
        }
    }
}



jQuery(function(){setupAjax()});

DOM.addEventListener(document, 'click', docClicked);
document.write("<style> div.ljcmtmanage { color: #000; background: #e0e0e0; border: 2px solid #000; padding: 3px; }</style>");
Horizon = new Object;

// Holds style info for the top level menu
Horizon.toplevel_hover_style = null;
// Holds the last menu opened
Horizon.opened_menu = null;
// Holds Select elements tht have been hidden
Horizon.hiddenSelects = [];
// Is IE version 6 or lower flag
Horizon.isIE6down = false;

Horizon.scheme_init = function () {
    Horizon.toplevel_hover_style = DOM.getComputedStyle($("Alpha"));
    Horizon.setIsIE6down();
    DOM.addEventListener($('footer_lang_list'), "change", function (evt) { Horizon.changeLang(evt, $('footer_lang_list').value) });
}

Horizon.open_menu = function (m) {
    /* Needed to nicely turn on top level menu items for IE */
    if (Horizon.toplevel_hover_style) {
        m.style.backgroundImage = Horizon.toplevel_hover_style.backgroundImage;
        m.style.borderColor = Horizon.toplevel_hover_style.borderColor;
        m.style.borderWidth = Horizon.toplevel_hover_style.borderWidth;
        m.style.borderStyle = Horizon.toplevel_hover_style.borderStyle;
        var links = m.getElementsByTagName('a');
        links[0].style.color = Horizon.toplevel_hover_style.color;
    }

    Horizon.hideSelects();
    var menus = m.getElementsByTagName('ul');
    for (var i = 0; i <= menus.length; i++) {
        if (!menus[i]) return;
        menus[i].style.display = "block";
    }

    Event.stop(e);
    return false;
}

Horizon.close_menu = function (m) {
    if (Horizon.toplevel_hover_style) {
        m.style.backgroundImage = '';
        m.style.borderColor = '';
        m.style.borderWidth = '';
        m.style.borderStyle = '';
        var links = m.getElementsByTagName('a');
        links[0].style.color = '';
    }

    Horizon.showSelects();
    var menus = m.getElementsByTagName('ul');
    for (var i = 0; i <= menus.length; i++) {
        if (!menus[i]) return;
        menus[i].style.display = "none";
    }

    Event.stop(e);
    return false;
}

Horizon.mouseMove = function (evt) {
    Event.prep(evt);
    if (!evt.target) return;

    var ancestors = DOM.getAncestorsByClassName(evt.target, "NavMenuItem", true);
    if (ancestors.length) {
        if (!Horizon.opened_menu || Horizon.opened_menu != ancestors[0])
            Horizon.open_menu(ancestors[0]);
        if (Horizon.opened_menu && Horizon.opened_menu != ancestors[0])
            Horizon.close_menu(Horizon.opened_menu);
        Horizon.opened_menu = ancestors[0];
    } else {
        if (Horizon.opened_menu) Horizon.close_menu(Horizon.opened_menu);
        Horizon.opened_menu = null;
    }
}

Horizon.hideSelects = function () {
    if (!Horizon.isIE6down) return;
    var sels = document.getElementsByTagName("select");
    var ele;
    for (var i = 0; i < sels.length; i++) {
        ele = sels[i];
        if (!ele) continue;

        if (ele.style.visibility != 'hidden' && ele.className == 'hideable') {
            ele.style.visibility = 'hidden';
            Horizon.hiddenSelects.push(ele);
        }
    }
}

Horizon.showSelects = function () {
    var ele;
    while (ele = Horizon.hiddenSelects.pop())
        ele.style.visibility = '';
}

Horizon.setIsIE6down = function () {
    var UA = navigator.userAgent.toLowerCase();
    if ((UA.indexOf('msie 5') != -1) || (UA.indexOf('msie 6') != -1))
        Horizon.isIE6down = true;
}

Horizon.changeLang = function(evt, lang) {
    if (lang) {
        window.location = Site.siteroot + "/tools/setlang.bml?lang=" + lang + "&returnto=" + escape(window.location);
    }
}

/* Try to speed up page load in Mozilla */
if (window.controllers) {
    document.addEventListener("DOMContentLoaded", Horizon.scheme_init, null);
    if(!window.vertigo) document.addEventListener("mousemove", Horizon.mouseMove, document);
} else {
    DOM.addEventListener(window, "load", Horizon.scheme_init);
    if(!window.vertigo) DOM.addEventListener(document, "mousemove", Horizon.mouseMove);
}

// ljtalk for ctxpopup
LiveJournal.register_hook("ctxpopup_extrainfo", function (userdata) {
    var content = document.createElement("div");

    if (userdata.is_person) {
        if (userdata.is_online !== '') {
            // online status
            var onlineStatusLabel = document.createElement("span");
            var jabberTitle = userdata.jabber_title;
            onlineStatusLabel.innerHTML = jabberTitle + ": ";
            DOM.addClassName(onlineStatusLabel, "OnlineStatus");
            content.appendChild(onlineStatusLabel);

            // build status
            var onlineStatus = document.createElement("span");


            var onlineStatusText = document.createElement("span");
            onlineStatus.appendChild(onlineStatusText);

            content.appendChild(onlineStatus);

            if (userdata.is_online) {
                onlineStatusText.innerHTML = "Online";
            } else if (userdata.is_online == '0') {
                onlineStatusText.innerHTML = "Offline";
            }
        }
    }

    return content;
});

// for updating ljcom widgets from livejournal ones
LiveJournal.register_hook("update_other_widgets", function (from_widget) {
    if (from_widget == "LayoutChooser" && Customize.AdLayout) {
        Customize.AdLayout.updateContent();
    }
});

