/*!
 * 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);// Assanka change: alter function name to prevent noConflict/scope issues, and pass in jQuery as the first argument for the same reason
jQueryAutocomplete = function(jQuery, input, options) {
	// Create a link to self
	var me = this;

	// Create jQuery object for input element
	var $input = jQuery(input).attr("autocomplete", "off");

	// Apply inputClass if necessary
	if (options.inputClass) $input.addClass(options.inputClass);

	// Assanka change - disable results div creation, do it on demand to avoid "operation aborted" errors in IE
	var results = false;
	var $results = false;
	/*
	// Create results
	var results = document.createElement("div");
	// Create jQuery object for results
	var $results = jQuery(results);
	$results.hide().addClass(options.resultsClass).css("position", "absolute");
	if( options.width > 0 ) $results.css("width", options.width);

	// Add to body element
	jQuery("body").append(results);
*/
	input.autocompleter = me;

	var timeout = null;
	var prev = "";
	var active = -1;
	var cache = {};
	var keyb = false;
	var hasFocus = false;
	var lastKeyPressCode = null;
	
	// Assanka change - add a variable to track whether the user results div has been created.
	var resultsdivcreated = false;

	// flush cache
	function flushCache(){
		cache = {};
		cache.data = {};
		cache.length = 0;
	};

	// flush cache
	flushCache();

	// if there is a data array supplied
	if( options.data != null ){
		var sFirstChar = "", stMatchSets = {}, row = [];

		// no url was specified, we need to adjust the cache length to make sure it fits the local data store
		if( typeof options.url != "string" ) options.cacheLength = 1;

		// loop through the array and create a lookup structure
		for( var i=0; i < options.data.length; i++ ){
			// if row is a string, make an array otherwise just reference the array
			row = ((typeof options.data[i] == "string") ? [options.data[i]] : options.data[i]);

			// if the length is zero, don't add to list
			if( row[0].length > 0 ){
				// get the first character
				sFirstChar = row[0].substring(0, 1).toLowerCase();
				// if no lookup array for this character exists, look it up now
				if( !stMatchSets[sFirstChar] ) stMatchSets[sFirstChar] = [];
				// if the match is a string
				stMatchSets[sFirstChar].push(row);
			}
		}

		// add the data items to the cache
		for( var k in stMatchSets ){
			// increase the cache size
			options.cacheLength++;
			// add to the cache
			addToCache(k, stMatchSets[k]);
		}
	}

	$input
	.keydown(function(e) {
		// track last key pressed
		lastKeyPressCode = e.keyCode;
		switch(e.keyCode) {
			case 38: // up
				e.preventDefault();
				moveSelect(-1);
				break;
			case 40: // down
				e.preventDefault();
				moveSelect(1);
				break;
			case 9:  // tab
			case 13: // return
				if( selectCurrent() ){
					// make sure to blur off the current field
					$input.get(0).blur();
					e.preventDefault();
				}
				break;
			default:
				active = -1;
				if (timeout) clearTimeout(timeout);
				timeout = setTimeout(function(){onChange();}, options.delay);
				break;
		}
	})
	.focus(function(){
		// track whether the field has focus, we shouldn't process any results if the field no longer has focus
		hasFocus = true;
	})
	.blur(function() {
		// track whether the field has focus
		hasFocus = false;
		hideResults();
	});

	hideResultsNow();

	// Assanka change - create results on demand to avoid operation aborted errors in IE, support base offset
	// element.
	function createResultsOnDemand() {
		if (resultsdivcreated) return;

		// Create results
		results = document.createElement("div");
		// Create jQuery object for results
		 $results = jQuery(results);
		$results.hide().addClass(options.resultsClass).css("position", "absolute");
		if( options.width > 0 ) $results.css("width", options.width);
	
		// Add to base element
		jQuery(options.baseOffsetElementIdentifier).append(results);
		resultsdivcreated = true;
	}
	
	function onChange() {
		// Assanka change - ensure results div is created on demand
		if (!resultsdivcreated) createResultsOnDemand();

		// ignore if the following keys are pressed: [del] [shift] [capslock]
		if( lastKeyPressCode == 46 || (lastKeyPressCode > 8 && lastKeyPressCode < 32) ) return $results.hide();
		var v = $input.val();
		if (v == prev) return;
		prev = v;
		if (v.length >= options.minChars) {
			$input.addClass(options.loadingClass);
			requestData(v);
		} else {
			$input.removeClass(options.loadingClass);
			$results.hide();
		}
	};

 	function moveSelect(step) {
		
		// Assanka change - ensure results div is created on demand
		if (!resultsdivcreated) createResultsOnDemand();
		
		var lis = jQuery("li", results);
		if (!lis) return;

		active += step;

		if (active < 0) {
			active = 0;
		} else if (active >= lis.size()) {
			active = lis.size() - 1;
		}

		lis.removeClass("ac_over");

		jQuery(lis[active]).addClass("ac_over");

		// Weird behaviour in IE
		// if (lis[active] && lis[active].scrollIntoView) {
		// 	lis[active].scrollIntoView(false);
		// }

	};

	function selectCurrent() {
		var li = jQuery("li.ac_over", results)[0];
		if (!li) {
			var $li = jQuery("li", results);
			if (options.selectOnly) {
				if ($li.length == 1) li = $li[0];
			} else if (options.selectFirst) {
				li = $li[0];
			}
		}
		if (li) {
			selectItem(li);
			return true;
		} else {
			return false;
		}
	};

	function selectItem(li) {
		if (!li) {
			li = document.createElement("li");
			li.extra = [];
			li.selectValue = "";
		}
		var v = jQuery.trim(li.selectValue ? li.selectValue : li.innerHTML);
		input.lastSelected = v;
		prev = v;
		$results.html("");
		$input.val(v);
		hideResultsNow();

		if (options.onItemSelect) setTimeout(function() { options.onItemSelect(li) }, 1);
	};

	// selects a portion of the input string
	function createSelection(start, end){
		// get a reference to the input element
		var field = $input.get(0);
		if( field.createTextRange ){
			var selRange = field.createTextRange();
			selRange.collapse(true);
			selRange.moveStart("character", start);
			selRange.moveEnd("character", end);
			selRange.select();
		} else if( field.setSelectionRange ){
			field.setSelectionRange(start, end);
		} else {
			if( field.selectionStart ){
				field.selectionStart = start;
				field.selectionEnd = end;
			}
		}
		field.focus();
	};

	// fills in the input box w/the first match (assumed to be the best match)
	function autoFill(sValue){
		// if the last user key pressed was backspace, don't autofill
		if( lastKeyPressCode != 8 ){
			// fill in the value (keep the case the user has typed)
			$input.val($input.val() + sValue.substring(prev.length));
			// select the portion of the value not typed by the user (so the next character will erase)
			createSelection(prev.length, sValue.length);
		}
	};

	function showResults() {
		// get the position of the input field right now (in case the DOM is shifted)
		var pos = findPos(input);
		// either use the specified width, or autocalculate based on form element
		var iWidth = (options.width > 0) ? options.width : $input.width();
		// reposition
		$results.css({
			width: parseInt(iWidth) + "px",
			top: (pos.y + input.offsetHeight) + "px",
			left: pos.x + "px"
		}).show();
	};

	function hideResults() {
		if (timeout) clearTimeout(timeout);
		timeout = setTimeout(hideResultsNow, 200);
	};

	function hideResultsNow() {
		// Assanka change - don't hide if no div (created on demand)
		if (!resultsdivcreated) return;
		
		if (timeout) clearTimeout(timeout);
		$input.removeClass(options.loadingClass);
		if ($results.is(":visible")) {
			$results.hide();
		}
		if (options.mustMatch) {
			var v = $input.val();
			if (v != input.lastSelected) {
				selectItem(null);
			}
		}
	};

	function receiveData(q, data) {
		if (data) {
			$input.removeClass(options.loadingClass);
			results.innerHTML = "";

			// if the field no longer has focus or if there are no matches, do not display the drop down
			if( !hasFocus || data.length == 0 ) return hideResultsNow();

			if (jQuery.browser.msie) {
				// we put a styled iframe behind the calendar so HTML SELECT elements don't show through
				$results.append(document.createElement('iframe'));
			}
			results.appendChild(dataToDom(data));
			// autofill in the complete box w/the first match as long as the user hasn't entered in more data
			if( options.autoFill && ($input.val().toLowerCase() == q.toLowerCase()) ) autoFill(data[0][0]);
			
			// Assanka change: in IE set the iframe height to the menu height.
			if (jQuery.browser.msie) $results.find("iframe").height($results.outerHeight()+4);
			
			showResults();
		} else {
			hideResultsNow();
		}
	};

	function parseData(data) {
		if (!data) return null;
		var parsed = [];
		var rows = data.split(options.lineSeparator);
		for (var i=0; i < rows.length; i++) {
			var row = jQuery.trim(rows[i]);
			if (row) {
				parsed[parsed.length] = row.split(options.cellSeparator);
			}
		}
		return parsed;
	};

	function dataToDom(data) {
		var ul = document.createElement("ul");
		var num = data.length;

		// limited results to a max number
		if( (options.maxItemsToShow > 0) && (options.maxItemsToShow < num) ) num = options.maxItemsToShow;

		for (var i=0; i < num; i++) {
			var row = data[i];
			if (!row) continue;
			var li = document.createElement("li");
			if (options.formatItem) {
				li.innerHTML = options.formatItem(row, i, num);
				li.selectValue = row[0];
			} else {
				li.innerHTML = row[0];
				li.selectValue = row[0];
			}
			var extra = null;
			if (row.length > 1) {
				extra = [];
				for (var j=1; j < row.length; j++) {
					extra[extra.length] = row[j];
				}
			}
			li.extra = extra;
			ul.appendChild(li);
			jQuery(li).hover(
				function() { jQuery("li", ul).removeClass("ac_over"); jQuery(this).addClass("ac_over"); active = jQuery("li", ul).indexOf(jQuery(this).get(0)); },
				function() { jQuery(this).removeClass("ac_over"); }
			).click(function(e) { e.preventDefault(); e.stopPropagation(); selectItem(this) });
		}
		return ul;
	};

	function requestData(q) {
		if (!options.matchCase) q = q.toLowerCase();
		var data = options.cacheLength ? loadFromCache(q) : null;
		// recieve the cached data
		if (data) {
			receiveData(q, data);
		// if an AJAX url has been supplied, try loading the data now
		} else if( (typeof options.url == "string") && (options.url.length > 0) ){
			jQuery.get(makeUrl(q), function(data) {
				data = parseData(data);
				addToCache(q, data);
				receiveData(q, data);
			});
		// if there's been no data found, remove the loading class
		} else {
			$input.removeClass(options.loadingClass);
		}
	};

	function makeUrl(q) {
		var url = options.url + "?q=" + encodeURI(q);
		for (var i in options.extraParams) {
			url += "&" + i + "=" + encodeURI(options.extraParams[i]);
		}
		return url;
	};

	function loadFromCache(q) {
		if (!q) return null;
		if (cache.data[q]) return cache.data[q];
		if (options.matchSubset) {
			for (var i = q.length - 1; i >= options.minChars; i--) {
				var qs = q.substr(0, i);
				var c = cache.data[qs];
				if (c) {
					var csub = [];
					for (var j = 0; j < c.length; j++) {
						var x = c[j];
						var x0 = x[0];
						if (matchSubset(x0, q)) {
							csub[csub.length] = x;
						}
					}
					return csub;
				}
			}
		}
		return null;
	};

	function matchSubset(s, sub) {
		if (!options.matchCase) s = s.toLowerCase();
		var i = s.indexOf(sub);
		if (i == -1) return false;
		return i == 0 || options.matchContains;
	};

	this.flushCache = function() {
		flushCache();
	};

	this.setExtraParams = function(p) {
		options.extraParams = p;
	};

	this.findValue = function(){
		var q = $input.val();

		if (!options.matchCase) q = q.toLowerCase();
		var data = options.cacheLength ? loadFromCache(q) : null;
		if (data) {
			findValueCallback(q, data);
		} else if( (typeof options.url == "string") && (options.url.length > 0) ){
			jQuery.get(makeUrl(q), function(data) {
				data = parseData(data)
				addToCache(q, data);
				findValueCallback(q, data);
			});
		} else {
			// no matches
			findValueCallback(q, null);
		}
	}

	function findValueCallback(q, data){
		if (data) $input.removeClass(options.loadingClass);

		var num = (data) ? data.length : 0;
		var li = null;

		for (var i=0; i < num; i++) {
			var row = data[i];

			if( row[0].toLowerCase() == q.toLowerCase() ){
				li = document.createElement("li");
				if (options.formatItem) {
					li.innerHTML = options.formatItem(row, i, num);
					li.selectValue = row[0];
				} else {
					li.innerHTML = row[0];
					li.selectValue = row[0];
				}
				var extra = null;
				if( row.length > 1 ){
					extra = [];
					for (var j=1; j < row.length; j++) {
						extra[extra.length] = row[j];
					}
				}
				li.extra = extra;
			}
		}

		if( options.onFindValue ) setTimeout(function() { options.onFindValue(li) }, 1);
	}

	function addToCache(q, data) {
		if (!data || !q || !options.cacheLength) return;
		if (!cache.length || cache.length > options.cacheLength) {
			flushCache();
			cache.length++;
		} else if (!cache[q]) {
			cache.length++;
		}
		cache.data[q] = data;
	};

	// Assanka change: amend by adding support for baseOffsetElement
	function findPos(obj) {
		var checkformatchingelement = false;
		var matchingelement = false;
		if (options.baseOffsetElementIdentifier != "body") {
			checkformatchingelement = true;
			matchingelement = jQuery(options.baseOffsetElementIdentifier).get(0);
		}
		var curleft = obj.offsetLeft || 0;
		var curtop = obj.offsetTop || 0;
		while ((obj = obj.offsetParent) && (!checkformatchingelement || matchingelement != obj)) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
		return {x:curleft,y:curtop};
	}
};

// Assanka change: grab a reference to current, pre-noconflict'd jQuery, by using a closure
(function( AssankaChangejQuery ){
AssankaChangejQuery.fn.autocomplete = function(url, options, data) {
	// Make sure options exists
	options = options || {};
	// Set url as option
	options.url = url;
	// set some bulk local data
	options.data = ((typeof data == "object") && (data.constructor == Array)) ? data : null;

	// Set default values for required options
	// Assanka change: certain options accept a value of 0 but OR the provided value with a non-zero default;
	// fix this by checking typeof on those occasions.
	options.inputClass = options.inputClass || "ac_input";
	options.resultsClass = options.resultsClass || "ac_results";
	options.lineSeparator = options.lineSeparator || "\n";
	options.cellSeparator = options.cellSeparator || "|";
	options.minChars = options.minChars || 1;
	options.delay = (typeof(options.delay) == "undefined") ? 400 : options.delay;
	options.matchCase = options.matchCase || 0;
	options.matchSubset = (typeof(options.matchSubset) == "undefined") ? 1 : options.matchSubset;
	options.matchContains = options.matchContains || 0;
	options.cacheLength = options.cacheLength || 1;
	options.mustMatch = options.mustMatch || 0;
	options.extraParams = options.extraParams || {};
	options.loadingClass = options.loadingClass || "ac_loading";
	options.selectFirst = options.selectFirst || false;
	options.selectOnly = options.selectOnly || false;
	options.maxItemsToShow = options.maxItemsToShow || -1;
	options.autoFill = options.autoFill || false;
	options.width = parseInt(options.width, 10) || 0;
	// Assanka change: support a different element, in order to avoid operation aborted errors
	options.baseOffsetElementIdentifier = options.baseOffsetElementIdentifier || "body";

	this.each(function() {
		var input = this;
		
		// Assanka change: alter function name to prevent noConflict/scope issues, pass in jquery ref
		new jQueryAutocomplete(AssankaChangejQuery, input, options);
	});

	// Don't break the chain
	return this;
}

AssankaChangejQuery.fn.autocompleteArray = function(data, options) {
	return this.autocomplete(null, options, data);
}

AssankaChangejQuery.fn.indexOf = function(e){
	for( var i=0; i<this.length; i++ ){
		if( this[i] == e ) return i;
	}
	return -1;
}
// Assanka change: closure end to sort out scope issues
})( jQuery );
// Reassign jQuery from $ (already used by the FT) to $jq.
var $jq = jQuery.noConflict();
if (typeof(Assanka) == "undefined") { var Assanka = {}; Assanka.$ = $jq; }

var benchvar = false;
var showtimer = false;
var hidetimer = false;
var menuhidetimer = false;
var showingprofile = false;

var sharetablesettings = {};

// On page ready, initialise the page.
$jq(document).ready(function() {
	if (!document.body.getAttribute("si:pageID") && typeof(rankingssipageid) != "undefined" && typeof(SiSetPageID) == "function") {
		SiSetPageID(rankingssipageid);
	}
	if (typeof(rankingstabledetails) != "undefined") initRankingsTable();
	$jq(".slidecontainer").each(function(i) {
		setSlideshowToAnimate($jq(this));
	});
	$jq("#waitspinner").css("display", "none");
});


// Collapse or expand the container holding the search filter lists
function toggleSearchFilters() {
	var controlele = $jq('#'+((rankingsstyle == 'falcon')?'falcon':'')+'collapseexpandfilters');
	if (controlele.html() == "Show advanced search filters") {
		controlele.addClass("expanded").html("Hide advanced search filters");
		$jq("#searchfilters").show();
	} else {
		controlele.removeClass("expanded").html("Show advanced search filters");
		$jq("#searchfilters").hide();
	}
	controlele.get(0).blur();
	repositionRankingsTable();
}

// Show or hide the previous sequence comparison information
function toggleCompareToPrevious() {
	var enablecompare = $jq('#comparetopreviouscheckbox').attr('checked');
	if (enablecompare) {
		$jq("#rankingstablediv").addClass('comparetopreviouswrapper');
	} else {
		$jq("#rankingstablediv").removeClass('comparetopreviouswrapper');
	}
}

// Collapse or expand the container holding the field toggle checkboxes
function toggleRankingsControls() {
	var controlele = $jq("#collapseexpandcontrol");
	if (controlele.html() == "Show all available fields") {
		controlele.addClass("expanded").html("Show featured fields");
		$jq(".fieldhidden", $jq("#columncontrol")).show();
	} else {
		controlele.removeClass("expanded").html("Show all available fields");
		$jq(".fieldhidden", $jq("#columncontrol")).hide();
	}
	controlele.get(0).blur();
	repositionRankingsTable();
}

// Show a column as a result of checking the control.  Mark the column as visible and redraw the table.
function showRankingsColumn(columnid) {
	if (!rankingstabledetails.loaded) initRankingsTable();

	// Log an event
	logActionToWebtrends("addcolumn", rankingstabledetails.columns[columnid].title);

	rankingstabledetails.activecolumns[rankingstabledetails.columns[columnid].colnum] = columnid;
	startWaiting("Adding new column");
	setTimeout(recreateRankingsTable, 100);
}

// Hide a column, either as a result of closing the column via the "X" or unchecking a control.
// Update the interface if necessary, mark the column as hidden, and redraw the table.
function hideRankingsColumn(e, columnid) {
	if (e !== false) {
		if (!e) var e = window.event;
		if (e) {
			e.cancelBubble = true;
			if (e.stopPropagation) e.stopPropagation();
		}
	}
	var controlele = $jq("#field"+columnid);
	var listele = controlele.parent().parent();
	if (!rankingstabledetails.loaded) initRankingsTable();

	// Log an event
	logActionToWebtrends("removecolumn", rankingstabledetails.columns[columnid].title);

	delete(rankingstabledetails.activecolumns[rankingstabledetails.columns[columnid].colnum]);
	if (controlele.attr("checked")) {
		listele.addClass("fieldoff").removeClass("fieldon");
		controlele.uncheck();
	}
	startWaiting("Removing column");
	setTimeout(recreateRankingsTable, 100);
}

// Called as a result of a column control being toggled.  Update the interface to match, and call the
// appropriate action function.
function toggleFieldControl(columnid) {
	var controlele = $jq("#field"+columnid);
	var listele = controlele.parent().parent();
	if (controlele.attr("checked")) {
		listele.addClass("fieldon").removeClass("fieldoff");
		showRankingsColumn(columnid);
	} else {
		listele.addClass("fieldoff").removeClass("fieldon");
		hideRankingsColumn(false, columnid);
	}
}

// Called as a result of the user clicking in a table header or on the sort control
function sortRankingsTable(columnid) {
	if (!rankingstabledetails.loaded) initRankingsTable();
	if ($jq("#waitspinner").css("display")=="none") {
		startWaiting("Sorting");
		setTimeout("sortRankingsTable("+columnid+")", 100);
		return false;
	}

	// Determine sort direction (either last used for col or opposite of current sort)
	var alreadysorted = rankingstabledetails.activecolumns[rankingstabledetails.cursort]==columnid;
	if (alreadysorted) {
		var sortdir = ($jq("#th"+columnid).is(".ascsort")) ? "desc" : "asc";
	} else {
		var sortdir = rankingstabledetails.columns[columnid].sort;
	}
	var columndefaultsort = rankingstabledetails.columns[columnid].initsort;

	// If pagination is enabled, submit a new request to the server
	if (enablepagination) {
		window.location = '/'+rankingseriesslug+'/'+rankingslug+'?sortcol='+columnid+'&sortdir='+sortdir+'&search='+$jq("#rankingssearchtext").val()+'&fields='+fetchActiveColIDs().join('|');
		return false;
	}

	// Log an event
	logActionToWebtrends("sort", rankingstabledetails.columns[columnid].title+" ("+sortdir+")");

	// Set global sort parameters for visual effects when redrawing the table
	rankingstabledetails.cursort = rankingstabledetails.columns[columnid].colnum;
	rankingstabledetails.columns[columnid].sort = sortdir;

	// Perform sort
	var type = rankingstabledetails.columns[columnid].type;
	if (type == "text") {
		rankingstabledetails.table.sort(rtSortText);
	} else if (type == "numberwithmeta") {
		rankingstabledetails.table.sort(rtSortNumericWithMeta);
	} else {
		rankingstabledetails.table.sort(rtSortNumeric);
	}

	// Redraw the table
	recreateRankingsTable();

	// Sort callbacks
	// Alphabetic sort for text, numeric sort for all numbers.  Formatted
	// number and regular number can use same sort callback, since in each
	// case we're just interested in the numeric part of the string.
	// Number-with-meta needs a slightly different preprocessing function so
	// it gets it's own sort callback.  Final note: Numeric sorts are
	// overridden if one of the values is non-numeric, forcing those
	// rows to the bottom of the table.
	function rtSortText(a,b) {
		var x = a[rankingstabledetails.cursort].val;
		var y = b[rankingstabledetails.cursort].val;
		var ret = ((x<y)?-1 : ((x>y)?1:0));
		return (sortdir=="desc") ? -1 * ret : ret;
	}
	function rtSortNumeric(a,b) {
		var x = a[rankingstabledetails.cursort].val.replace(/\<em.*/i,'').replace(/[^0-9\.]/g, "");
		var y = b[rankingstabledetails.cursort].val.replace(/\<em.*/i,'').replace(/[^0-9\.]/g, "");
		var ret = x-y;
		if ((x === "" || isNaN(x)) && (y !== "" && !isNaN(y))) ret = (columndefaultsort=="desc") ? -1 : 1;
		if ((y === "" || isNaN(y)) && (x !== "" && !isNaN(x))) ret = (columndefaultsort=="desc") ? 1 : -1;
		if ((y === "" || isNaN(y)) && (x === "" || isNaN(x))) ret = 0;
		return (sortdir=="desc") ? -1 * ret : ret;
	}
	function rtSortNumericWithMeta(a,b) {
		var x = a[rankingstabledetails.cursort].val.replace(/\<em.*/i,'').replace(/^([0-9\.]+)[\s\(].*$/, "$1");
		var y = b[rankingstabledetails.cursort].val.replace(/\<em.*/i,'').replace(/^([0-9\.]+)[\s\(].*$/, "$1");
		var ret = x-y;
		if ((x === "" || isNaN(x)) && (y !== "" && !isNaN(y))) ret = (columndefaultsort=="desc") ? -1 : 1;
		if ((y === "" || isNaN(y)) && (x !== "" && !isNaN(x))) ret = (columndefaultsort=="desc") ? 1 : -1;
		if ((y === "" || isNaN(y)) && (x === "" || isNaN(x))) ret = 0;
		return (sortdir=="desc") ? -1 * ret : ret;
	}
}

function searchRankings() {

	// Check the advanced filters, if present, and reset the activefilters as appropriate
	// rankingstabledetails.filters maps the filter select offset to the column ID filtered by that box
	if (rankingstabledetails.filters) {
		rankingstabledetails.activefilters = {length:0};

		// For each filter list, fetch all the options
		for (var i=rankingstabledetails.filters.length; i>=0; i--) {
			var selecteditems = new Array();
			var filteroptions = $jq("option", $jq("#filterlist"+rankingstabledetails.filters[i]));

			// For each option, collate all the selected ranges into an array
			// Each option's value will be either a range in the form low|high or a single value
			for (var j=filteroptions.length-1; j>=0; j--) {
				if (filteroptions[j].selected) {
					var filtervalue = filteroptions[j].value;
					filtervalue = filtervalue.split("|");
					if (filtervalue.length == 2) {
						var filterout = {low:parseFloat(filtervalue[0]), high:parseFloat(filtervalue[1]), val:false};
					} else {
						var filterout = {low:false, high:false, val:parseFloat(filtervalue[0])};
					}
					selecteditems[selecteditems.length] = filterout;
				}
			}

			// Save the selected ranges against the relevant column
			if (selecteditems.length && selecteditems.length != filteroptions.length) {
				rankingstabledetails.activefilters[rankingstabledetails.filters[i]] = selecteditems;
				rankingstabledetails.activefilters.length++;
			}
		}
	}

	$jq(".rankingssearchsubmit").get(0).blur();
	$jq(".rankingsadvsearchsubmit").get(0).blur();
	$jq("#advsearchpreview").html("");
	var q = $jq("#rankingssearchtext").val();
	if (!q.length && !rankingstabledetails.activefilters.length) {
		alert("Please enter a search word or phrase");
		$jq("#rankingssearchtext").get(0).focus();
		return false;
	}

	// If pagination is enabled, submit a new request to the server
	if (enablepagination) {
		window.location = '/'+rankingseriesslug+'/'+rankingslug+'?sortcol='+rankingstabledetails.activecolumns[rankingstabledetails.cursort]+'&sortdir='+rankingstabledetails.columns[rankingstabledetails.activecolumns[rankingstabledetails.cursort]].sort+'&search='+q+'&fields='+fetchActiveColIDs().join('|');
		return false;
	}

	if (q) {

		// Send to webtrends if the search string has changed
		var querystrings = getQueryStrings();
		if (!querystrings["search"] || querystrings["search"].replace(/\+/g, " ") != q) {
			logActionToWebtrends("search", q);
		}

		$jq(".rankingssearchreset").css("display", "inline");
		$jq("#rankingssearchtext").css("background-color", "#FFC");
		rankingstabledetails.filter = q.replace(/[^\w ]/gi, "").replace(/^\s+|\s+$/g, '').toLowerCase();
	} else {
		rankingstabledetails.filter = "";
		$jq(".rankingssearchreset").css("display", "none");
		$jq("#rankingssearchtext").css("background-color", "#FFF");
	}

	startWaiting("Searching");
	setTimeout(recreateRankingsTable, 100);
	return false;
}

function resetRankingSearch(resetsearchtext, resetadvfilters) {
	if (typeof(resetsearchtext) == "undefined") resetsearchtext = true;
	if (typeof(resetadvfilters) == "undefined") resetadvfilters = true;

	// If pagination is enabled, submit a new request to the server
	if (enablepagination) {
		window.location = '/'+rankingseriesslug+'/'+rankingslug+'?sortcol='+rankingstabledetails.activecolumns[rankingstabledetails.cursort]+'&sortdir='+rankingstabledetails.columns[rankingstabledetails.activecolumns[rankingstabledetails.cursort]].sort+'&fields='+fetchActiveColIDs().join('|');
		return false;
	}

	if (resetsearchtext) {
		$jq(".rankingssearchreset").hide();
		rankingstabledetails.filter = false;
		$jq(".rankingssearchreset").css("display", "none");
		$jq("#rankingssearchtext").css("background-color", "#FFF");
	}

	if (resetadvfilters && rankingstabledetails.filters) {
		rankingstabledetails.activefilters = {length:0};
		for (var i=rankingstabledetails.filters.length; i>=0; i--) {
			$jq("option", $jq("#filterlist"+rankingstabledetails.filters[i])).attr("selected", false);
		}
		$jq("select.filterlistselect option").css("color", "menutext").each(function() { this.disabled = false });
		$jq("#advsearchpreview").html("");
	}

	startWaiting("Clearing search");
	setTimeout(recreateRankingsTable, 100);
	return false;
}

function updateAdvancedFilters() {

	// Get all options and current selections from filter boxes
	var filters = new Object();
	for (var i=rankingstabledetails.filters.length-1; i>=0; i--) {
		var filteroptions = $jq("option", $jq("#filterlist"+rankingstabledetails.filters[i]));
		filters[rankingstabledetails.filters[i]] = {numselected:0};
		filters[rankingstabledetails.filters[i]].opts = new Array(); // "The filter for column n has these options"

		// For each option, collate all the available ranges
		// Each option's value will be either a range in the form low|high or a single value
		for (var j=filteroptions.length-1; j>=0; j--) {
			var filtervalue = filteroptions[j].value;
			filtervalue = filtervalue.split("|");
			if (filtervalue.length == 2) {
				var opt = {low:parseFloat(filtervalue[0]), high:parseFloat(filtervalue[1]), val:false};
			} else {
				var opt = {low:false, high:false, val:parseFloat(filtervalue[0])};
			}
			opt.selected = filteroptions[j].selected;
			if (opt.selected) filters[rankingstabledetails.filters[i]].numselected++;
			filters[rankingstabledetails.filters[i]].opts[j] = opt;
		}
	}

	// Get list of rows that match current selections
	var itemcount = rankingstabledetails.table.length;
	var validrowcount = 0;
	var colmap = new Array();
	for (var key in rankingstabledetails.columns) colmap[colmap.length] = key;
	for (var i=0; i<itemcount; i++) {
		var rowitems = rankingstabledetails.table[i];
		var rowitemlength = rowitems.length;
		var filtermatchfail = false;
		var optsmatched = new Object();
		for (var j=1; j<rowitemlength; j++) {
			if (filters[colmap[j-1]]) {
				var advfiltermatched = false;
				var celldata = rowitems[j].val;
				celldata = celldata.replace(/^([\-0-9\.]+)[\s?\(].*$/, "$1");
				celldata = celldata.replace(/[^\-0-9\.]/g, "");
				celldata = parseFloat(celldata);
				optsmatched[j-1] = new Object();
				var filtertocheck = filters[colmap[j-1]].opts;
				for (var k=0; k<filtertocheck.length; k++) {
					var v = filtertocheck[k];
					if (v.val === false) {
						if (celldata <= v.high && celldata >= v.low) {
							if (v.selected) advfiltermatched = true;
							optsmatched[j-1][k] = true;
						}
					} else {
						if (celldata == v.val) {
							if (v.selected) advfiltermatched = true;
							optsmatched[j-1][k] = true;
						}
					}
				}
				if (filters[colmap[j-1]].numselected && filters[colmap[j-1]].numselected != filters[colmap[j-1]].opts.length && !advfiltermatched) {
					filtermatchfail = true;
					break;
				}
			}
		}
		if (!filtermatchfail) {
			validrowcount++;
			for (coloffset in optsmatched) {
				for (optionoffset in optsmatched[coloffset]) {
					if (optsmatched[coloffset][optionoffset]) filters[colmap[coloffset]].opts[optionoffset].matched=true;
				}
			}
		}
	}
	$jq("#advsearchpreview").html("Your new selections match "+validrowcount+" entr"+((validrowcount==1)?"y":"ies")+".  Click apply to update the table.");

	// Grey out options in unused select boxes that would yield zero results
	for (var colid in filters) {
		if (filters[colid].numselected) {
			$jq("option", $jq("#filterlist"+colid)).each(function() { this.disabled=false });
		} else {
			for (var i=0; i<filters[colid].opts.length; i++) {
				$jq("#filterlist"+colid+" option").get(i).disabled = (filters[colid].opts[i].matched) ? false : true;
				$jq("#filterlist"+colid+" option").eq(i).css("color", (filters[colid].opts[i].matched) ? "menutext" : "graytext");
			}
		}
	}
}

function compareRankings() {
	$jq("#notepopup").hide();
	if (showtimer) clearTimeout(showtimer);
	if (hidetimer) clearTimeout(hidetimer);
	rankingstabledetails.compareEnabled = (rankingstabledetails.compareEnabled) ? 0 : 1;
	var numtocompare = 0;
	if (rankingstabledetails.compareEnabled) {
		for (var i=(rankingstabledetails.table.length-1); i>=0; i--) {
			if (rankingstabledetails.table[i][0].val.indexOf("checked=\"checked") != -1) numtocompare++;
		}
		if (!numtocompare) {
			alert("You must tick one or more rows to compare before clicking the compare button");
			rankingstabledetails.compareEnabled = 0;
			return false;
		} else {

			// Log an event
			logActionToWebtrends("compare", numtocompare+" rows");
		}
	}
	startWaiting("Please wait");
	var paginationArea = $jq('.tablenav');
	if (paginationArea) {
		if (rankingstabledetails.compareEnabled) paginationArea.parent().hide();
		else paginationArea.parent().show();
	}
	setTimeout(recreateRankingsTable, 100);
}

function toggleCompareState(evt) {
	var chk = evt.target;
	var el = chk;
	var rowindex = 0;
	while (el.tagName!="TR") el = el.parentNode;
	if (el.id.substr(0,9)=='rowoffset') {
		rowindex = el.id.substr(9);
	} else {
		while (el = el.previousSibling) if (el.tagName=="TR") rowindex++;
	}
	rankingstabledetails.table[rowindex][0].val = "<input type=\"checkbox\" name=\"comp\" class=\"compcheck\""+((chk.checked)?" checked=\"checked\"":"")+" />";
}

function startWaiting(str) {
	var wh = (self.innerHeight) ? self.innerHeight : document.documentElement.clientHeight;
	var y = (self.pageYOffset) ? self.pageYOffset : document.documentElement.scrollTop;
	var x = (self.pageXOffset) ? self.pageXOffset : document.documentElement.scrollLeft;
	$jq("#waitspinner div").html(str);
	$jq("#waitspinner").css({top:(y+(wh/2))+'px',left:(x+365)+'px',display:'block'});
}

// Read in the rankings table and construct a javascript array of all the values for easy rebuilds.
function initRankingsTable() {
	if (rankingstabledetails.loading) return;
	rankingstabledetails.loading = true;

	// Create the note popup bubble
	createNoteBubble();

	// Remove accessible note markers
	$jq("sup", "#rankingstable").remove();

	// Initialise table data structure
	rankingstabledetails.notetexts = new Array();
	rankingstabledetails.onmouseovers = new Array();
	rankingstabledetails.headerdescs = new Array();
	rankingstabledetails.activecolumns = new Array();
	rankingstabledetails.table = new Array();
	rankingstabledetails.filters = new Array();
	rankingstabledetails.activefilters = {length:0};

	// Load notes into memory (located at end of HTML source)
	$jq(".notes p").each(function(i) {
		var ele = $jq(this);
		var note = $jq(this).html().replace(/^[0-9]+\.\s+/, "");
		rankingstabledetails.notetexts[i+1] = note;
	});

	// Load note index from inline JS in HTML source
	var notes = rankingstabledetails.notes;

	// Store default sort orders
	for (var key in rankingstabledetails.columns) {
		if (rankingstabledetails.columns[key].sort) rankingstabledetails.columns[key].initsort = rankingstabledetails.columns[key].sort;
	}

	// Establish array of active columns, and mark sort column
	// Note the use of i (column offset) and colid (unique field id from db)
	// Read column header metadata from source
	var idstring;
	var jstablehead = new Array();
	var tableheadings = $jq("#rankingstable thead").get(0).childNodes;
	for (var i=tableheadings[0].childNodes.length-1; i>=0; i--) {
		var el = tableheadings[0].childNodes[i];
		idstring = el.id;
		if (idstring) {
			colid = idstring.substring(2);
			if (colid == rankingstabledetails.entityfield) rankingstabledetails.activecolumns[i] = colid;
			if ($jq("#field"+colid).attr("checked")) rankingstabledetails.activecolumns[i] = colid;
		}
		if ($jq(el).hasClass("cursort") || $jq(el).hasClass("cursortpreend")) rankingstabledetails.cursort = i;
		rankingstabledetails.headerdescs[i] = el.title;
		el.title = "";
		rankingstabledetails.onmouseovers[i] = el.onmouseover;
		jstablehead[i] = el.innerHTML;
	}
	rankingstabledetails.headings = jstablehead.slice(0);

	// Prepare to create a table based on the cells present in the HTML source
	var jstable = new Array();

	// Iterate over all the rows in the table
	$jq("#rankingstable tbody tr").each(function(i) {
		var tablerow = jstable[i] = new Array();
		var rowele = $jq(this).get(0);
		var rowitems = rowele.childNodes;

		// Iterate over the cells in the row
		for (var j=rowitems.length-1; j>=0; j--) {
			tablerow[j] = {val:rowitems[j].innerHTML};

			// If the row has a note (looked up from note index) add it to the row object in memory
			if (notes[i] && notes[i][j]) tablerow[j].noteid = notes[i][j];
		}

		// Add the entity id to the comparison cell
		if (rowele.id) tablerow[0].id = rowele.id.substring(3);
	});

	// Construct the whole table by copying the jstable array, excluding the last row (comparison row)
	rankingstabledetails.table = jstable.slice(0, jstable.length-1);

	// Read in any filters
	if ($jq("#searchfilters").length) {
		var filterlists = $jq(".filterlistselect", $jq("#searchfilters"));
		for (var i=filterlists.length - 1; i>=0; i--) {
			var filterid = filterlists[i].id;
			filterid = filterid.substring("filterlist".length);
			rankingstabledetails.filters[i] = filterid;
		}
	}

	// Set up event handlers
	$jq("#footcompa").click(compareRankings);
	$jq("#compcolheader").click(compareRankings);
	$jq("#rankingstable input.compcheck").click(toggleCompareState);
	$jq("select.filterlistselect").change(updateAdvancedFilters);

	$jq(".featuredicon").each(function() {
		var oldtitle = $jq(this).attr("title");
		var dispnote = displayNoteBubble('<p>'+oldtitle+'</p>', $jq(this).get(0));
		$jq(this).attr("title", "");
		$jq(this).mouseover(function() { showtimer = window.setTimeout(dispnote, 50); }).mouseout(hideRankingsNotes);
	});

	// Reposition the table if the default view is too wide.
	if ($jq("#rankingstable").get(0).offsetWidth > (rankingsstyle == 'falcon')?590:658) repositionRankingsTable();

	// Done
	rankingstabledetails.loaded = true;

	// Update checked boxes
	$jq("#rankingstable input.compcheck:checked").each(function(i) {
		toggleCompareState({target:$jq(this).get(0)});
	});

	// Amend any pagination links
	$jq(".tablenav a").each(function(i) {
		$jq(this).click(function() { followPaginationLink($jq(this).get(0)); return false });
	});

	// Trigger a search if one is provided on querystring
	var querystrings = getQueryStrings();
	if (querystrings["search"] && !enablepagination) searchRankings();
}

// Function to parse notes on the entities table page and set up any intra-page ranking navigation.
function initProfileTables() {
	if (typeof(profiletables) == "undefined" || profiletables.loading) return;
	profiletables.loading = true;
	var notetexts = {};
	var notes = profiletables.notes;
	$jq('#locallink-'+rankingtoshow).css("font-weight", "bold");

	// Create the notes popup bubble
	createNoteBubble();

	// Move the nav menu to the body element
	if ($jq('#rankingnavmenu').length) {
		$jq('#rankingnavmenu').appendTo(document.body);
		$jq(".rankingtitlearea").addClass("rankingnavpadding");
	}

	// Step through any available entityrankingsdata divs
	$jq("div.entityrankingsdata").each(function(i) {
		var thisrankingdiv = $jq(this);

		// In each div, find any notes, and add them to the notetexts array
		$jq(".notes p", thisrankingdiv).each(function(j) {
			var note = $jq(this).html().replace(/^[0-9]+\.\s+/, "");
			notetexts['table'+i+'data'+j] = note;
		});

		// Select the data keys, select their titles, and add them to the notetexts array
		$jq("td.headcol", thisrankingdiv).each(function(j) {
			var ele = $jq(this).get(0);
			var fieldnote = '';
			if (ele.title) {
				fieldnote = ele.title;
				ele.title = '';
			}
			if (typeof(notes[i]) != "undefined" && typeof(notes[i][j]) != "undefined") {
				if (fieldnote) fieldnote += '<br /><br />';
				fieldnote += notetexts['table'+i+'data'+notes[i][j]];
			}
			if (fieldnote) {
				$jq(ele).addClass('tnote');
				notetexts['table'+i+'col'+j] = fieldnote;
			}
		});
	});

	// Switch to profile if set
	if (document.location.hash && document.location.hash == '#profile' && $jq('.rankingprofiledata').length) {
		$jq('.entitytablecontainer').hide();
		$jq('.rankingprofiledata').show();
		$jq('.profiletab').addClass('selected').addClass('active');
		showingprofile = true;

	} else {
		showingprofile = false;
		$jq('.datatab').addClass('selected').addClass('active');

		// Select a different ranking if set
		if (document.location.hash && $jq('#entityranking'+document.location.hash.substring(1)).length) {
			profileSwitchToRanking(document.location.hash.substring(1));
		}

	}

	profiletables.notetexts = notetexts;
	profiletables.loaded = true;
}

// Initialise additional notes where javascript is not already being called.
function initNoteData() {

	// Create the notes popup bubble
	createNoteBubble();

	$jq(".featuredicon").each(function() {
		var oldtitle = $jq(this).attr("title");
		var dispnote = displayNoteBubble('<p>'+oldtitle+'</p>', $jq(this).get(0));
		$jq(this).attr("title", "");
		$jq(this).mouseover(function() { showtimer = window.setTimeout(dispnote, 50); }).mouseout(hideRankingsNotes);
	});
}

// Switch to hightlight a different ranking on a profile page
function profileSwitchToRanking(slug) {
	if (menuhidetimer) clearTimeout(menuhidetimer);

	if (showingprofile) {
		$jq('.rankingprofiledata').hide();
		$jq('.entitytablecontainer').show();
		$jq('.profiletab').removeClass('selected').removeClass('active');
		$jq('.datatab').addClass('selected').addClass('active').children().get(0).blur();
		showingprofile = false;
	}

	$jq('#entityranking'+rankingtoshow).hide();
	$jq(".rankingtitleh2 span", $jq("#entityranking"+rankingtoshow)).css("background-color", "#F2F2F2");
	$jq("#rankingnavmenu").hide();
	$jq('#locallink-'+rankingtoshow).css("font-weight", "normal");
	rankingtoshow = slug;
	$jq('#entityranking'+slug).show();
	$jq('#locallink-'+slug).css("font-weight", "bold");
	window.location.hash = slug;
}

// Show the profile view
function profileViewProfileData() {
	if (showingprofile) return;

	$jq('.entitytablecontainer').hide();
	$jq('.rankingprofiledata').show();
	$jq('.datatab').removeClass('selected').removeClass('active');
	$jq('.profiletab').addClass('selected').addClass('active').children().get(0).blur();
	showingprofile = true;
	window.location.hash = 'profile';
}

// Show and position the navigation rankings menu
function showRankingNavMenu(slug, seqid) {
	if (menuhidetimer) clearTimeout(menuhidetimer);
	var themenu = $jq("#rankingnavmenu");
	if (themenu.css("display") == "block") return;
	seqid = 'navmenusequence-'+seqid;

	// Set the initial position of the menu
	var initialposition = $jq("#entityranking"+slug+" .rankingsmenulink").offset();
	themenu.css({left:"1px", top:initialposition.top+"px", width:"530px", visibility:"hidden", display:"block"});

	// Step through the menu items to calculate negative height offset and new width
	var menuwidth = 0;
	var activemenufound = false;
	var heightoffset = 0;
	$jq("a", themenu).each(function() {
		if ($jq(this).attr('id') == seqid) {
			$jq(this).addClass("active").addClass("initialhover").mouseout(function() { $jq(this).removeClass("initialhover"); });
			activemenufound = true;
		} else {
			if (!activemenufound) heightoffset += $jq(this).parent().height();
			$jq(this).removeClass("active").removeClass("initialhover");
		}
		var itemwidth = $jq("span", $jq(this)).width();
		if (itemwidth) menuwidth = Math.max(menuwidth, itemwidth);
	});
	var targetwidth = (menuwidth && menuwidth < 530)?menuwidth+40:530;
	var leftoffset = ((rankingsstyle == 'falcon')?$jq('#page-container').get(0).offsetLeft+22:8);
	themenu.css({left:(initialposition.left-menuwidth+119)+"px", top:(initialposition.top - (heightoffset/2) - ((rankingsstyle == 'falcon')?6:5))+"px", width:targetwidth+"px", visibility:"visible"});
}

// Hide the navigation rankings menu on mouseout.
function profileRankingMenuMouseout() {
	menuhidetimer = window.setTimeout(function() {
		$jq("#rankingnavmenu").hide();
	}, 300);
}

// Output a new rankings table from the javascript array, based on column selection, search criteria and compare settings
function recreateRankingsTable() {
	$jq("#rankingstable").removeClass("initialrender");

	// Create local vars for rapid lookups
	var tablebody = $jq("#rankingstable tbody");
	var colmap = new Array();
	var newtableop = new Array();
	var rankingstableitems = rankingstabledetails.table;
	var activecols = rankingstabledetails.activecolumns;
	var sortcol = rankingstabledetails.cursort;
	var itemcount = rankingstableitems.length;
	var rowitemlength = rankingstabledetails.headings.length;
	var entitycolid = rankingstabledetails.entityfield;
	var visiblecolcount = 1;
	var columnclasses = new Array();
	newtableop.push("<thead><tr><th class=\"compcol"+((sortcol==1)?" presort":"")+"\" onmouseout=\"hideRankingsNotes()\" onmouseover=\"showNote(event);\">"+rankingstabledetails.headings[0]+"</th>");

	// Build up a column map of column ids to indexes.  Previously marked as AB review, so: AB:REVIEW
	// Add a zero-column for the checkboxes
	for (var key in rankingstabledetails.columns) {
		colmap[colmap.length] = key;
	}

	for (var i=1; i<=rowitemlength; i++) {
		if (!isNaN(activecols[i])) {
			newtableop.push("<th style=\"text-align: left;\""+((i == sortcol)?" class=\"cursort "+rankingstabledetails.columns[activecols[i]].sort+"sort\"":"")+" onclick=\"sortRankingsTable("+activecols[i]+")\" onmouseout=\"hideRankingsNotes()\" id=\"th"+activecols[i]+"\">"+rankingstabledetails.headings[i]+"</th>");
			visiblecolcount++;

			var thiscolclasses = new Array();
			if (rankingstabledetails.columns[activecols[i]].type == "text" || activecols[i] == entitycolid) thiscolclasses.push("text");
			if (i == sortcol) thiscolclasses.push("cursort");
			columnclasses[i] = thiscolclasses.join(" ");
		}
	}

	newtableop.push("</tr></thead><tbody>");
	var oprowcount = 0;
	var shaderow = false;
	for (var i=0; i<itemcount; i++) {
		if (!rankingstabledetails.compareEnabled || rankingstableitems[i][0].val.indexOf("checked=\"checked") != -1) {
			var rowitems = rankingstableitems[i];
			var filtermatch = (rankingstabledetails.filter || rankingstabledetails.activefilters.length) ? false : true;
			var filtermatchfail = false;

			// First cell in the row always contains a checkbox for comparisons
			var tablerowop = "<tr"+((shaderow)?" class=\"shade\"":"")+" id=\"rowoffset"+i+"\"><th"+((rankingstabledetails.compareEnabled)?" class=\"compareenabled\"":"")+">"+rowitems[0].val+"</th>";
			var searchtext = new String();
			for (var j=1; j<rowitemlength && !filtermatchfail; j++) {
				if (!filtermatch || rankingstabledetails.activefilters[colmap[j-1]]) {
					var celldata = rowitems[j].val;
					if (rankingstabledetails.filter) {
						searchtext = celldata.replace(/(<([^>]+)>)/ig,"").replace(/[^\w ]/gi, "").toLowerCase();
						if (searchtext.indexOf(rankingstabledetails.filter) != -1) filtermatch = true;
					} else {
						filtermatch = true;
					}
					if (rankingstabledetails.activefilters[colmap[j-1]]) {
						var advfiltermatched = false;
						celldata = celldata.replace(/\<em.*/i,'').replace(/^([\-0-9\.]+)[\s?\(].*$/, "$1");
						celldata = celldata.replace(/[^\-0-9\.]/g, "");
						celldata = parseFloat(celldata);
						var filtertocheck = rankingstabledetails.activefilters[colmap[j-1]];
						for (var k=0; k<filtertocheck.length; k++) {
							var v = filtertocheck[k];
							if (v.val === false) {
								if (celldata <= v.high && celldata >= v.low) advfiltermatched = true;
							} else {
								if (celldata == v.val) advfiltermatched = true;
							}
						}
						if (!advfiltermatched) {
							filtermatchfail = true;
							break;
						}
					}
				}
				if (!isNaN(activecols[j])) {
					if (!isNaN(rowitems[j].noteid)) {
						tablerowop += "<td class=\""+columnclasses[j]+" tnote\" onmouseover=\"showNote(event, "+rowitems[j].noteid+")\" onmouseout=\"hideRankingsNotes(event)\">"+rowitems[j].val+"</td>";
					} else {
						var colclass = columnclasses[j];
						tablerowop += "<td"+((colclass)?" class=\""+colclass+"\"":"")+">"+rowitems[j].val+"</td>";
					}
				}
			}
			tablerowop += "</tr>";

			// Only add the completed row to the output if it matches the active search filter (or if there isn't one)
			if (filtermatch && !filtermatchfail) {
				newtableop.push(tablerowop);
				oprowcount++;
				shaderow = !shaderow;
			}
		}
	}

	// Write table footer and render new DOM
	if (oprowcount) {
		newtableop.push("<tr class=\"comprow\"><td class=\"compcol\" colspan=\""+(activecols.length+2)+"\"><span></span><a href=\"javascript:saveAsPDF();\" class=\"pdf\">Download this view as a PDF</a> <a href=\"javascript:saveAsExcel();\" class=\"excel\">Output this view to Excel</a>"+((!rankingstabledetails.compareEnabled || !enablecharts)?"":" <a href=\"javascript:showChartOfCurrentView();\" id=\"tablechartlink\">View this comparison on a chart</a>")+" <a href=\"javascript:void(0);\" onmouseover=\"showNote(event);\" onmouseout=\"hideRankingsNotes();\" id=\"footcompa\"> </a></td></tr>");
		var htmlout = "<table id=\"rankingstable\">"+newtableop.join("")+"</tbody></table>";
	} else {
		var htmlout = "<table id=\"rankingstable\">"+newtableop.join("")+"<tr><td colspan=\""+visiblecolcount+"\" style=\"font-style:italic; text-align: center\">No entries match your search.  <a href=\"javascript:void(0)\" onclick=\"resetRankingSearch()\">Reset?</a></td></tr></tbody></table>";
	}
	$jq('#rankingstablediv').html(htmlout);
	repositionRankingsTable();

	// Re-map mouseover events (AB: ick)
	for (var key in rankingstabledetails.activecolumns) {
		if (typeof(rankingstabledetails.activecolumns[key]) == "undefined") continue;
		$jq("#th"+rankingstabledetails.activecolumns[key]).mouseover(rankingstabledetails.onmouseovers[key]);
	}

	// If a compare is active, disable comparison checkboxes
	if (rankingstabledetails.compareEnabled) {
		$jq("input.compcheck").attr("disabled", "disabled");
	} else {
		$jq("input.compcheck").click(toggleCompareState);
	}
	$jq("#footcompa").click(compareRankings);
	$jq("#compcolheader").click(compareRankings);
	$jq("#waitspinner").css("display", "none");

}

// Display a note bubble with text appropriate to the source element and note reference ID
function showNote(e, noteref) {
	if (!$jq("#notepopup").length) return;
	if ((typeof(rankingstabledetails) != "undefined" && !rankingstabledetails.loaded) || (typeof(profiletables) != "undefined" && !profiletables.loaded)) return;
	var el = getEventSrc(e);
	var notestr = new String();

	// Work out the correct note target if possible by walking up the tree to a TH/TD.
	var hovertarget = el;
	var parTag = el.parentNode.tagName;
	if (el.id != "footcompa") {
		if (el.tagName == "STRONG" || parTag == "TH" || parTag == "TD" || parTag == "LABEL") hovertarget = el.parentNode;
		parParTag = el.parentNode.parentNode.tagName;
		if ((parTag == "DIV" || parTag == "EM") && (parParTag == "TH" || parParTag == "TD" || parParTag == "LABEL")) hovertarget = el.parentNode.parentNode;
	}

	// Work out what kind of note is required...
	if (typeof(profiletables) == "undefined") {

		/* Rankings table page */

		// Advanced filter note
		if (hovertarget.id == "advfiltershelp") {
			notestr = "<p>The advanced search filters can be used to narrow down your results.  Select values and trigger the search to see only entries that match the selected values.</p><p>Click or click and drag to select items in the lists.  To select separate items in the list, or to deselect items, hold down the "+((navigator.platform.toLowerCase().indexOf("mac") != -1)?"Command (Apple)":"Control")+" key and click on the item.</p>";

		// Cell note
		} else if (hovertarget.tagName=="TD" && hovertarget.parentNode.parentNode.parentNode.id=="rankingstable") {
			notestr = "<p>"+rankingstabledetails.notetexts[noteref]+"</p>";

		// Control box note
		} else if (hovertarget.tagName=="LABEL" && hovertarget.parentNode.parentNode.id=="columncontrollist") {
			var col = rankingstabledetails.columns[noteref];
			notestr = "<strong>"+col.title+"</strong>";
			if (col.noteref) notestr += "<p>"+rankingstabledetails.notetexts[col.noteref]+"</p>";
			notestr += "<p><em>Click to "+((rankingstabledetails.activecolumns[noteref])?"remove this column from":"add this column to")+" the table.</em></p>";

		// Filter area
		} else if (hovertarget.className == "filterlist") {
			var col = rankingstabledetails.columns[noteref];
			notestr = "<strong>"+col.title+"</strong>";
			if (col.noteref) notestr += "<p>"+rankingstabledetails.notetexts[col.noteref]+"</p>";

		// Comparison column button note
		} else if (el.id == "footcompa" || (el.tagName=="A" && el.parentNode.parentNode && $jq(el.parentNode.parentNode).is(".compcol"))) {
			notestr = "<strong>Compare selected rows</strong>" + ((rankingstabledetails.compareEnabled)?"<p>Click to remove the comparison filter.</p>":"<p>Click to show only the rows you have selected for comparison.</p>");

		// Column header note
		} else if (hovertarget.tagName=="TH" && hovertarget.parentNode.parentNode.parentNode.id=="rankingstable" && noteref) {
			var col = rankingstabledetails.columns[noteref];
			if (col) {
				notestr = "<strong>"+col.title+"</strong>";
				if (col.noteref) notestr += "<p>"+rankingstabledetails.notetexts[col.noteref]+"</p>";
				if (el.tagName=="A") {
					notestr += "<p><em>Click to remove this column from the table.</em></p>";
				} else if (rankingstabledetails.cursort == noteref) {
					notestr += "<p><em>Click to re-sort this column in "+(($jq("#th"+rankingstabledetails.activecolumns[noteref]).is(".ascsort"))?"descending":"ascending")+" order.</em></p>";
				} else {
					notestr += "<p><em>Click to sort the table using this column.</em></p>";
				}
			}

		// Sharing field box note
		} else if (hovertarget.tagName=="LABEL" && hovertarget.parentNode.parentNode.id=="rankingsextractcolumnlist") {
			var col = rankingstabledetails.columns[noteref];
			notestr = "<strong>"+col.title+"</strong>";
			if (col.noteref) notestr += "<p>"+rankingstabledetails.notetexts[col.noteref]+"</p>";
			notestr += "<p><em>Click to "+((rankingstabledetails.activecolumns[noteref])?"remove this column from":"add this column to")+" the shared table.</em></p>";
		}
	} else {

		/* Profile page */

		if (noteref && profiletables.notetexts[noteref]) notestr = "<p>"+profiletables.notetexts[noteref]+"</p>";
		if ($jq("span", hovertarget).length) hovertarget = $jq("span", hovertarget).get(0);
	}

	if (notestr.length) {
		if (showtimer) clearTimeout(showtimer);
		if (hidetimer) clearTimeout(hidetimer);
		var dispnote = displayNoteBubble(notestr, hovertarget);
		if ($jq("#notepopup").css("display") != "none") {
			dispnote();
		} else {
			showtimer = setTimeout(dispnote, 250);
		}
	}
}

// Display a note bubble pointing at the top centre of an element
function displayNoteBubble(notetext, refel) {
	return (function() {

		// Check the initial position inside a try/catch - if elements are removed from the DOM during
		// the small mouse hover day, javscript errors sometimes occur
		try {
			var initialposition = $jq(refel).offset();
		} catch(err) {
			return;
		}
		var elewidth = refel.offsetWidth;
		var popuptype = "top";
		var arrowoffset = 0;
		var maxwidthele = (typeof(profiletables) == "object")?$jq("#entityview"):$jq("#rankingstable");
		if (!maxwidthele.length) maxwidthele = $jq("#rankings");
		var widthlimit = $jq(maxwidthele).width() + 300; // Table width (variable) + sidebar.
		var adleftpx = 667; // Hardcoded for simplicity/speed.
		var adrightpx = 977; // Hardcoded for simplicity/speed.

		// Set a default bubble width of 200 and increase if there's lots of text
		var notewidth = 300;
		if (notetext.length > 350) {
			notewidth = 350;
			if (notetext.length > 700) notewidth = 400;
		}

		// Set the starting top and left positions
		var toppx = initialposition.top;
		var leftpx = initialposition.left + Math.floor((elewidth - notewidth)/2);

		// If the note bubble appears to conflict with the advert, trigger repositioning logic.
		if (leftpx + notewidth > adleftpx && leftpx < adrightpx && toppx > 250 && toppx < 700) {

			// If we can shuffle the note bubble to the left while keeping the arrow on the element, do so.
			if (initialposition.left + elewidth/2 + 10 < adleftpx) {
				var correction = (leftpx + notewidth) - 5 - adleftpx;
				leftpx -= correction;
				arrowoffset += correction;

			// Or if we can shuffle the note bubble to the right:
			} else if (initialposition.left + elewidth/2 - 10 > adrightpx) {
				var correction = 5 + adrightpx - leftpx;
				leftpx += correction;
				arrowoffset -= correction;

			// If both aren't possible, we must use a note bubble positioned to the left.
			} else {
				popuptype = "left";
				leftpx = initialposition.left - notewidth;
				toppx = initialposition.top - 5;
			}
		}

		// Use additional checks and limits if we're positioning above the element - can conflict with
		// the screen edges.  If it does, reposition inwards.
		if (popuptype == "top") {
			if (leftpx < 10) {
				arrowoffset += leftpx - 10;
				leftpx = 10;
			} else if (leftpx + notewidth > widthlimit + 10) {
				arrowoffset += leftpx + notewidth - 10 - widthlimit;
				leftpx = widthlimit + 10 - notewidth;
			}
		}

		// Initially render of the notes div - in the correct location to the left, but if above is
		// rendered directly over the element to allow height to be set before we move upwards.
		$jq("#notetext").html(notetext);
		$jq("#notepopup").css({left:leftpx+"px", top:toppx+"px", width:notewidth+"px", visibility:"hidden", display:"block"});

		// Switch to orientation-appropriate rendering
		if (popuptype == "top") {

			// Add appropriate popup class and position arrow, as well as moving iframe if it exists.
			$jq("#notepopup").removeClass("popupleft").addClass("popupabove");
			$jq("#noteiframe").css({width:(notewidth+2)+"px", left:"-1px", top:"-1px", height:($jq("#notepopup").height() + 9)+"px", display:"block", filter:"alpha(opacity=0)"});
			$jq("#notearrow").css({top:"auto", left:(Math.floor(notewidth / 2)+arrowoffset-((rankingsstyle == 'falcon')?9:7))+"px"});

			// Calculate the offset position and move the bubble
			toppx -= $jq("#notepopup").height();
			$jq("#notepopup").css({top:toppx+"px", visibility:"visible"});

		} else {

			// Add the correct popup class, hide the iframe if it exists, and display the note.
			$jq("#notepopup").removeClass("popupabove").addClass("popupleft");
			$jq("#notearrow").css({top:Math.floor(refel.offsetHeight/2 - ((rankingsstyle == 'falcon')?5:0))+"px", left:"auto"});
			$jq("#noteiframe").hide();
			$jq("#notepopup").css("visibility", "visible");
		}
	});
}

// Function to create the hidden note element - should be called from page initialisation functions.
function createNoteBubble() {
	if ($jq("#notepopup").length) return;
	var iframestr = '';

	// If this is IE 6, we need to iframe the popup to avoid <select> problems
	if ($jq.browser.msie && parseInt($jq.browser.version) < 7) {
		iframestr = '<iframe id="noteiframe" src="javascript:\'<html></html>\';" scrolling="no" frameborder="no"></iframe>';
	}

	var notebubblehtml = '<div id="notepopup">'+iframestr+'<div id="noteboundary"><div id="noteinner"><div class="nw"></div><div class="ne"></div><div id="notetext"></div><div class="sw"></div><div class="se"></div></div></div><div id="notearrow"></div></div>';
	$jq(document.body).append(notebubblehtml);
}

function hideRankingsNotes() {
	if (hidetimer) clearTimeout(hidetimer);
	if (showtimer) clearTimeout(showtimer);
	hidetimer = setTimeout(function() { $jq("#noteiframe").hide(); $jq("#notepopup").hide(); }, 50);
}

// Reposition the table as necessary so the ads aren't covered
function repositionRankingsTable() {
	// Redmine #34857 - new wrapper made this funtionality untenable
}

// Log an action to the FT stats system by calling the webtrends function dcsMultiTrack.
function logActionToWebtrends(action, detail) {
	// REVIEW:AB:20080621: DCS Multitrack has been deprecated by FT.
	//if (typeof(detail) == "undefined") detail = false;
	//dcsMultiTrack("WT.rankingsAction", action, "WT.rankingsActionDetail", detail);
}

// Trigger a request for the current table view as a PDF.
function saveAsPDF() {
	if (!rankingstabledetails.loaded) initRankingsTable();
	var visiblecols = fetchActiveColIDs();
	var visiblerows = fetchActiveRowIDs();

	if (!visiblecols.length || !visiblerows.length) {
		alert("You must have some data visible to download this table as a PDF.");
	}

	// Log an event
	logActionToWebtrends("custompdfdownload", visiblecols.length+" cols and "+visiblerows.length+" rows");

	startWaiting("Generating PDF");
	setTimeout(function() {
		if ($jq.browser.msie) {
			$jq("#waitspinner").css("display", "none");
			var wh = (self.innerHeight) ? self.innerHeight : document.documentElement.clientHeight;
			var y = (self.pageYOffset) ? self.pageYOffset : document.documentElement.scrollTop;
			var x = (self.pageXOffset) ? self.pageXOffset : document.documentElement.scrollLeft;
			var ielink = document.createElement("div");
			ielink.id = "iedownload";
			ielink.innerHTML = "<iframe src=\"javascript:'<html></html>';\" scrolling=\"no\" frameborder=\"no\"></iframe><a onclick=\"$jq('#iedownload div').show(); window.location = '/exportranking"+window.location.pathname.replace(/\/[0-9]+$/, '')+"/pdf?cols="+visiblecols.join("|")+"&rows="+visiblerows.join("|")+"&sortby="+rankingstabledetails.activecolumns[rankingstabledetails.cursort]+"'; setTimeout(function() { $jq('#iedownload').remove(); }, 5000);\"><div></div></a>";
			$jq(ielink).css({top:(y+(wh/2)-75)+'px', left:(x+365)+'px'}).appendTo("#content");
			$jq("#iedownload iframe").css("filter", "alpha(opacity=0)");
			$jq("#iedownload a").css("top", 0);
		} else {
			setTimeout(function() { $jq("#waitspinner").css("display", "none"); }, 3000);
			window.location = "/exportranking"+window.location.pathname.replace(/\/[0-9]+$/, '')+"/pdf?cols="+visiblecols.join("|")+"&rows="+visiblerows.join("|")+"&sortby="+rankingstabledetails.activecolumns[rankingstabledetails.cursort];
		}
	}, 1100);
}

// Trigger a request for the current table view as an Excel 2003/XML file.
function saveAsExcel() {
	if (!rankingstabledetails.loaded) initRankingsTable();
	var visiblecols = fetchActiveColIDs();
	var visiblerows = fetchActiveRowIDs();

	if (!visiblecols.length || !visiblerows.length) {
		alert("You must have some data visible to download this table as an Excel file.");
	}

	// Log an event
	logActionToWebtrends("customexceldownload", visiblecols.length+" cols and "+visiblerows.length+" rows");

	startWaiting("Generating Excel file");
	setTimeout(function() {
		if ($jq.browser.msie) {
			$jq("#waitspinner").css("display", "none");
			var wh = (self.innerHeight) ? self.innerHeight : document.documentElement.clientHeight;
			var y = (self.pageYOffset) ? self.pageYOffset : document.documentElement.scrollTop;
			var x = (self.pageXOffset) ? self.pageXOffset : document.documentElement.scrollLeft;
			var ielink = document.createElement("div");
			ielink.id = "iedownload";
			ielink.innerHTML = "<iframe src=\"javascript:'<html></html>';\" scrolling=\"no\" frameborder=\"no\"></iframe><a onclick=\"$jq('#iedownload div').show(); window.location = '/exportranking"+window.location.pathname.replace(/\/[0-9]+$/, '')+"/excel?cols="+visiblecols.join("|")+"&rows="+visiblerows.join("|")+"&sortby="+rankingstabledetails.activecolumns[rankingstabledetails.cursort]+"'; setTimeout(function() { $jq('#iedownload').remove(); }, 5000);\"><div></div></a>";
			$jq(ielink).css({top:(y+(wh/2)-75)+'px', left:(x+365)+'px'}).appendTo("#content");
			$jq("#iedownload iframe").css("filter", "alpha(opacity=0)");
			$jq("#iedownload a").css("top", 0);
		} else {
			setTimeout(function() { $jq("#waitspinner").css("display", "none"); }, 3000);
			window.location = "/exportranking"+window.location.pathname.replace(/\/[0-9]+$/, '')+"/excel?cols="+visiblecols.join("|")+"&rows="+visiblerows.join("|")+"&sortby="+rankingstabledetails.activecolumns[rankingstabledetails.cursort];
		}
	}, 1100);
}

// Link to the chart page for the currently selected ranking/sort col/entities
function showChartOfCurrentView() {
	var link = "/"+rankingseriesslug+"/charts?ranking="+rankingslug+"&field="+rankingstabledetails.activecolumns[rankingstabledetails.cursort]+"&entities=";

	var rankingstableitems = rankingstabledetails.table;
	var itemcount = rankingstableitems.length;
	for (var i=0; i<itemcount; i++) {
		if (rankingstableitems[i][0].val.indexOf("checked=\"checked") != -1) {
			link += rankingstableitems[i][0].id+"|";
		}
	}
	if (itemcount) link += "&fromtablecompare=1";

	window.location = link;
}

// Determine whether to display the interface for the embeddable table wizard
function shareRankingViaWeb() {
	if (!rankingstabledetails.loaded) initRankingsTable();
	var selectedtableitems = new Array();
	var selectedtableitemnames = new Array();
	var rankingstableitems = rankingstabledetails.table;
	var entityhighlightoptionhtml = '<option value="">None</option>';
	var itemcount = rankingstableitems.length;
	var entitycol = rankingstabledetails.columns[rankingstabledetails.entityfield].colnum;
	sharetablesettings = {};

	Assanka.$("#rankingsextractentitieslimited").hide();
	Assanka.$("#rankingsextractpreviewprogress").hide();

	var currentlyshowingpreview = (Assanka.$('#rankingsextractcontainer').css("display") != "none");

	for (var i=0; i<itemcount; i++) {
		if (rankingstableitems[i][0].val.indexOf("checked=\"checked") != -1) {
			if (selectedtableitems.length >= 10) {
				Assanka.$("#rankingsextractentitieslimited").show();
				break;
			}

			selectedtableitems[selectedtableitems.length] = rankingstableitems[i][0].id;
			var itemname = rankingstableitems[i][entitycol].val;
			itemname = itemname.replace(/\<em.*/i,'');
			itemname = itemname.replace(/\<a[^\>]+\>(.*)\<\/a\>/i, "$1");
			itemname = itemname.replace(/\<img[^\>]+>/i, "");
			selectedtableitemnames[selectedtableitemnames.length] = itemname;

			entityhighlightoptionhtml += '<option value="'+rankingstableitems[i][0].id+'">'+itemname+'</option>';
		}
	}

	if (!selectedtableitems.length) {
		alert("To generate a table extract, you must first select which rows you want to export (up to a maximum of ten).\n\nTo do this, mark the checkboxes in the first table column for the rows you wish to export, and then try again.");
		return;
	}
	sharetablesettings.entities = selectedtableitems;

	// If the overlay doesn't already exist, create it and add to the body
	if (!Assanka.$("#rankingsextractbackground").length) {
		Assanka.$('<div id="rankingsextractbackground" style="display: none"><iframe src="javascript:\'<html></html>\';" scrolling="no" frameborder="no" ALLOWTRANSPARENCY="true" style="background-color: transparent"></iframe><div></div>').appendTo(Assanka.$(document.body));

		// ...and move the extract HTML to after it for IE layering
		Assanka.$("#rankingsextractcontainer").appendTo(Assanka.$(document.body));
	}

	// Stretch the background out to full body size
	var targetbgheight = Assanka.$(document.body).height();
	if (Assanka.$("#fullpage-container").length) targetbgheight = Math.max(targetbgheight, Assanka.$("#fullpage-container").height() + Assanka.$("#fullpage-container").get(0).offsetTop);
	Assanka.$("#rankingsextractbackground").width(Math.max(Assanka.$(document.body).width(), document.documentElement.scrollWidth)).height(targetbgheight);


	if (!currentlyshowingpreview) {

		// Update the interface of the form
		// First the selected entity names and highlight
		Assanka.$("#rankingsextractentities").html("<li><span>"+selectedtableitemnames.join("</span></li><li><span>")+"</span></li>");
		Assanka.$("#rankingsextractentityhighlight").html(entityhighlightoptionhtml).val("");

		// Then the column dropdowns and selections.
		var columnoptionshtml = "";
		var columnselecthtml = "";
		var tablecolumns = rankingstabledetails.columns;
		var cursortid = rankingstabledetails.activecolumns[rankingstabledetails.cursort];
		var selectedactivecols = {length:0};
		for (var i=0; i<rankingstabledetails.activecolumns.length && selectedactivecols.length < 4; i++) {
			if (typeof(rankingstabledetails.activecolumns[i]) == "undefined") continue;
			if (rankingstabledetails.activecolumns[i] == rankingstabledetails.entityfield) continue;
			selectedactivecols[rankingstabledetails.activecolumns[i]] = true;
			selectedactivecols.length++;
		}
		for (var i in tablecolumns) {
			if (!tablecolumns[i].title) continue;
			columnoptionshtml += '<option value="'+i+'"'+((i == cursortid)?' selected="selected"':'')+'>'+unescape(tablecolumns[i].title)+'</option>';

			if (i == rankingstabledetails.entityfield) continue;
			columnselecthtml += '<li'+((selectedactivecols[i])?' class="fieldon"':'')+'><label onmouseout="hideRankingsNotes()" onmouseover="showNote(event, '+i+')" for="sharefield'+i+'"><input type="checkbox" id="sharefield'+i+'" value="'+i+'" onclick="toggleSharedFieldControl('+i+');" '+((selectedactivecols[i])?' checked="checked"':'')+'/>'+unescape(tablecolumns[i].shorttitle)+'</label></li>';
		}
		Assanka.$("#rankingsextractsortcol").html(columnoptionshtml);
		if (cursortid) Assanka.$("#rankingsextractsortorder").val(tablecolumns[cursortid].sort);
		Assanka.$("#rankingsextractcolumnlist").html(columnselecthtml);
	}
	Assanka.$(".rankingsextractpreviewbutton").attr("disabled", "");

	if (currentlyshowingpreview) {
		Assanka.$("#rankingsextractpreview").slideUp(300);
		Assanka.$("#rankingsextractinterface").slideDown(300);

	} else {

		// Get the window width, height, scroll top and left
		var ww = (window.innerWidth) ? window.innerWidth : ((document.documentElement && document.documentElement.clientWidth) ? document.documentElement.clientWidth : document.body.clientWidth );
		var wh = (window.innerHeight) ? window.innerHeight : ((document.documentElement && document.documentElement.clientHeight) ? document.documentElement.clientHeight : document.body.clientHeight );
		var scrolly = (window.pageYOffset) ? window.pageYOffset : ((document.documentElement && document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop);
		var scrollx = (window.pageXOffset) ? window.pageXOffset : ((document.documentElement && document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft);

		// Position and display the interface
		Assanka.$("#rankingsextractinterface").show();
		Assanka.$("#rankingsextractpreview").hide();
		Assanka.$("#rankingsextractbackground").css({display:"block"}).children("div").css({opacity:0}).animate({opacity:0.8}, 300);
		Assanka.$("#rankingsextractcontainer").css({top:(scrolly + Math.max((wh - Assanka.$("#rankingsextractcontainer").height())/2, 10)), left:(scrollx + Math.max((ww - Assanka.$("#rankingsextractcontainer").width())/2, 10))}).fadeIn(300);
	}
}

// Amend the shared field control display and show or hide the too-many-fields warning as appropriate
function toggleSharedFieldControl(fieldid) {
	Assanka.$("#sharefield"+fieldid).parent().parent().toggleClass('fieldon');
	if (Assanka.$("#rankingsextractcolumnlist input:checked").length > 4) {
		Assanka.$("#rankingsextractcolslimited").html("A maximum of four columns (in addition to the name column) can be exported.").slideDown(500);
		Assanka.$(".rankingsextractpreviewbutton").attr("disabled", "disabled");
	} else if (Assanka.$("#rankingsextractcolumnlist input:checked").length == 0) {
		Assanka.$("#rankingsextractcolslimited").html("You must select at least one column to display.").slideDown(500);
		Assanka.$(".rankingsextractpreviewbutton").attr("disabled", "disabled");
	} else {
		Assanka.$("#rankingsextractcolslimited").slideUp(500);
		Assanka.$(".rankingsextractpreviewbutton").attr("disabled", "");
	}
}

// Table pagination link clicked - amend the link and follow it.
function followPaginationLink(linkElement) {
	var paginationLink = linkElement.href;
	if (paginationLink.indexOf('fields=') != -1) {
		paginationLink = paginationLink.replace(/fields=([^&]*)/, 'fields='+fetchActiveColIDs().join('|'));
	} else if (paginationLink.indexOf('?') != -1) {
		paginationLink = paginationLink+'&fields='+fetchActiveColIDs().join('|');
	} else {
		paginationLink = paginationLink+'?fields='+fetchActiveColIDs().join('|');
	}
	window.location = paginationLink;
}

// Start the preview display process, updating the interface as necessary.
function shareRankingViaWebPreview() {

	// Set the interface up before making the server request
	Assanka.$(".rankingsextractpreviewbutton").attr("disabled", "disabled");
	Assanka.$("#rankingsextractpreviewprogress").html("Loading preview...").fadeIn(300);

	// Update the highlighted entity, if any
	sharetablesettings.highlightedentity = Assanka.$("#rankingsextractentityhighlight").val();

	// Update the selected column and sort order
	sharetablesettings.sortcolumn = Assanka.$("#rankingsextractsortcol").val();
	sharetablesettings.sortorder = Assanka.$("#rankingsextractsortorder").val();

	// Select up to four enabled columns
	sharetablesettings.columns = new Array();
	Assanka.$("#rankingsextractcolumnlist input:checked").each(function(i) {
		if (i == 4) return false;
		sharetablesettings.columns[i] = Assanka.$(this).val();
	});

	// Make a post request to the server with the supplied details to get the preview
	Assanka.$.get("/lib/ajx/getrankingextractpreview", {"series":rankingseriesslug, "ranking":rankingslug, "entities":sharetablesettings.entities.join("|"), "highlightedentity":sharetablesettings.highlightedentity, "sortcolumn":sharetablesettings.sortcolumn, "sortorder":sharetablesettings.sortorder, "columns":sharetablesettings.columns.join("|")}, function(response) {
		if (response.error) {
			alert(response.error);
			Assanka.$(".rankingsextractpreviewbutton").attr("disabled", "");
			Assanka.$("#rankingsextractpreviewprogress").fadeOut(300);
			return;
		}

		// On success, update the preview interface.
		Assanka.$("#rankingsextractembedsource").val(response.iframe);
		Assanka.$("#rankingsextractsourcelink").html(response.link);

		Assanka.$("#rankingsextracttablepreview").html(response.preview);
		Assanka.$(".rankingsextractpreviewbutton").attr("disabled", "");
	}, "json");
}

function shareRankingViaWeb_DisplayPreview() {
	Assanka.$("#rankingsextractinterface").slideUp(300);
	Assanka.$("#rankingsextractpreview").slideDown(300);

	if (!Assanka.$("#rankingsextracttypesource").attr("checked")) {
		window.setTimeout(function() { Assanka.$("#rankingsextractembedsource").select(); }, 25);
	}
}

// Update the interface when the export type is changed
function shareRankingViaWeb_AlterExportType() {
	if (Assanka.$("#rankingsextracttypesource").attr("checked")) {
		Assanka.$("#rankingsextractembedpreview").hide();
		Assanka.$("#rankingsextractlinkpreview").show();
	} else {
		Assanka.$("#rankingsextractlinkpreview").hide();
		Assanka.$("#rankingsextractembedpreview").show();
		window.setTimeout(function() { Assanka.$("#rankingsextractembedsource").select(); }, 25);
	}
}

// Return an array containing the id of each visible column in the current table view
function fetchActiveColIDs() {
	var activecols = new Array();

	for (var i=0; i<rankingstabledetails.activecolumns.length; i++) {
		if (typeof(rankingstabledetails.activecolumns[i]) != "undefined") activecols.push(rankingstabledetails.activecolumns[i]);
	}

	return activecols;
}

// Return an array containing the id of each visible row in the current table view
function fetchActiveRowIDs() {
	var activerows = new Array();
	var colmap = new Array();

	// Build up a column map of column ids to indexes.  Previously marked as AB review, so: AB:REVIEW
	// Add a zero-column for the checkboxes
	for (var key in rankingstabledetails.columns) {
		colmap[colmap.length] = key;
	}

	for (var i=0; i<rankingstabledetails.table.length; i++) {
		if (!rankingstabledetails.compareEnabled || rankingstabledetails.table[i][0].val.indexOf("checked=\"checked") != -1) {
			var searchtext = new String();
			var filtermatch = (rankingstabledetails.filter || rankingstabledetails.activefilters.length) ? false : true;
			var filtermatchfail = false;
			var rowitems = rankingstabledetails.table[i];
			for (var j=1; j<rowitems.length; j++) {
				if (!filtermatch || rankingstabledetails.activefilters[colmap[j-1]]) {
					var celldata = rowitems[j].val.replace(/\<em.*/i,'');
					if (rankingstabledetails.filter) {
						searchtext = celldata.replace(/(<([^>]+)>)/ig,"").replace(/[^\w ]/gi, "").toLowerCase();
						if (searchtext.indexOf(rankingstabledetails.filter) != -1) filtermatch = true;
					} else {
						filtermatch = true;
					}
					if (rankingstabledetails.activefilters[colmap[j-1]]) {
						var advfiltermatched = false;
						celldata = celldata.replace(/^([\-0-9\.]+)[\s?\(].*$/, "$1");
						celldata = celldata.replace(/[^\-0-9\.]/g, "");
						celldata = parseFloat(celldata);
						var filtertocheck = rankingstabledetails.activefilters[colmap[j-1]];
						for (var k=0; k<filtertocheck.length; k++) {
							var v = filtertocheck[k];
							if (v.val === false) {
								if (celldata <= v.high && celldata >= v.low) advfiltermatched = true;
							} else {
								if (celldata == v.val) advfiltermatched = true;
							}
						}
						if (!advfiltermatched) filtermatchfail = true;
					}
				}
			}
			if (filtermatch && !filtermatchfail) {
				activerows.push(rankingstabledetails.table[i][0].id);
			}
		}
	}

	return activerows;
}

function DoBench(benchtext){
	var curTime;
	var localvar = benchvar;
	curTime = new Date().getTime();
	if (typeof(benchtext) != "undefined") {
		if (typeof(console) != "undefined") console.log(benchtext+" took "+((curTime - localvar))+" milliseconds.");
		else $jq("#rankingssearchtext").val(benchtext+" took "+((curTime - localvar))+" milliseconds.");
	}
	benchvar = curTime;
}

// Browser compliant method of returning source of event.
function getEventSrc(e) {
	if (!e) var e = window.event;
	if (!e) return false;
	var ele;
	if (e.target) ele = e.target;
	else if (e.srcElement) ele = e.srcElement;

	// If element is text node, select parent
	if (ele.nodeType == 3) ele = ele.parentNode;
	return ele;
}

function getQueryStrings() {
	var queryStringParams = new Array();
	var querystring = window.location.search.substring(1);
	var params = querystring.split("&");
	for (var i=0; i<params.length; i++) {
		var position = params[i].indexOf("=");
		if (position > 0) {
			queryStringParams[params[i].substring(0, position)] = params[i].substring(position+1);
		}
	}
	return queryStringParams;
}

// Provide javascript array push for IE 5 - thankyou quirksmode.org!
function Array_push() {
	var A_p = 0
	for (A_p = 0; A_p < arguments.length; A_p++) {
		this[this.length] = arguments[A_p]
	}
	return this.length
}
if (typeof Array.prototype.push == "undefined") {
	Array.prototype.push = Array_push
}

jQuery.fn.extend({
	check: function(shouldcheck) {
		if (typeof(shouldcheck) == "undefined") shouldcheck = true;
		return this.each(function() { this.checked = shouldcheck; });
	},
	uncheck: function() {
		return this.each(function() { this.checked = false; });
	}
});
/**
 * Provide javascript for the charts pages - included on pages via
 * alljavascript.
 *
 * @copyright The Financial Times Limited [All Rights Reserved]
 */

var selectedranking = false;
var selectedrankingtitle = false;
var selectedcharttype = false;
var chartdrawn = {};
var charteverdrawn = {};
var chartseriesslug = false;
var currententityentry = false;
var chartobjects = {};
var delayingtimer = false;
var showingrecommendations = false;
var rankingselectioncollapsed = false;
var entityselectioncollapsed = false;
var variableselectioncollapsed = false;
var charttypecollapsed = false;
var chartlinkselementshowing = false;
var scrolltocharthidetimer = false;

Assanka.$(document).ready(function() {
	createNoteBubble();
});

// Initialise charts when necessary
function initCharts(slug) {
	if (!Assanka.$("#chartrankingdropdown").val()) Assanka.$(".appearslistwidget").hide();
	rankingselectioncollapsed = Assanka.$("#chartrankingselection").hasClass("collapsed");
	entityselectioncollapsed = Assanka.$("#chartentityselection").hasClass("collapsed");
	variableselectioncollapsed = Assanka.$("#chartvariableselection").hasClass("collapsed");
	charttypecollapsed = Assanka.$("#charttypeselection").hasClass("collapsed");
	selectedranking = Assanka.$("#chartrankingdropdown").val();
	selectedrankingtitle = Assanka.$("#chartrankingdropdown option:selected").text();
	selectedcharttype = Assanka.$("#charttypeselection input:checked").val();
	Assanka.$('#chartvariable_set input:checked').parents('.field').addClass('selectedfield');
	chartseriesslug = slug;
	chartpageid += Math.floor(Math.random() * 500000000);

	updateChartsInterface();
	updateChartDisplay();
	if (!showingrecommendations) {
		Assanka.$("#chartentitysuggestiontitle").css({"opacity":0, "display":"block"});
	}

	// Set up the entity entry autocomplete menu, and also get the text field to update the selected item
	// if the text is later changed.
	Assanka.$("#chartentityautocomplete").focus(function() { if (Assanka.$(this).val() == "Enter the "+entityname+" name here") Assanka.$(this).val('').removeClass("inputhint"); }).blur(function() { if (Assanka.$(this).val() == "") Assanka.$(this).val("Enter the "+entityname+" name here").addClass("inputhint"); }).autocomplete("/lib/ajx/entitylookup", {extraParams:{"series":chartseriesslug, "set":selectedranking, "autocomplete":1}, "baseOffsetElementIdentifier":"#rankings", matchSubset:false, onItemSelect:function(listitem) { if (listitem && listitem.extra) currententityentry = listitem.extra; selectChartEntityEntry(); }, formatItem:function(row) { return row[2]; }}).keyup(function() { if (currententityentry && Assanka.$(this).val() != currententityentry[0]) currententityentry = false; });
	
	if (Assanka.$.browser.msie) {
		Assanka.$("#scrolltochart").append(document.createElement('iframe'));
		Assanka.$("#chartlinkpopup").append(document.createElement('iframe'));
	}
	
	updateChartData();
	Assanka.$(window).scroll(function() {
		if (scrolltocharthidetimer) {
			clearTimeout(scrolltocharthidetimer);
			scrolltocharthidetimer = false;
			Assanka.$("#scrolltochart").hide();
		}
	});
}

// Collapse or expand the Ranking selection box
function toggleChartRankingSelection() {
	if (!rankingselectioncollapsed) {
		if (selectedranking) {
			Assanka.$("#chartrankingsummary").html(Assanka.$("#chartrankingselection option[value='"+selectedranking+"']").html());
		} else {
			Assanka.$("#chartrankingsummary").html("<em>None selected.  Please select one of the available "+setsgroupreference+" to proceed.</em>");
		}
	}
	toggleChartInterface("ranking", rankingselectioncollapsed);
	rankingselectioncollapsed = !rankingselectioncollapsed;
}

// Collapse or expand the entity entry selection box
function toggleChartEntitySelection() {
	if (!selectedranking) return;
	if (!entityselectioncollapsed) {
		var entities = Assanka.$("#chartentities_entities span");
		if (selectedentityentries.length) {
		
			// Note that prepopulated logic matching this is present in /pages/charts.
			var displaystring = "";
			for (var i = 0; i < selectedentityentries.length; i++) {
				var entityentryname = selectedentityentries[i][0];
				if (displaystring.length + entityentryname.length > 50) {
					if (displaystring.length) {
						displaystring += " and "+(selectedentityentries.length-i)+" other"+((selectedentityentries.length-i == 1)?"":"s");
					} else {
						displaystring = selectedentityentries.length+" selected";
					}
					i = selectedentityentries.length;
				} else {
					displaystring += ((displaystring.length)?", ":"") + entityentryname;
				}
			}
			Assanka.$("#chartentitysummary").html(displaystring);
		} else {
			Assanka.$("#chartentitysummary").html("<em>"+Assanka.$("#chartentities_noentities").html()+"</em>");
		}
	}
	toggleChartInterface("entity", entityselectioncollapsed);
	entityselectioncollapsed = !entityselectioncollapsed;
}

// Collapse or expand the variable selection box
function toggleChartVariableSelection() {
	if (!selectedranking) return;
	if (!variableselectioncollapsed) {
		if (selectedvariable) {
			Assanka.$("#chartvariablesummary").html(Assanka.$("#field"+selectedvariable).attr("fullname"));
		} else {
			Assanka.$("#chartvariablesummary").html("<em>None selected</em>");
		}
	}
	toggleChartInterface("variable", variableselectioncollapsed);
	variableselectioncollapsed = !variableselectioncollapsed;
}

// Collapse or expand the chart type box
function toggleChartTypeSelection() {
	if (!selectedranking) return;
	if (!charttypecollapsed) {
		if (Assanka.$("#charttypetimeseries").attr("checked")) {
			Assanka.$("#charttypesummary").html("Show changes over time");
		} else {
			Assanka.$("#charttypesummary").html("Show only this ranking");
		}
	}
	toggleChartInterface("type", charttypecollapsed);
	charttypecollapsed = !charttypecollapsed;
}

function toggleChartInterface(interfacetype, iscurrentlycollapsed) {
	hideChartLinks(false);
	if (iscurrentlycollapsed) {
		Assanka.$("#chart"+interfacetype+"selection .collapsearea").slideDown(300);
		Assanka.$("#chart"+interfacetype+"selection .summaryarea").fadeOut(300);
		Assanka.$("#chart"+interfacetype+"selection").removeClass("collapsed");
	} else {
		Assanka.$("#chart"+interfacetype+"selection .collapsearea").slideUp(300);
		Assanka.$("#chart"+interfacetype+"selection .summaryarea").fadeIn(300);
		Assanka.$("#chart"+interfacetype+"selection").addClass("collapsed");
	}
}

// Add an entity entry to the comparison list, triggered by either selecting an item from the autocomplete
// list or clicking the "+" button.
function selectChartEntityEntry() {
	Assanka.$(".chartentityaddbutton").blur();
	if (!selectedranking) return;

	// If no entity entry has been selected via the autocomplete, attempt to look up the entity name supplied
	if (!currententityentry) {
		Assanka.$("#entitylookupspinner").show();
		Assanka.$("button.chartentityaddbutton").hide();
		Assanka.$.getJSON("/lib/ajx/entitylookup", {series: chartseriesslug, set: selectedranking, q: Assanka.$("#chartentityautocomplete").val()}, function(json) {
			if (json.error) {
				Assanka.$("#entitylookupspinner").hide();
				Assanka.$("button.chartentityaddbutton").show();
				alert(json.error);
				return;
			}

			addEntityEntryToList(json.entity, "autocomplete");

			// Refocus on the text box
			Assanka.$("#chartentityautocomplete").focus();
		});

	// Otherwise select the current entity entry
	} else {
		addEntityEntryToList(currententityentry, "autocomplete");

		// Refocus on the text box
		Assanka.$("#chartentityautocomplete").focus();
	}
}

// Add a suggestion to the entities list when clicked
function selectSuggestion(suggestionentityid) {
	
	// Retrieve the entity details
	suggestionelement = Assanka.$("#chartsuggestions_entities div[entityentryid="+suggestionentityid+"]");
	var entityentry = new Array();
	entityentry[0] = suggestionelement.find("a").text();
	entityentry[1] = entityentry[0];
	entityentry[2] = suggestionentityid;

	addEntityEntryToList(entityentry, "suggestion");
}

// Add a supplied entity entry to the chart entity selection list.
function addEntityEntryToList(entityentry, sourcemethod) {
	Assanka.$("#entitylookupspinner").hide();
	Assanka.$("button.chartentityaddbutton").show();
	var transferelement;
	var sourceelement;
	entitychangesmade = true;

	if (sourcemethod == "autocomplete") {
		sourceelement = Assanka.$("#chartentityautocomplete");
	} else {
		sourceelement = Assanka.$("#chartsuggestions_entities div[entityentryid="+entityentry[2]+"]");
	}
	
	// Check if the entity entry already exists, in which case we can animate directly to it instead of
	// creating a duplicate.
	transferelement = Assanka.$("#chartentities_entities div[entityentryid="+entityentry[2]+"]");
	if (transferelement.length) {
		sourceelement.transferTo(transferelement);

	// Otherwise, create a new element and add it.
	} else {

		if (selectedentityentries.length >= 10) {
			alert("You can only graph ten "+entitynameplural+" at one time.\n\nTo add more "+entitynameplural+", remove some from the list above by clicking on the red 'x' next to their name.");
			return;
		} else {
			if (Assanka.$("#chartentities_entities").css("display") == "none") {
				Assanka.$("#chartentities_noentities").slideUp(300);
				Assanka.$("#chartentities_entities").slideDown(300);
			}
			
			// Also note that preloading the page with entities selected outputs similar
			// code into starting HTML.
			Assanka.$('<div entityentryid="'+entityentry[2]+'"><span><a href="javascript:removeEntityEntryFromList('+entityentry[2]+');"></a>'+entityentry[0]+'</span></div>').appendTo("#chartentities_entities").slideDown(300, function() { Assanka.$(this).css("display", "inline");});
			sourceelement.transferTo(Assanka.$("#chartentities_entities div[entityentryid="+entityentry[2]+"]"));
			selectedentityentries[selectedentityentries.length] = entityentry;
			
			// If this was added via autocomplete, disable any associated suggestions
			if (sourcemethod == "autocomplete") {
				Assanka.$("#chartsuggestions_entities div[entityentryid="+entityentry[2]+"]").addClass("disabled");
			} 

			updateChartDisplay();
			updateChartData();
		}
	}

	if (sourcemethod == "autocomplete") {
		sourceelement.val('');
		currententityentry = false;
	} else {
		sourceelement.addClass("disabled");
	}
}

// Remove an entity entry from the chart selection list
function removeEntityEntryFromList(entityentryid) {
	entitychangesmade = true;
	Assanka.$("#chartentities_entities div[entityentryid="+entityentryid+"]").slideUp(300, function() {
		Assanka.$(this).remove();
	}).children("a").blur();
	for (var i in selectedentityentries) {
		if (selectedentityentries[i][2] == entityentryid) {
			selectedentityentries.splice(i, 1);
			break;
		}
	}
	if (!selectedentityentries.length) {
		if (showingrecommendations) {
			Assanka.$("#chartsuggestions_entitiesouter").animate({"height":1}, 250, "linear", function() { Assanka.$("#chartsuggestions_entities").html(""); });
			Assanka.$("#chartentitysuggestiontitle").animate({opacity:0}, 300);
		}
		showingrecommendations = false;
		Assanka.$("#chartentities_noentities").slideDown(300);
		Assanka.$("#chartentities_entities").slideUp(300);
		updateChartDisplay();
	}
	updateChartData();
}

// Update the ranking selection - triggered by clicking the "set" button next to the rankings dropdown
function selectChartRanking() {
	Assanka.$("#chartrankingsetbutton").blur();
	
	// If page has not fully initialised yet retry again shortly
	if (!Assanka.$("#chartentityautocomplete").get(0).autocompleter) {
		if (delayingtimer) {
			clearTimeout(delayingtimer);
		}
		delayingtimer = setTimeout(selectChartRanking, 250);
		return;
	}
	
	var newranking = Assanka.$("#chartrankingdropdown").val();
	if (newranking != selectedranking) {
		selectedvariable = false;
		selectedentityentries.splice(0, selectedentityentries.length);
		Assanka.$("#chartentitysummary").html("<em>"+Assanka.$("#chartentities_noentities").html()+"</em>");
		Assanka.$("#chartentities_entities").slideUp(300, function() { Assanka.$(this).html(''); });
		Assanka.$("#chartentities_noentities").slideDown(300);
		Assanka.$("#chartvariablesummary").html("<em>None selected</em>");
		Assanka.$("#chartsuggestions_entitiesouter").animate({"height":1}, 250, "linear", function() { Assanka.$("#chartsuggestions_entities").html(""); });
		if (showingrecommendations) Assanka.$("#chartentitysuggestiontitle").animate({opacity:0}, 300);
		showingrecommendations = false;
		
		if (newranking) {
			Assanka.$("#rankinglink").attr("href", "/"+seriesslug+"/"+newranking).text("View this "+rankingreferences[newranking]+" as a table");
			Assanka.$("#rankinglinkdivtitle").text("This "+rankingreferences[newranking]);
			Assanka.$(".appearslistwidget").slideDown(300);
			
			Assanka.$("#chartvariable_noset").hide(200);
			if (!Assanka.$("#chartvariableselection").hasClass("collapsed")) Assanka.$("#chartvariableselection .spinner").slideDown(300);
			Assanka.$("#chartvariable_set").slideUp(500);

			// Update the entity entry autocompleter with variables for the new set
			Assanka.$("#chartentityautocomplete").get(0).autocompleter.setExtraParams({"series":chartseriesslug, "set":newranking,"autocomplete":1});
			Assanka.$("#chartentityautocomplete").get(0).autocompleter.flushCache();

			// Retrieve the field names for the selected set
			Assanka.$.getJSON("/lib/ajx/getfieldnames", {series: chartseriesslug, set: newranking}, function(json) {
				if (json.error) {
					alert(json.error);
					return;
				}

				// Build up an HTML string
				var chartvariableselection = "";
				for (var i in json.fields) {
					if (typeof(json.fields[i].id) == "undefined") continue;

					// Also note that preloading the page with variables selected outputs similar
					// code into starting HTML.
					var field = json.fields[i];
					var fieldname = field.shortname.length?field.shortname:field.name;
					chartvariableselection += '<div class="field"><label id="field'+field.id+'label" for="field'+field.id+'"><input type="radio" name="chartfield" id="field'+field.id+'" fullname="'+field.name+'" '+((field.id == json.defaultfield)?'checked="checked" ':'')+' value="'+field.id+'" onclick="updateChartVariable('+field.id+');" '+((field.fieldsequenceid)?'class="hassequence" ':'')+' />'+fieldname+'</label></div>';
					if (field.id == json.defaultfield) {
						selectedvariable = field.id;
						if (field.fieldsequenceid) {
							Assanka.$("#charttypecont").slideDown(500);
						} else {
							Assanka.$("#charttypecont").slideUp(500);
							Assanka.$("#charttypesingleranking").attr("checked", "checked");
							updateChartType(false);
						}
					}
				}
                //this will help debugging
                if (!selectedvariable) {
                    if (typeof console != 'undefined') {
                        console.log('There is no selectedvariable present for field ID ' + json.defaultfield);
                    }
                }
				chartvariableselection += '<div class="heightlessclearer"></div>';

				// Add it to the page
				Assanka.$("#chartvariable_set").html(chartvariableselection);

				// Add notes where suitable.
				for (var i in json.fields) {
					if (typeof(json.fields[i].id) == "undefined") continue;

					var field = json.fields[i];
					var fielddesc = "<strong>"+field.name+"</strong>";
					if (field.description) fielddesc += field.description;
					if (field.description && field.note) fielddesc += "<br /><br />";
					if (field.note) fielddesc += "<em>"+field.note+"</em>";

					if (fielddesc) addChartNoteToElementWithId(fielddesc, "field"+field.id+"label");
				}

				// Reveal it
				Assanka.$("#chartvariable_set").slideDown(500);
				Assanka.$("#chartvariableselection .spinner").slideUp(300);

				// ...or update the summary string
				var selectedradioitem = Assanka.$("#chartvariableselection input[checked]");
				if (selectedradioitem.length) {
					Assanka.$("#chartvariablesummary").html(selectedradioitem.attr("fullname"));
					updateChartDisplay();
					updateChartData();
				} else {
					Assanka.$("#chartvariablesummary").html("<em>None selected</em>");
				}

			});
		} else {
			Assanka.$("#chartvariable_set").hide(300, function() { Assanka.$(this).html(); });
			Assanka.$("#chartvariableselection .spinner").slideUp(300);
			Assanka.$("#chartvariable_noset").show(300);
			Assanka.$(".appearslistwidget").slideUp(300);
			Assanka.$("#charttypecont").slideUp(300);
			Assanka.$("#charttypesingleranking").attr("checked", "checked");
			updateChartType(false);
		}
	}
	selectedranking = newranking;
	selectedrankingtitle = Assanka.$("#chartrankingdropdown option:selected").text();
	updateChartsInterface();
	updateChartDisplay();
}

// Show the link and embed overlay
function showChartLinks() {

	// If the links popup is already showing, hide it.
	if (chartlinkselementshowing) {
		hideChartLinks(true);
		return;
	}
	
	updateChartLinks();

	// Reveal the links popup
	if (jQuery.browser.msie) Assanka.$("#chartlinkpopup").find("iframe").height(Assanka.$("#chartlinkpopup").outerHeight()).width(Assanka.$("#chartlinkpopup").outerWidth()).css("left", -1);
	Assanka.$("#chartlinksbutton").addClass("active").blur();
	Assanka.$("#chartlinkpopup").css("top", Assanka.$("#chartlinksbutton").position().top+((rankingsstyle == 'falcon')?17:23)).slideDown(500);

	chartlinkselementshowing = true;
}
function updateChartLinks() {

	// Generate the link to this chart
	var link = window.location.protocol+"//"+window.location.host+window.location.pathname;
	link += "?ranking="+selectedranking+"&field="+selectedvariable+"&type="+selectedcharttype+"&entities=";
	var selectedentityentryids = new Array();
	for (var i in selectedentityentries) {
		if (selectedentityentries[i][2]) selectedentityentryids[selectedentityentryids.length] =  selectedentityentries[i][2];
	}
	link += selectedentityentryids.join("|");
	if (Assanka.$('#chartshowtitlecheckbox').get(0).checked) link += "&title=1";
	Assanka.$("#chartlinkinput").val(link);
	
	// Generate the embed for this chart
	var embedlink = window.location.protocol+"//"+window.location.host+"/"+seriesslug+"/embeds/chart";
	embedlink += "?set="+selectedranking+"&variable="+selectedvariable+"&type="+selectedcharttype+"&entityentries=";
	embedlink += selectedentityentryids.join(",");
	if (Assanka.$('#chartshowtitlecheckbox').get(0).checked) embedlink += "&title=1";
	Assanka.$("#chartembedinput").val('<iframe src="'+embedlink+'" width="400" height="250" frameborder="0"></iframe>');
}
function hideChartLinks(animatehide) {
	if (!chartlinkselementshowing) return;
	Assanka.$("#chartlinksbutton").removeClass("active").blur();
	if (animatehide) {
		Assanka.$("#chartlinkpopup").slideUp(500);
	} else {
		Assanka.$("#chartlinkpopup").hide();
	}
	chartlinkselementshowing = false;
}

// Update chart variable selection
function updateChartVariable(newvariable) {
	if (selectedvariable == newvariable) return;
	selectedvariable = newvariable;
	Assanka.$('#chartvariable_set .selectedfield').removeClass('selectedfield');
	Assanka.$('#chartvariable_set input:checked').parents('.field').addClass('selectedfield');
	if (Assanka.$('#field'+newvariable).hasClass('hassequence')) {
		Assanka.$("#charttypecont").slideDown(500);
	} else {
		Assanka.$("#charttypecont").slideUp(500);
		Assanka.$("#charttypesingleranking").attr("checked", "checked");
		Assanka.$("#charttypesummary").html("Show only this ranking");
		updateChartType(false);
	}
	updateChartDisplay();
	updateChartData();
}

// Update chart type as appropriate
function updateChartType(refreshdata) {
	if (typeof(refreshdata) == "undefined") refreshdata = true;

	var newcharttype = Assanka.$("#charttypeselection input:checked").val();
	if (newcharttype == selectedcharttype) return;

	selectedcharttype = newcharttype;
	for (var eachtype in chartobjects) {
		if (eachtype == selectedcharttype+'chart') {
			Assanka.$('#'+eachtype+'flashcontent').css('visibility', 'visible');
		} else {
			Assanka.$('#'+eachtype+'flashcontent').css('visibility', 'hidden');
		}
	}
	if (refreshdata) {
		updateChartDisplay();
		updateChartData();
	}
}

// Disable entity entry and variable selection if no set is selected
function updateChartsInterface() {
	if (!selectedranking) {
		Assanka.$("#chartentityselectioncont").css("opacity", 0.5).addClass("disabled").find("input").attr("disabled", "disabled");
		Assanka.$("#chartvariableselectioncont").css("opacity", 0.5).addClass("disabled").find("input").attr("disabled", "disabled");
	} else {
		Assanka.$("#chartentityselectioncont").css("opacity", 1).removeClass("disabled").find("input").attr("disabled", "");
		Assanka.$("#chartvariableselectioncont").css("opacity", 1).removeClass("disabled").find("input").attr("disabled", "");
	}
}

// Update the chart display
function updateChartDisplay() {
	hideChartLinks(false);

	if (!selectedranking) {
		hideCharts("Please select one of the "+setsgroupreference+", some "+entitynameplural+", and a Chart variable above.");
		Assanka.$("#chartheading").html("Chart");
		return;
	}

	if (!selectedvariable) {
		Assanka.$("#chartheading").html(selectedrankingtitle+" - chart");
		if (selectedentityentries.length) {
			hideCharts("Please select a Chart variable above.");
		} else {
			hideCharts("Please select "+entitynamepluralcap+" and a Chart variable above.");
		}
		return;
	}

	Assanka.$("#chartheading").html(selectedrankingtitle+" - "+Assanka.$("#field"+selectedvariable).attr("fullname"));

	if (!selectedentityentries.length) {
		hideCharts("Please add "+entitynamepluralcap+" above.");
		return;
	}

	if (!chartdrawn[selectedcharttype]) {
		if (!charteverdrawn[selectedcharttype]) {
			if (rankingsstyle == 'falcon') {
				Assanka.$("#"+selectedcharttype+"chartflashcontent").css({visibility:'visible', left:0-(605+Assanka.$('#page-container').get(0).offsetLeft), top:-420});
			} else {
				Assanka.$("#"+selectedcharttype+"chartflashcontent").css({visibility:'visible', left:-664, top:-420});
			}
		}
		Assanka.$("#chartflashcontentplaceholder").animate({height:415}, 500, "linear", function() {
			setTimeout(function() {
				if (!chartobjects[selectedcharttype+'chart'] || typeof(chartobjects[selectedcharttype+'chart'].setData) != "function" || typeof(chartobjects[selectedcharttype+'chart'].setSettings) != "function") {
					Assanka.$("#"+selectedcharttype+"chartflashcontent").css({left:0, top:0});
				}
			}, 5000);
		});
		Assanka.$("#chart_notenoughdetails").slideUp(300);
		Assanka.$("#chartlinksbutton").css("display", "inline");
		chartdrawn[selectedcharttype] = true;
		charteverdrawn[selectedcharttype] = true;
	}
}

// Retrieve full or additional data for the chart.  If a parameter recording an entity entry id is supplied,
// only that data is supplied; otherwise all the data is fetched again.
function updateChartData() {
	if (!selectedranking || !selectedvariable || !selectedentityentries.length){
        if (typeof console != 'undefined') {
            console.log('Sel-ranking ' + selectedranking + '\n' + 'sel-variable ' + selectedvariable + ' sel-Entity ' + selectedentityentries.length);
            console.log('Some required variables are missing, no graph will be displayed');
        }
        return false;
    }

	// Ensure charts have fully loaded and initialised.
	if (!chartobjects[selectedcharttype+'chart'] || typeof(chartobjects[selectedcharttype+'chart'].setData) != "function" || typeof(chartobjects[selectedcharttype+'chart'].setSettings) != "function") {
        if (typeof console != 'undefined') console.log('Chart data will be loaded in 0.25 s');

        window.setTimeout(function() { updateChartData(); }, 250);
		return false;
	}

	// Set up a variable containing either the supplied entity entry or all entity entries
	var entityentriestosubmit = new Array();
	var entityentrynamestosubmit = new Array();
	for (var i = 0; i < selectedentityentries.length; i++) {
		entityentriestosubmit[i] = selectedentityentries[i][2];
		entityentrynamestosubmit[i] = selectedentityentries[i][0].replace(",", "|");
	}
	Assanka.$("#"+selectedcharttype+"chartflashcontent").css({"visibility":"hidden"});

	// Submit the requested data to the server
	Assanka.$.getJSON("/lib/ajx/chartdata", {"series":chartseriesslug, "set":selectedranking, "variable":selectedvariable, "entityentries":entityentriestosubmit.toString(), "pageid":chartpageid, "nocache":Math.random(), "returnrecommendations":1, "storerecommendations":(entitychangesmade?1:0), "type":selectedcharttype }, function(json) {
		if (json.error) {
			Assanka.$("#chartflashcontentplaceholder").animate({height:0}, 500);
			alert(json.error);
			return;
		}

		// Set the data order
		var axiskey = (selectedcharttype == 'timeseries')?'y_left':'value';
		chartobjects[selectedcharttype+'chart'].setSettings("<settings><values><"+axiskey+"><reverse>"+(json.reverseorder?"true":"false")+"</reverse></"+axiskey+"></values></settings>", false);
		if (selectedcharttype == 'single' || json.reverseorder) {
			chartobjects[selectedcharttype+'chart'].setSettings("<settings><values><"+axiskey+"><min>"+json.min+"</min></"+axiskey+"></values></settings>", false);
			chartobjects[selectedcharttype+'chart'].setSettings("<settings><values><"+axiskey+"><max>"+json.max+"</max></"+axiskey+"></values></settings>", false);
		} else {
			chartobjects[selectedcharttype+'chart'].setSettings("<settings><values><"+axiskey+"><min>"+json.min+"</min></"+axiskey+"></values></settings>", false);
			chartobjects[selectedcharttype+'chart'].setSettings("<settings><values><"+axiskey+"><max></max></"+axiskey+"></values></settings>", false);
			chartobjects[selectedcharttype+'chart'].setSettings("<settings><plot_area><margins><right>20</right></margins></plot_area></settings>", false);
		}

		// Update the recommendations list.
		var recommendationshtml = "";
		Assanka.$("#chartsuggestions_entities").html("");
		for (var i in json.recommendations) {
			if (!json.recommendations[i].name) continue;
			recommendationshtml += '<div entityentryid="'+json.recommendations[i].id+'" style="display: block;"><span><a href="javascript:selectSuggestion('+json.recommendations[i].id+');">'+json.recommendations[i].name+'</a></span></div>';
		}
		if (recommendationshtml) {
			if (!showingrecommendations) Assanka.$("#chartentitysuggestiontitle").animate({opacity:1}, 300);
			Assanka.$("#chartsuggestions_entities").html(recommendationshtml);
			if (Assanka.$("#chartsuggestions_entities").outerHeight(true) > 15) {
				Assanka.$("#chartsuggestions_entitiesouter").animate({"height":Assanka.$("#chartsuggestions_entities").outerHeight(true)}, 300, "linear");
			} else {
				Assanka.$("#chartsuggestions_entitiesouter").css("height", "auto");			
			}
			showingrecommendations = true;
		} else {
			if (showingrecommendations) {
				Assanka.$("#chartsuggestions_entitiesouter").animate({"height":1}, 300, "linear", function() { Assanka.$("#chartsuggestions_entities").html(""); });
				Assanka.$("#chartentitysuggestiontitle").animate({opacity:0}, 300);
			}
			showingrecommendations = false;
		}
		
		// Delayed set & draw to give the Flash time to refresh
		if (document.all) {
			window.setTimeout(function() { chartobjects[selectedcharttype+'chart'].setData(json.xml, false);   Assanka.$("#"+selectedcharttype+"chartflashcontent").css({"visibility":"visible", "left":0, "top":0}); window.setTimeout(function() { chartobjects[selectedcharttype+'chart'].rebuild(); if (selectedcharttype == 'timeseries') chartobjects[selectedcharttype+'chart'].showAll(); }, 1); }, 300);
		} else {
			window.setTimeout(function() { chartobjects[selectedcharttype+'chart'].setData(json.xml, false);  chartobjects[selectedcharttype+'chart'].rebuild(); if (selectedcharttype == 'timeseries') chartobjects[selectedcharttype+'chart'].showAll(); Assanka.$("#"+selectedcharttype+"chartflashcontent").css({"visibility":"visible", "left":0, "top":0}); }, 300);
		}
		
		// Ensure the graph is in view or notify of update
		graphUpdateNotification();
	});
}

// Graph update notification - if the graph is sufficiently in view, do nothing.  Otherwise,
// show a notification layer.
function graphUpdateNotification() {

	// If the element is already showing, just extend the timer
	if (scrolltocharthidetimer) {
		clearTimeout(scrolltocharthidetimer);
		scrolltocharthidetimer = setTimeout(function() { Assanka.$("#scrolltochart").animate({"top": "+=55"}, 500, "linear", function() { Assanka.$(this).hide(); }); scrolltocharthidetimer = false; }, 3000);
		return;
	}

	// Get the window scroll top
	var scrollposition = window.pageYOffset;
	if (!scrollposition && document.body.scrollTop) scrollposition = document.body.scrollTop;
	if (!scrollposition && document.documentElement && document.documentElement.scrollTop) scrollposition = document.documentElement.scrollTop;
	if (!scrollposition) scrollposition = 0;

	// Get the window height
	var windowheight = window.innerHeight;
	if (!windowheight && document.documentElement && document.documentElement.clientHeight) windowheight = document.documentElement.clientHeight;
	if (!windowheight) windowheight = document.body.clientHeight;

	// Get the window width
	var windowwidth = window.innerWidth;
	if (!windowwidth && document.documentElement && document.documentElement.clientWidth) windowwidth = document.documentElement.clientWidth;
	if (!windowwidth) windowwidth = document.body.clientWidth;
	
	// If the window width is less than the body width, there is a scrollbar - reduce window height.
	if (window.innerHeight && windowwidth - 20 < document.getElementById("fullpage-container").clientWidth) {
		windowheight -= 20;
	}

	// Get the graph top position.
	var ele = Assanka.$("#chart").get(0);
	var chartpositiontop = ele.offsetTop;
	while (ele = ele.offsetParent) {
		chartpositiontop += ele.offsetTop
	}

	// If the graph top is significantly in view, no action is required.
	if (chartpositiontop + 75 < scrollposition + windowheight) return;

	// Otherwise the "graph updated" message should be shown.
	// Determine the offset required for the rankings div
	var ele = Assanka.$("#rankings").get(0);
	var rankingspositiontop = ele.offsetTop;

	while (ele = ele.offsetParent) {
		rankingspositiontop += ele.offsetTop
	}

	var initialposition = scrollposition + windowheight - rankingspositiontop;
	Assanka.$("#scrolltochart").css({"top": initialposition}).one("click", function() {
		Assanka.$("html,body").animate({"scrollTop":chartpositiontop - windowheight + 440}, 500);
		}).show().animate({"top": initialposition - 55}, 500, "linear", function() {

			// Set a timer to hide the element
			scrolltocharthidetimer = setTimeout(function() { Assanka.$("#scrolltochart").animate({"top": "+=55"}, 500, "linear", function() { Assanka.$(this).hide(); }); scrolltocharthidetimer = false; }, 3000);	
		});	
	
}

// Set the charting interface to hidden
function hideCharts(errorstring) {
	Assanka.$("#chart_notenoughdetails").html(errorstring);
	if (chartdrawn[selectedcharttype]) {
		Assanka.$("#"+selectedcharttype+"chartflashcontent").css({"visibility":"hidden"});
		Assanka.$("#chartflashcontentplaceholder").animate({height:0}, 500);
		Assanka.$("#chart_notenoughdetails").slideDown(300);
		Assanka.$("#chartlinksbutton").hide();
		chartdrawn[selectedcharttype] = false;
	}
}

// Add a popup note to an element
function addChartNoteToElementWithId(note, id) {
	var displayvariablenote = displayNoteBubble('<p>'+note+'</p>', Assanka.$("#"+id).get(0));
	Assanka.$("#"+id).mouseover(function() { showtimer = window.setTimeout(displayvariablenote, 50); }).mouseout(hideRankingsNotes);
}

// Record the flash movie when it is initied
function amChartInited(chartid) {
	chartobjects[chartid] = document.getElementById(chartid);
	if (document.all && typeof document.body.style.maxHeight == "undefined") {
		chartobjects[selectedcharttype+'chart'].setSettings("<settings><column><grow_time>0</grow_time></column></settings>", false);
		chartobjects[selectedcharttype+'chart'].setSettings("<settings><indicator><zoomable>false</zoomable></indicator></settings>", false);
	}
}

// Add a transfer-to function for use by entity entry additions
Assanka.$.fn.transferTo = function(target, duration) {
	if (typeof(duration) == "undefined") duration = 500;

	// Create a reference to the element being transferred from.
	var fromele = Assanka.$(this);
	var position = fromele.offset();

	// Create the transfer element
	var transferele = Assanka.$('<div class="charttransfereffect"></div>').appendTo(document.body);
	transferele.css({
		top: position.top,
		left: position.left,
		height: fromele.outerHeight() - 2, // Subtract transfer element's border width
		width: fromele.outerWidth() - 2 // Subtract transfer element's border width
	});

	// Set up the animation position
	position = target.offset();
	var animation = {
		top: position.top,
		left: position.left,
		height: 24,
		width: target.outerWidth() - 2 // Subtract transfer element's border width
	}

	// Trigger the animation
	transferele.animate(animation, duration, "linear", function() {
		transferele.remove();
	});

	return this;
}/**
 * Provide javascript for the maps pages - included on pages via
 * alljavascript.
 *
 * @copyright The Financial Times Limited [All Rights Reserved]
 */

var entitymap = false;
var entitymarkers = new Object();
var entitymarkerlength = 0;
var entitymapplottimer = false
var entitymapcurrentbbox;
var entitymapcurrentzoom = 1;
var entityselection = false;
var entityselectiontitle = false;
var entitymapicons = new Array();
var entitymarkerselectedid = false;
var initialmaploadtime = 0;
var scrolltomaphidetimer = false;

var entitylocationcache = {};
var markertypes = {};


// Initialise maps when necessary
function initMaps() {
	entityselection = Assanka.$("#mapentityselectiondropdown").val();
	entityselectiontitle = Assanka.$("#mapentityselectiondropdown option:selected").text();

	Assanka.$(document).ready(function() { createNoteBubble() });

	if (typeof google.maps.Map != "function") {
		if (initialmaploadtime > 15) {
			alert("Loading the map is taking a very long time, which means there is probably a problem.  Try refreshing (press F5 after clicking OK on this message), and if the problem persists, let us know.");
		} else {
			setTimeout(initMaps, 1000);
		}
		initialmaploadtime++;
		return;
	}

	// Initialise the map and add default controls
	entitymap = new google.maps.Map(document.getElementById('entitymapcontainerinner'), {
		backgroundColor: '#e9decf',
		center: new google.maps.LatLng(24, -6.33),
		mapMaker: false,
		mapTypeControl: false,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		minZoom: 0,
		panControl: false,
		rotateControl: false,
		scaleControl: false,
		scrollwheel: false,
		streetViewControl: false,
		zoom: 1,
		zoomControlOptions: {
			position: google.maps.ControlPosition.TOP_LEFT,
			style: google.maps.ZoomControlStyle.LARGE
		}
	});

	// Store the current bounding box
	google.maps.event.addDomListenerOnce(entitymap, 'bounds_changed', function() {
		entitymapcurrentbbox = entitymap.getBounds();
		entityMapLoadMarkers();
	});

	// Set up event handlers
	google.maps.event.addDomListener(entitymap, 'dragend', entityMapMoveEnd);
	google.maps.event.addDomListener(entitymap, 'zoom_changed', entityMapLoadMarkers);

	// Set up the marker types
	markertypes = {
		cluster:{
			onclick:function(marker) {
				entitymap.setCenter(new google.maps.LatLng(marker.lat, marker.lng));
				entitymap.setZoom(entitymap.getZoom() + 1);
			},
			iconwidth:91,
			iconheight:37,
			iconanchor:[46,19],
			infowindowanchor:[46,19],
			iconfile:function(marker) {
				return '/lib/img/clusters/'+((rankingsstyle == 'falcon')?'f/':'')+marker.count;
			}
		},
		entity:{
			onclick:function(marker) {
				loadEntityLocationDetails(marker.id);
			},
			iconwidth:entitymapiconwidth,
			iconheight:entitymapiconheight,
			iconanchor:[Math.floor(entitymapiconwidth/2),entitymaphasdefaulticon?entitymapiconheight:Math.floor(entitymapiconheight/2)],
			infowindowanchor:[Math.floor(entitymapiconwidth/2), Math.floor(entitymapiconheight/3)],
			iconfile:function(marker) {
				if (entitymaphasdefaulticon) return '/lib/img/'+((rankingsstyle == 'falcon')?'falcon':'')+'defaultmarker.png';
				return '/lib/img/markers/'+seriesslug;
			},
			title:"test"
		}	
	};

	Assanka.$(window).scroll(function() {
		if (scrolltomaphidetimer) {
			clearTimeout(scrolltomaphidetimer);
			scrolltomaphidetimer = false;
			Assanka.$("#scrolltomap").hide();
		}
	});
}

function entityMapMoveEnd() {

	// Ignore movements of less than 2% of the visible area
	var newsw = entitymap.getBounds().getSouthWest();
	var oldsw = entitymapcurrentbbox.getSouthWest();
	var oldne = entitymapcurrentbbox.getNorthEast();
	var verticalchange = Math.abs((newsw.lat() - oldsw.lat()) / (oldne.lat() - oldsw.lat()));
	var horizontalchange = Math.abs((newsw.lng() - oldsw.lng()) / (oldne.lng() - oldsw.lng()));
	if (verticalchange < 0.02 && horizontalchange < 0.02 && entitymap.getZoom() == entitymapcurrentzoom) {
		return;
	}

	// Look up entities within the new map boundaries.
	entityMapLoadMarkers();
}

// Load new entities that fall within the current map view
function entityMapLoadMarkers() {
	
	Assanka.$("#entitymapstatustext").html("Loading locations...").addClass("working");
	Assanka.$("#entitymapstatus").show().animate( { opacity:0.85, width:200 }, { queue: false, duration: 300} );
	
	var bounds = entitymap.getBounds();
	var southwestlng = bounds.getSouthWest().lng();
	var southwestlat = bounds.getSouthWest().lat();
	var northeastlng = bounds.getNorthEast().lng();
	var northeastlat = bounds.getNorthEast().lat();
	
	// If zooming out, delete all markers (do this in addition to redundantmarkers, below, for speed in
	// all other cases)
	if (entitymap.getZoom() < entitymapcurrentzoom) {
		for (var i in entitymarkers) {
			if (entitymarkers[i].obj) {
				entitymarkers[i].obj.setMap(null);
			}
			delete(entitymarkers[i]);
			entitymarkerlength--;
		}
	}
	
	// Store the new bounding box and zoom level
	entitymapcurrentbbox = bounds;
	entitymapcurrentzoom = entitymap.getZoom();
	
	// Cancel any ongoing plot operations
	if (entitymapplottimer) clearTimeout(entitymapplottimer);
	
	// Delete any markers that are outside the new bounding box
	for (var i in entitymarkers) {
		if (entitymarkers[i].lng < southwestlng || entitymarkers[i].lng > northeastlng || entitymarkers[i].lat < southwestlat || entitymarkers[i].lat > northeastlat) {
			if (entitymarkers[i].obj) {
				entitymarkers[i].obj.setMap(null);
			}
			delete(entitymarkers[i]);
			entitymarkerlength--;
		}
	}
	
	// Set up the url to retrieve new markers
	var url = "/lib/ajx/getentitymarkers?x1=" + southwestlng + "&y1=" + southwestlat + "&x2=" + northeastlng + "&y2=" + northeastlat + "&z=" + entitymapcurrentzoom + "&series=" + seriesslug + "&set=" + entityselection + ((entitymarkertodisplay)?"&includemarker=" + entitymarkertodisplay:"");
	
	// Retrieve the new set of markers
	Assanka.$.getJSON(url, function(response) {
		var redundantmarkers = new cloneObject(entitymarkers);
		var entitymarkertotal = response.total + entitymarkerlength;

		// Add each new marker to the markers array
		if (response.markers) for (var i in response.markers) {
			if (isNaN(i)) continue;
			var m = response.markers[i];
			if (!entitymarkers[m.id]) {
				entitymarkers[m.id] = m;
				entitymarkerlength++;
			} else {
				delete redundantmarkers[m.id];
				entitymarkertotal--;
			}
		}
		
		// Remove redundant markers, eg those overwritten by a cluster
		for (var i in redundantmarkers) {
			if (entitymarkers[i].id != entitymarkerselectedid) {
				if (entitymarkers[i].obj) {
					entitymarkers[i].obj.setMap(null);
				}
				delete(entitymarkers[i]);
				entitymarkerlength--;
			}
		}
		
		// If there's no markers, show a message
		if (entitymarkertotal == 0) {
			Assanka.$("#entitymapstatustext").html("There are no results for this area.  Zoom out to see more results.").removeClass("working");
			Assanka.$("#entitymapstatus").animate( { width:400 }, 300);
			return;	
		}
		
		// Set the markers to be plotted
		entitymapplottimer = window.setTimeout("entityMapPlotMarkers(0)", 10);
	});
}

function entityMapPlotMarkers(plotfrom) {
	var plotsperiteration = 50;
	var plotsthisiteration = 0;
	var circlerad = 0.00024;
	var zoom = entitymap.getZoom();
	var conflictpx = 10;
	var conflictdistance_lat = conflictpx / Math.pow(2, zoom);
	var conflictdistance_lng = conflictpx / (Math.pow(2, zoom) * 0.77162458338772);
	var newplots = [];
	if (!plotfrom && zoom >= 5) Assanka.$("#entitymapstatustext").html("Drawing locations...");
	for (var i in entitymarkers) {
		if (plotfrom) {
			if (i == plotfrom) plotfrom = false;
			plotsperiteration++;
			plotsthisiteration++;
			continue;
		}
		if (!entitymarkers[i].obj) {
			delete entitymarkers[i].conflictswith;
			var conflicts = false;
			for (var y in entitymarkers) {
				if (entitymarkers[y].obj && Math.abs(entitymarkers[i].lat - entitymarkers[y].lat) < conflictdistance_lat && Math.abs(entitymarkers[i].lng - entitymarkers[y].lng) < conflictdistance_lng) {
					entitymarkers[i].conflictswith = y;
					if (entitymarkers[y].overlapping) entitymarkers[y].overlapping++; else entitymarkers[y].overlapping = 1;
					break;
				}
			}
			if (!entitymarkers[i].conflictswith) {
				entityMapCreateMarker(i);
				entitymarkers[i].obj.setMap(entitymap);

			} else {
				if (zoom > 16) {

					// Plot the marker, but move it slightly:
					var thecircle = 1;
					var theang = 6.282/6;
					var theoffset = 1;

					if (entitymarkers[entitymarkers[i].conflictswith].overlapping > 6){
						theoffset = 7;
						theang = 6.282/12;
						thecircle = 2;
					}

					if (entitymarkers[entitymarkers[i].conflictswith].overlapping > 18){
						theoffset = 19;
						theang = 6.282/18;
						thecircle = 3;
					}

					if (entitymarkers[entitymarkers[i].conflictswith].overlapping>36){
						theoffset = 37;
						theang = 6.282/24;
						thecircle = 4;
					}

					theang = (entitymarkers[entitymarkers[i].conflictswith].overlapping-theoffset) * theang;
					thecircle = thecircle*circlerad;

					dx = thecircle * Math.sin(theang);
					dy = thecircle * Math.cos(theang) * 0.7;

					entitymarkers[i].lat = parseFloat(entitymarkers[entitymarkers[i].conflictswith].lat) + dy;
					entitymarkers[i].lng = parseFloat(entitymarkers[entitymarkers[i].conflictswith].lng) + dx;
					entityMapCreateMarker(i);
					entitymarkers[i].obj.setMap(entitymap);
					
				// The currently to-highlight marker is conflicting with a previously plotted marker
				} else {
					if (entitymarkers[i].id == entitymarkertodisplay) {
						if (entitymarkers[entitymarkers[i].conflictswith].obj) {
							entitymarkers[entitymarkers[i].conflictswith].obj.setMap(null);
						}
						entitymarkers[entitymarkers[i].conflictswith].conflictswith = i;
						delete(entitymarkers[entitymarkers[i].conflictswith].obj);
						delete(entitymarkers[i].conflictswith);
						entityMapCreateMarker(i);
						entitymarkers[i].obj.setMap(entitymap);
					}
				}
			}
		}
		plotsthisiteration++;
		if (plotsthisiteration >= plotsperiteration) {
			plottimer = window.setTimeout("entityMapPlotMarkers('"+i+"')", 10);
			return true;
		}
	}

	// If a marker is set to autodisplay, and it has been plotted, highlight it. At the same time,
	// count the number of markers displayed
	var hiddencount = 0;
	for (var y in entitymarkers) {
		if (typeof(entitymarkers[y].obj) == "object") {
			if (entitymarkers[y].id == entitymarkertodisplay) {
				entitymarkertodisplay = false;
				entityMapMarkerClick(entitymarkers[y]);
			}
		} else {
			hiddencount++;
		}
	}

	if (hiddencount) {
		Assanka.$("#entitymapstatustext").html(hiddencount+" overlapping result"+((hiddencount==1)?" has":"s have")+" been hidden - zoom in further to reveal.").removeClass("working");
		Assanka.$("#entitymapstatus").animate( { width:400 }, 300);
	} else {
		Assanka.$("#entitymapstatus").animate( { opacity:0 }, { queue: false, duration: 300, complete:function() { Assanka.$("#entitymapstatus").hide(); } } );
	}

	for (var y in entitymarkers) {
		if (entitymarkers[y]["conflictswith"]) entitymarkers[y]["conflictswith"] = NaN;
		if (entitymarkers[y]["overlapping"]) entitymarkers[y]["overlapping"] = NaN;
	}
}

function entityMapCreateMarker(id) {
	var latlng = new google.maps.LatLng(parseFloat(entitymarkers[id].lat), parseFloat(entitymarkers[id].lng));

	if (typeof markertypes[entitymarkers[id].t].iconfile == "function") {
		var iconfile = markertypes[entitymarkers[id].t].iconfile(entitymarkers[id]);
	} else {
		var iconfile = markertypes[entitymarkers[id].t].iconfile;
	}
	if (!entitymapicons[iconfile]) {
		var baseicon = markertypes[entitymarkers[id].t];
		entitymapicons[iconfile] = {
			url: iconfile,
			size: new google.maps.Size(baseicon.iconwidth, baseicon.iconheight),
			anchor: new google.maps.Point(baseicon.iconanchor[0], baseicon.iconanchor[1])
		};
	}
	var markerobj = new google.maps.Marker({
		position: latlng,
		icon: entitymapicons[iconfile],
		title: entitymarkers[id].name
	});
	google.maps.event.addDomListener(markerobj, 'click', function() {
		entityMapMarkerClick(entitymarkers[id]);
	});
	entitymarkers[id].obj = markerobj;
}

function entityMapMarkerClick(marker) {
	if (markertypes[marker.t].onclick) markertypes[marker.t].onclick(marker);	
}

// Update the ranking selection - triggered by clicking the "set" button next to the rankings dropdown
function selectMapEntities() {
	Assanka.$(".mapentityselectionbutton").blur();
	entityselection = Assanka.$("#mapentityselectiondropdown").val();
	entityselectiontitle = Assanka.$("#mapentityselectiondropdown option:selected").text();
	
	// Reload the map markers
	entityMapLoadMarkers();
}

// Load details for a selected entity location, using the global cache of details if appropriate
function loadEntityLocationDetails(entitylocationid) {
	Assanka.$("#entitymaplocationdetailsouter").addClass("loading").show();
	if (entitylocationcache[entitylocationid]) {
		Assanka.$("#entitymaplocationdetails").addClass("animating").slideUp(200, function() {
			displayEntityLocationDetails(entitylocationcache[entitylocationid]);
		});
		return true;
	}
	
	Assanka.$("#entitymaplocationdetails").addClass("animating").slideUp(200);

	// Request the information for this entity location
	// Retrieve the new set of markers
	Assanka.$.getJSON('/lib/ajx/getentitydetails', {'entitylocationid':entitylocationid}, function(response) {
		var html = "";
		
		if (response.entityentryhtml) html += response.entityentryhtml;
		
		var titlehtml = '<h2><a href="/'+seriesslug+'/'+response.slug+'">'+response.name+((response.isfeatured)?'<img id="entitylocation'+entitylocationid+'featuredicon" alt="Featured '+response.entityname+'" src="'+response.cdndetails+'/lib/img/featured.gif" class="featuredicon" title="This is a featured '+response.entityname+' - click to see the additional detail available." />':'')+'</a></h2>';
		if (rankingsstyle == 'falcon') {
			html = titlehtml + html;
		} else {
			html += titlehtml;
		}

		html += '<a href="/'+seriesslug+'/'+response.slug+'" class="entitylocationlogo"><img src="'+response.cdndetails+'/lib/img/logos/entitylocationthumbnail/'+response.slug+((rankingsstyle == 'falcon')?'?s=f':'')+'" alt="'+response.name+' logo" /></a>';

		// Add to cache and display
		entitylocationcache[entitylocationid] = html;
		displayEntityLocationDetails(html);
	});
	
}

// Draw the details for a selected entity location.
function displayEntityLocationDetails(html) {
	html += '<div class="heightlessclearer"></div>';
	Assanka.$("#entitymaplocationdetails").html(html).slideDown(400, function() { Assanka.$("#entitymaplocationdetails").removeClass("animating"); });
	Assanka.$("#entitymaplocationdetails .featuredicon").each(function() {
		addMapNoteToElementWithId(Assanka.$(this).attr("title"), Assanka.$(this).attr("id"));
		Assanka.$(this).attr("title", "");
	});
	Assanka.$("#entitymaplocationdetailsouter").removeClass("loading");

	detailUpdateNotification();
}

// Entity update notification - if the detail section is sufficiently in view, do nothing.  Otherwise,
// show a notification layer.
function detailUpdateNotification() {

	// If the element is already showing, just extend the timer
	if (scrolltomaphidetimer) {
		clearTimeout(scrolltomaphidetimer);
		scrolltomaphidetimer = setTimeout(function() { Assanka.$("#scrolltomap").animate({"top": "+=55"}, 500, "linear", function() { Assanka.$(this).hide(); }); scrolltocharthidetimer = false; }, 3000);
		return;
	}

	// Get the window scroll top
	var scrollposition = window.pageYOffset;
	if (!scrollposition && document.body.scrollTop) scrollposition = document.body.scrollTop;
	if (!scrollposition && document.documentElement && document.documentElement.scrollTop) scrollposition = document.documentElement.scrollTop;
	if (!scrollposition) scrollposition = 0;

	// Get the window height
	var windowheight = window.innerHeight;
	if (!windowheight && document.documentElement && document.documentElement.clientHeight) windowheight = document.documentElement.clientHeight;
	if (!windowheight) windowheight = document.body.clientHeight;

	// Get the window width
	var windowwidth = window.innerWidth;
	if (!windowwidth && document.documentElement && document.documentElement.clientWidth) windowwidth = document.documentElement.clientWidth;
	if (!windowwidth) windowwidth = document.body.clientWidth;
	
	// If the window width is less than the body width, there is a scrollbar - reduce window height.
	if (window.innerHeight && windowwidth - 20 < document.getElementById("fullpage-container").clientWidth) {
		windowheight -= 20;
	}

	// Get the detail top position.
	var ele = Assanka.$("#entitymaplocationdetailsouter").get(0);
	var mappositiontop = ele.offsetTop;
	while (ele = ele.offsetParent) {
		mappositiontop += ele.offsetTop
	}

	// If the detail top is significantly in view, no action is required.
	if (mappositiontop + 30 < scrollposition + windowheight) return;

	// Otherwise the "detail updated" message should be shown.
	// Determine the offset required for the rankings div
	var ele = Assanka.$("#rankings").get(0);
	var rankingspositiontop = ele.offsetTop;

	while (ele = ele.offsetParent) {
		rankingspositiontop += ele.offsetTop
	}

	var initialposition = scrollposition + windowheight - rankingspositiontop;
	Assanka.$("#scrolltomap").css({"top": initialposition}).one("click", function() {
		Assanka.$("html,body").animate({"scrollTop":mappositiontop - windowheight + Assanka.$("#entitymaplocationdetailsouter").height() + 10 }, 500);
		}).show().animate({"top": initialposition - 55}, 500, "linear", function() {

			// Set a timer to hide the element
			scrolltomaphidetimer = setTimeout(function() { Assanka.$("#scrolltomap").animate({"top": "+=55"}, 500, "linear", function() { Assanka.$(this).hide(); }); scrolltomaphidetimer = false; }, 3000);
		});	
	
}

// Add a popup note to an element
function addMapNoteToElementWithId(note, id) {
	var displayvariablenote = displayNoteBubble('<p>'+note+'</p>', Assanka.$("#"+id).get(0));
	Assanka.$("#"+id).mouseover(function() { showtimer = window.setTimeout(displayvariablenote, 50); }).mouseout(hideRankingsNotes);
}

// Utility 'class' to clone an object.
function cloneObject(what) {
    for (i in what) {
        this[i] = what[i];
    }
}
/*
 * jQuery Cycle Plugin (core engine only)
 * Examples and documentation at: http://jquery.malsup.com/cycle/
 * Copyright (c) 2007-2009 M. Alsup
 * Version: 2.54 (23-FEB-2009)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 * Requires: jQuery v1.2.3 or later
 *
 * Originally based on the work of:
 *	1) Matt Oakes (http://portfolio.gizone.co.uk/applications/slideshow/)
 *	2) Torsten Baldes (http://medienfreunde.com/lab/innerfade/)
 *	3) Benjamin Sterling (http://www.benjaminsterling.com/experiments/jqShuffle/)
 */
;(function($){var ver="2.54";if($.support==undefined){$.support={opacity:!($.browser.msie&&/MSIE 6.0/.test(navigator.userAgent))};}function log(){if(window.console&&window.console.log){window.console.log("[cycle] "+Array.prototype.join.call(arguments,""));}}$.fn.cycle=function(options,arg2){if(this.length==0&&options!="stop"){if(!$.isReady&&this.selector){log("DOM not ready, queuing slideshow");var o={s:this.selector,c:this.context};$(function(){$(o.s,o.c).cycle(options,arg2);});return;}log("terminating; zero elements found by selector"+($.isReady?"":" (DOM not ready)"));return this;}return this.each(function(){options=handleArguments(this,options,arg2);if(options===false){return;}if(this.cycleTimeout){clearTimeout(this.cycleTimeout);}this.cycleTimeout=this.cyclePause=0;var $cont=$(this);var $slides=options.slideExpr?$(options.slideExpr,this):$cont.children();var els=$slides.get();if(els.length<2){log("terminating; too few slides: "+els.length);return;}var opts=buildOptions($cont,$slides,els,options);if(opts===false){return;}if(opts.timeout||opts.continuous){this.cycleTimeout=setTimeout(function(){go(els,opts,0,!opts.rev);},opts.continuous?10:opts.timeout+(opts.delay||0));}});};function handleArguments(cont,options,arg2){if(cont.cycleStop==undefined){cont.cycleStop=0;}if(options===undefined||options===null){options={};}if(options.constructor==String){switch(options){case"stop":cont.cycleStop++;if(cont.cycleTimeout){clearTimeout(cont.cycleTimeout);}cont.cycleTimeout=0;$(cont).removeData("cycle.opts");return false;case"pause":cont.cyclePause=1;return false;case"resume":cont.cyclePause=0;if(arg2===true){options=$(cont).data("cycle.opts");if(!options){log("options not found, can not resume");return;}if(cont.cycleTimeout){clearTimeout(cont.cycleTimeout);cont.cycleTimeout=0;}go(options.elements,options,1,1);}return false;default:options={fx:options};}}else{if(options.constructor==Number){var num=options;options=$(cont).data("cycle.opts");if(!options){log("options not found, can not advance slide");return false;}if(num<0||num>=options.elements.length){log("invalid slide index: "+num);return false;}options.nextSlide=num;if(cont.cycleTimeout){clearTimeout(this.cycleTimeout);cont.cycleTimeout=0;}if(typeof arg2=="string"){options.oneTimeFx=arg2;}go(options.elements,options,1,num>=options.currSlide);return false;}}return options;}function buildOptions($cont,$slides,els,options){var opts=$.extend({},$.fn.cycle.defaults,options||{},$.metadata?$cont.metadata():$.meta?$cont.data():{});if(opts.autostop){opts.countdown=opts.autostopCount||els.length;}var cont=$cont[0];$cont.data("cycle.opts",opts);opts.$cont=$cont;opts.stopCount=cont.cycleStop;opts.elements=els;opts.before=opts.before?[opts.before]:[];opts.after=opts.after?[opts.after]:[];opts.after.unshift(function(){opts.busy=0;});if(!$.support.opacity&&opts.cleartype){opts.after.push(function(){this.style.removeAttribute("filter");});}if(opts.continuous){opts.after.push(function(){go(els,opts,0,!opts.rev);});}saveOriginalOpts(opts);if(!$.support.opacity&&opts.cleartype&&!opts.cleartypeNoBg){clearTypeFix($slides);}if($cont.css("position")=="static"){$cont.css("position","relative");}if(opts.width){$cont.width(opts.width);}if(opts.height&&opts.height!="auto"){$cont.height(opts.height);}if(opts.startingSlide){opts.startingSlide=parseInt(opts.startingSlide);}if(opts.random){opts.randomMap=[];for(var i=0;i<els.length;i++){opts.randomMap.push(i);}opts.randomMap.sort(function(a,b){return Math.random()-0.5;});opts.randomIndex=0;opts.startingSlide=opts.randomMap[0];}else{if(opts.startingSlide>=els.length){opts.startingSlide=0;}}opts.currSlide=opts.startingSlide=opts.startingSlide||0;var first=opts.startingSlide;$slides.css({position:"absolute",top:0,left:0}).hide().each(function(i){var z=first?i>=first?els.length-(i-first):first-i:els.length-i;$(this).css("z-index",z);});$(els[first]).css("opacity",1).show();if(!$.support.opacity&&opts.cleartype){els[first].style.removeAttribute("filter");}if(opts.fit&&opts.width){$slides.width(opts.width);}if(opts.fit&&opts.height&&opts.height!="auto"){$slides.height(opts.height);}var reshape=opts.containerResize&&!$cont.innerHeight();if(reshape){var maxw=0,maxh=0;for(var i=0;i<els.length;i++){var $e=$(els[i]),e=$e[0],w=$e.outerWidth(),h=$e.outerHeight();if(!w){w=e.offsetWidth;}if(!h){h=e.offsetHeight;}maxw=w>maxw?w:maxw;maxh=h>maxh?h:maxh;}if(maxw>0&&maxh>0){$cont.css({width:maxw+"px",height:maxh+"px"});}}if(opts.pause){$cont.hover(function(){this.cyclePause++;},function(){this.cyclePause--;});}supportMultiTransitions(opts);if(!opts.multiFx){var init=$.fn.cycle.transitions[opts.fx];if($.isFunction(init)){init($cont,$slides,opts);}else{if(opts.fx!="custom"&&!opts.multiFx){log("unknown transition: "+opts.fx,"; slideshow terminating");return false;}}}$slides.each(function(){var $el=$(this);this.cycleH=(opts.fit&&opts.height)?opts.height:$el.height();this.cycleW=(opts.fit&&opts.width)?opts.width:$el.width();});opts.cssBefore=opts.cssBefore||{};opts.animIn=opts.animIn||{};opts.animOut=opts.animOut||{};$slides.not(":eq("+first+")").css(opts.cssBefore);if(opts.cssFirst){$($slides[first]).css(opts.cssFirst);}if(opts.timeout){opts.timeout=parseInt(opts.timeout);if(opts.speed.constructor==String){opts.speed=$.fx.speeds[opts.speed]||parseInt(opts.speed);}if(!opts.sync){opts.speed=opts.speed/2;}while((opts.timeout-opts.speed)<250){opts.timeout+=opts.speed;}}if(opts.easing){opts.easeIn=opts.easeOut=opts.easing;}if(!opts.speedIn){opts.speedIn=opts.speed;}if(!opts.speedOut){opts.speedOut=opts.speed;}opts.slideCount=els.length;opts.currSlide=opts.lastSlide=first;if(opts.random){opts.nextSlide=opts.currSlide;if(++opts.randomIndex==els.length){opts.randomIndex=0;}opts.nextSlide=opts.randomMap[opts.randomIndex];}else{opts.nextSlide=opts.startingSlide>=(els.length-1)?0:opts.startingSlide+1;}var e0=$slides[first];if(opts.before.length){opts.before[0].apply(e0,[e0,e0,opts,true]);}if(opts.after.length>1){opts.after[1].apply(e0,[e0,e0,opts,true]);}if(opts.next){$(opts.next).click(function(){return advance(opts,opts.rev?-1:1);});}if(opts.prev){$(opts.prev).click(function(){return advance(opts,opts.rev?1:-1);});}if(opts.pager){buildPager(els,opts);}exposeAddSlide(opts,els);return opts;}function saveOriginalOpts(opts){opts.original={before:[],after:[]};opts.original.cssBefore=$.extend({},opts.cssBefore);opts.original.cssAfter=$.extend({},opts.cssAfter);opts.original.animIn=$.extend({},opts.animIn);opts.original.animOut=$.extend({},opts.animOut);$.each(opts.before,function(){opts.original.before.push(this);});$.each(opts.after,function(){opts.original.after.push(this);});}function supportMultiTransitions(opts){var txs=$.fn.cycle.transitions;if(opts.fx.indexOf(",")>0){opts.multiFx=true;opts.fxs=opts.fx.replace(/\s*/g,"").split(",");for(var i=0;i<opts.fxs.length;i++){var fx=opts.fxs[i];var tx=txs[fx];if(!tx||!txs.hasOwnProperty(fx)||!$.isFunction(tx)){log("discarding unknowtn transition: ",fx);opts.fxs.splice(i,1);i--;}}if(!opts.fxs.length){log("No valid transitions named; slideshow terminating.");return false;}}else{if(opts.fx=="all"){opts.multiFx=true;opts.fxs=[];for(p in txs){var tx=txs[p];if(txs.hasOwnProperty(p)&&$.isFunction(tx)){opts.fxs.push(p);}}}}if(opts.multiFx&&opts.randomizeEffects){var r1=Math.floor(Math.random()*20)+30;for(var i=0;i<r1;i++){var r2=Math.floor(Math.random()*opts.fxs.length);opts.fxs.push(opts.fxs.splice(r2,1)[0]);}log("randomized fx sequence: ",opts.fxs);}}function exposeAddSlide(opts,els){opts.addSlide=function(newSlide,prepend){var $s=$(newSlide),s=$s[0];if(!opts.autostopCount){opts.countdown++;}els[prepend?"unshift":"push"](s);if(opts.els){opts.els[prepend?"unshift":"push"](s);}opts.slideCount=els.length;$s.css("position","absolute");$s[prepend?"prependTo":"appendTo"](opts.$cont);if(prepend){opts.currSlide++;opts.nextSlide++;}if(!$.support.opacity&&opts.cleartype&&!opts.cleartypeNoBg){clearTypeFix($s);}if(opts.fit&&opts.width){$s.width(opts.width);}if(opts.fit&&opts.height&&opts.height!="auto"){$slides.height(opts.height);}s.cycleH=(opts.fit&&opts.height)?opts.height:$s.height();s.cycleW=(opts.fit&&opts.width)?opts.width:$s.width();$s.css(opts.cssBefore);if(opts.pager){$.fn.cycle.createPagerAnchor(els.length-1,s,$(opts.pager),els,opts);}if($.isFunction(opts.onAddSlide)){opts.onAddSlide($s);}else{$s.hide();}};}$.fn.cycle.resetState=function(opts,fx){var fx=fx||opts.fx;opts.before=[];opts.after=[];opts.cssBefore=$.extend({},opts.original.cssBefore);opts.cssAfter=$.extend({},opts.original.cssAfter);opts.animIn=$.extend({},opts.original.animIn);opts.animOut=$.extend({},opts.original.animOut);opts.fxFn=null;$.each(opts.original.before,function(){opts.before.push(this);});$.each(opts.original.after,function(){opts.after.push(this);});var init=$.fn.cycle.transitions[fx];if($.isFunction(init)){init(opts.$cont,$(opts.elements),opts);}};function go(els,opts,manual,fwd){if(manual&&opts.busy){$(els).stop(true,true);opts.busy=false;}if(opts.busy){return;}var p=opts.$cont[0],curr=els[opts.currSlide],next=els[opts.nextSlide];if(p.cycleStop!=opts.stopCount||p.cycleTimeout===0&&!manual){return;}if(!manual&&!p.cyclePause&&((opts.autostop&&(--opts.countdown<=0))||(opts.nowrap&&!opts.random&&opts.nextSlide<opts.currSlide))){if(opts.end){opts.end(opts);}return;}if(manual||!p.cyclePause){var fx=opts.fx;curr.cycleH=curr.cycleH||curr.offsetHeight;curr.cycleW=curr.cycleW||curr.offsetWidth;next.cycleH=next.cycleH||next.offsetHeight;next.cycleW=next.cycleW||next.offsetWidth;if(opts.multiFx){if(opts.lastFx==undefined||++opts.lastFx>=opts.fxs.length){opts.lastFx=0;}fx=opts.fxs[opts.lastFx];opts.currFx=fx;}if(opts.oneTimeFx){fx=opts.oneTimeFx;opts.oneTimeFx=null;}$.fn.cycle.resetState(opts,fx);if(opts.before.length){$.each(opts.before,function(i,o){if(p.cycleStop!=opts.stopCount){return;}o.apply(next,[curr,next,opts,fwd]);});}var after=function(){$.each(opts.after,function(i,o){if(p.cycleStop!=opts.stopCount){return;}o.apply(next,[curr,next,opts,fwd]);});};if(opts.nextSlide!=opts.currSlide){opts.busy=1;if(opts.fxFn){opts.fxFn(curr,next,opts,after,fwd);}else{if($.isFunction($.fn.cycle[opts.fx])){$.fn.cycle[opts.fx](curr,next,opts,after);}else{$.fn.cycle.custom(curr,next,opts,after,manual&&opts.fastOnEvent);}}}opts.lastSlide=opts.currSlide;if(opts.random){opts.currSlide=opts.nextSlide;if(++opts.randomIndex==els.length){opts.randomIndex=0;}opts.nextSlide=opts.randomMap[opts.randomIndex];}else{var roll=(opts.nextSlide+1)==els.length;opts.nextSlide=roll?0:opts.nextSlide+1;opts.currSlide=roll?els.length-1:opts.nextSlide-1;}if(opts.pager){$.fn.cycle.updateActivePagerLink(opts.pager,opts.currSlide);}}var ms=0;if(opts.timeout&&!opts.continuous){ms=getTimeout(curr,next,opts,fwd);}else{if(opts.continuous&&p.cyclePause){ms=10;}}if(ms>0){p.cycleTimeout=setTimeout(function(){go(els,opts,0,!opts.rev);},ms);}}$.fn.cycle.updateActivePagerLink=function(pager,currSlide){$(pager).find("a").removeClass("activeSlide").filter("a:eq("+currSlide+")").addClass("activeSlide");};function getTimeout(curr,next,opts,fwd){if(opts.timeoutFn){var t=opts.timeoutFn(curr,next,opts,fwd);if(t!==false){return t;}}return opts.timeout;}$.fn.cycle.next=function(opts){advance(opts,opts.rev?-1:1);};$.fn.cycle.prev=function(opts){advance(opts,opts.rev?1:-1);};function advance(opts,val){var els=opts.elements;var p=opts.$cont[0],timeout=p.cycleTimeout;if(timeout){clearTimeout(timeout);p.cycleTimeout=0;}if(opts.random&&val<0){opts.randomIndex--;if(--opts.randomIndex==-2){opts.randomIndex=els.length-2;}else{if(opts.randomIndex==-1){opts.randomIndex=els.length-1;}}opts.nextSlide=opts.randomMap[opts.randomIndex];}else{if(opts.random){if(++opts.randomIndex==els.length){opts.randomIndex=0;}opts.nextSlide=opts.randomMap[opts.randomIndex];}else{opts.nextSlide=opts.currSlide+val;if(opts.nextSlide<0){if(opts.nowrap){return false;}opts.nextSlide=els.length-1;}else{if(opts.nextSlide>=els.length){if(opts.nowrap){return false;}opts.nextSlide=0;}}}}if($.isFunction(opts.prevNextClick)){opts.prevNextClick(val>0,opts.nextSlide,els[opts.nextSlide]);}go(els,opts,1,val>=0);return false;}function buildPager(els,opts){var $p=$(opts.pager);$.each(els,function(i,o){$.fn.cycle.createPagerAnchor(i,o,$p,els,opts);});$.fn.cycle.updateActivePagerLink(opts.pager,opts.startingSlide);}$.fn.cycle.createPagerAnchor=function(i,el,$p,els,opts){var a=($.isFunction(opts.pagerAnchorBuilder))?opts.pagerAnchorBuilder(i,el):'<a href="#">'+(i+1)+"</a>";if(!a){return;}var $a=$(a);if($a.parents("body").length==0){$a.appendTo($p);}$a.bind(opts.pagerEvent,function(){opts.nextSlide=i;var p=opts.$cont[0],timeout=p.cycleTimeout;if(timeout){clearTimeout(timeout);p.cycleTimeout=0;}if($.isFunction(opts.pagerClick)){opts.pagerClick(opts.nextSlide,els[opts.nextSlide]);}go(els,opts,1,opts.currSlide<i);return false;});if(opts.pauseOnPagerHover){$a.hover(function(){opts.$cont[0].cyclePause++;},function(){opts.$cont[0].cyclePause--;});}};$.fn.cycle.hopsFromLast=function(opts,fwd){var hops,l=opts.lastSlide,c=opts.currSlide;if(fwd){hops=c>l?c-l:opts.slideCount-l;}else{hops=c<l?l-c:l+opts.slideCount-c;}return hops;};function clearTypeFix($slides){function hex(s){var s=parseInt(s).toString(16);return s.length<2?"0"+s:s;}function getBg(e){for(;e&&e.nodeName.toLowerCase()!="html";e=e.parentNode){var v=$.css(e,"background-color");if(v.indexOf("rgb")>=0){var rgb=v.match(/\d+/g);return"#"+hex(rgb[0])+hex(rgb[1])+hex(rgb[2]);}if(v&&v!="transparent"){return v;}}return"#ffffff";}$slides.each(function(){$(this).css("background-color",getBg(this));});}$.fn.cycle.commonReset=function(curr,next,opts,w,h,rev){$(opts.elements).not(curr).hide();opts.cssBefore.opacity=1;opts.cssBefore.display="block";if(w!==false&&next.cycleW>0){opts.cssBefore.width=next.cycleW;}if(h!==false&&next.cycleH>0){opts.cssBefore.height=next.cycleH;}opts.cssAfter=opts.cssAfter||{};opts.cssAfter.display="none";$(curr).css("zIndex",opts.slideCount+(rev===true?1:0));$(next).css("zIndex",opts.slideCount+(rev===true?0:1));};$.fn.cycle.custom=function(curr,next,opts,cb,speedOverride){var $l=$(curr),$n=$(next);var speedIn=opts.speedIn,speedOut=opts.speedOut,easeIn=opts.easeIn,easeOut=opts.easeOut;$n.css(opts.cssBefore);if(speedOverride){if(typeof speedOverride=="number"){speedIn=speedOut=speedOverride;}else{speedIn=speedOut=1;}easeIn=easeOut=null;}var fn=function(){$n.animate(opts.animIn,speedIn,easeIn,cb);};$l.animate(opts.animOut,speedOut,easeOut,function(){if(opts.cssAfter){$l.css(opts.cssAfter);}if(!opts.sync){fn();}});if(opts.sync){fn();}};$.fn.cycle.transitions={fade:function($cont,$slides,opts){$slides.not(":eq("+opts.currSlide+")").css("opacity",0);opts.before.push(function(curr,next,opts){$.fn.cycle.commonReset(curr,next,opts);opts.cssBefore.opacity=0;});opts.animIn={opacity:1};opts.animOut={opacity:0};opts.cssBefore={top:0,left:0};}};$.fn.cycle.ver=function(){return ver;};$.fn.cycle.defaults={fx:"fade",timeout:4000,timeoutFn:null,continuous:0,speed:1000,speedIn:null,speedOut:null,next:null,prev:null,prevNextClick:null,pager:null,pagerClick:null,pagerEvent:"click",pagerAnchorBuilder:null,before:null,after:null,end:null,easing:null,easeIn:null,easeOut:null,shuffle:null,animIn:null,animOut:null,cssBefore:null,cssAfter:null,fxFn:null,height:"auto",startingSlide:0,sync:1,random:0,fit:0,containerResize:1,pause:0,pauseOnPagerHover:0,autostop:0,autostopCount:0,delay:0,slideExpr:null,cleartype:!$.support.opacity,nowrap:0,fastOnEvent:0,randomizeEffects:1,rev:0};})(jQuery);var mapwidgetmaps = {};
var mapwidgetmarkers = {};
var mapwidgetinfowindows = {};
var currentmapaddresses = {};

// Initialise a map widget
function initialiseMapWidget(mapid, lat, lng, zoom, addressdetails, initwidth, initheight) {
	var latlng = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
	mapwidgetmaps[mapid] = new google.maps.Map(document.getElementById('mapwidget' + mapid), {
		backgroundColor: '#e9decf',
		center: latlng,
		mapMaker: false,
		mapTypeControl: false,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		minZoom: 0,
		panControl: false,
		rotateControl: false,
		scaleControl: false,
		scrollwheel: false,
		streetViewControl: false,
		zoom: parseInt(zoom),
		zoomControlOptions: {
			position: google.maps.ControlPosition.TOP_LEFT,
			style: google.maps.ZoomControlStyle.SMALL
		}
	});
	mapwidgetmarkers[mapid] = new google.maps.Marker({
		clickable: true,
		draggable: false,
		flat: false,
		map: mapwidgetmaps[mapid],
		position: latlng,
		visible: true
	});

	currentmapaddresses[mapid] = addressdetails;

	google.maps.event.addDomListener(mapwidgetmarkers[mapid], 'click', function() {
		if (typeof(this.getPosition) == 'function' && currentmapaddresses[mapid]) {
			mapwidgetinfowindows[mapid] = new google.maps.InfoWindow({
				content: currentmapaddresses[mapid],
				disableAutoPan: false,
				maxWidth: 200,
				pixelOffset: new google.maps.Size(0, -28),
				position: this.getPosition()
			});
			mapwidgetinfowindows[mapid].open(mapwidgetmaps[mapid]);
		}
	});
}

// Update the location view in a map widget
function updateMapWidget(mapid, lat, lng, zoom, addressdetails, popuplinkfunction) {
	if (mapwidgetinfowindows[mapid]) {
		mapwidgetinfowindows[mapid].close();
	}

	var latlng = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));

	mapwidgetmaps[mapid].panTo(latlng);
	mapwidgetmaps[mapid].setZoom(parseInt(zoom));
	mapwidgetmarkers[mapid].setPosition(latlng);

	currentmapaddresses[mapid] = addressdetails;
	mapwidgetinfowindows[mapid] = new google.maps.InfoWindow({
		content: currentmapaddresses[mapid],
		disableAutoPan: false,
		maxWidth: 300,
		pixelOffset: new google.maps.Size(0, -28),
		position: latlng
	});

	document.getElementById('maplink' + mapid).onclick = popuplinkfunction;
}

// Provide a function to animate slideshows.
function setSlideshowToAnimate(slideshowref) {
	if (jQuery("img", slideshowref).length > 1) {
		var gparentele = slideshowref.parent().parent();
		jQuery(".slidecontainerinner", slideshowref).cycle({fx:"fade", speed:1000, timeout:4000, pause:1, prev:"#"+jQuery("span.left", gparentele).get(0).id, next:"#"+jQuery("span.right", gparentele).get(0).id, before:function(currSlideElement, nextSlideElement, options, forwardFlag) { slideshowref.find(".caption p").fadeOut(400, function() { jQuery(this).html(nextSlideElement.alt.replace(/([0-9]+\/[0-9]+)/, "<strong>$1</strong>")).fadeIn(400);}); }});
		jQuery("span", gparentele).css({opacity:0, display:"block"});
		jQuery(".caption", gparentele).css({opacity:0.7});
		gparentele.bind("mouseover", function() {
			jQuery("span", jQuery(this)).animate({opacity:1}, {duration:250, queue: false});
		});
		gparentele.bind("mouseout", function() {
			jQuery("span", jQuery(this)).animate({opacity:0}, {duration:250, queue: false});
		});
	}
}

// Support link tracking across multiple sites
function widgetTrackingEvent(item, isexternal, actioncategory, actiontype, callbackfunction) {
	if (typeof(callbackfunction) == 'undefined') callbackfunction = false;

	// Favour Site Intelligence tracking
	if (typeof(SiTrackEvent) == 'function') {
		if (isexternal) {
			return SiTrackExternalLink(item, callbackfunction);
		} else {
			SiTrackEvent(item);
			if (callbackfunction) callbackfunction();
			return true;
		}

	// Otherwise try Google
	} else if (typeof(pageTracker) == 'object') {
		try {
			pageTracker._trackEvent(actioncategory, actiontype, item.href);
		} catch (err) {}
		if (callbackfunction) callbackfunction();
		return true;
	}
}