JHunz's Absinthe Minder

By JHunz Last update Apr 13, 2008 — Installed 127,034 times. Daily Installs: 147, 142, 175, 177, 173, 164, 154, 163, 172, 166, 166, 169, 150, 155, 151, 163, 172, 166, 148, 151, 142, 146, 146, 154, 150, 163, 131, 146, 130, 142, 164, 141

Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)

// ==UserScript==
// @name           JHunz's Absinthe Minder
// @namespace      hunsley@gmail.com
// @description    Kingdom of Loathing script to reduce Green Pixie micromanagement.
// @include        *www*kingdomofloathing.com/*
// @include        http://127.0.0.1:60*/*
// @exclude        *kingdomofloathing.com/chatlaunch.php*
// @exclude        *kingdomofloathing.com/*chat.php*
// @exclude        *kingdomofloathing.com/login.php*
// @exclude        *kingdomofloathing.com/loggedout.php*
// @exclude        *kingdomofloathing.com/topmenu.php*
// @exclude        *kingdomofloathing.com/*.html
// @exclude        http://127.0.0.1:60*/chatlaunch.php*
// @exclude        http://127.0.0.1:60*/*chat.php*
// @exclude        http://127.0.0.1:60*/login.php*
// @exclude        http://127.0.0.1:60*/loggedout.php*
// @exclude        http://127.0.0.1:60*/topmenu.php*
// @exclude        http://127.0.0.1:60*/*.html
// ==/UserScript==

// 
// Version 1.0	12/08/2007	First release!
// Version 1.1 	01/03/2008	A fix to make mode 1 work for more people and play nicer with other scripts.
//					Also a minor change so that you will no longer have a worm wood nag link on the page after the last choice adventure.
// Version 1.2	01/05/2008	A fix for the stupid bug I introduced in 1.1
// Version 1.3	03/14/2008	Update to account for a change in the choice adventure page syntax, and the combat bars interface upgrade.
// Version 1.4	03/31/2008  Update for Firefox 3 beta compatibility
// Version 1.5	04/12/2008	Improved compatibility with KOLMafia's relay browser.
//
// Official forum thread: http://forums.kingdomofloathing.com:8080/vb/showthread.php?t=144797
//

const VERSION=15;

var i,j,k,curAbsinthe,mode,areaNumber,choiceNumber,optionNumber,step,received9,received5,targetItem,needAlert='false',modeTwoElement,needInlineElement='false',charPaneLinkNode,compactOrFull='unknown';

CheckForUpdates();

//Grab the character name from the character pane
if (window.location.pathname == "/charpane.php") {
	// Get the current name
	var charName = document.getElementsByTagName("b")[0].textContent;
	GM_setValue('curCharName',charName);
}
else {
	var charName = GM_getValue('curCharName','UNDEFINED');
}

//Check if the script has been run before.  If not, set all preferences to defaults.
var targetItem = GM_getValue(charName + '.targetItem',0);
if (targetItem == 0) {
	//if the character name isn't known, exit and wait for the script to run first in the charpane
	if (charName == 'UNDEFINED') {
		return false;
	}

	targetItem = 2;
	GM_setValue(charName + '.targetItem',2);
	GM_setValue(charName + '.mode',3);
	GM_setValue(charName + '.prevAdventure','barrel.php');
	GM_setValue(charName + '.prevAdventureText','The Barrel Full of Barrels');
	GM_setValue(charName + '.prevAdventureParent','barrel.php');
	GM_setValue(charName + '.received9','false');
	GM_setValue(charName + '.received5','false');
}

mode = GM_getValue(charName + '.mode');
//If we're on the character pane, go back and grab the number of absinthe adventures remaining
//Also find and possibly save the last adventure link node if mode 1 is on
if (window.location.pathname == "/charpane.php") {
	// While we're here, also grab the current number of absinthe adventures
	var imgnodes = document.getElementsByTagName("img");
	var found = 'false';
	var prevAbsinthe;
	for (i=0;i < imgnodes.length; i++) {
		if (imgnodes[i].getAttribute('onclick') == 'eff("ebaff6fa82fe65630faccf2d1177b7cc");') {
			//absinthe found, store how many adventures of it we have
			var textnode = imgnodes[i].parentNode.nextSibling.firstChild;
			if (!textnode.hasChildNodes()) {
				//compact mode
				curAbsinthe=parseInt(imgnodes[i].parentNode.nextSibling.firstChild.nodeValue.split("(")[1].split(")")[0]);
				compactOrFull = 'compact';
			}
			else {
				//full mode
				curAbsinthe=parseInt(imgnodes[i].parentNode.nextSibling.firstChild.textContent.split("Absinthe-Minded (")[1].split(")")[0]);
				compactOrFull = 'full';
			}
			var prevAbsinthe = GM_getValue(charName + '.curAbsinthe');
			GM_setValue(charName + '.curAbsinthe',curAbsinthe);
			found = 'true';

		}
	}
	//set it to zero if the effect wasn't found on the character pane
	if (found == 'false') {
		curAbsinthe = 0;
		GM_setValue(charName + '.curAbsinthe',0);
	}
	//fix for the bug I introduced in 1.1
	if ((curAbsinthe == 1) && (prevAbsinthe == 0)) {
		curAbsinthe = 0;
		GM_setValue(charName + '.curAbsinthe',curAbsinthe);
	} 
	//set the choice adventure received info back to false when appropriate
	if ((found == 'false') || (curAbsinthe == 10)) {
		GM_setValue(charName + '.received9','false');
		GM_setValue(charName + '.received5','false');
	}

	//If mode 1 is active, find the last adventure link node now so that we can save, replace, or restore it later on.
	if ((mode==1)||(mode==3)||(mode==5)||(mode==7)) {
		//First, find the link with the text "Last Adventure" because it has a distinct class to search for
		var lastAdvParentLink = document.evaluate('//a[@class="nounder" and @target="mainpane"]',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null);
		var lastAdvParentLinkNode = lastAdvParentLink.singleNodeValue;

		//Now make sure this is the right node.  If not, we'll assume compact mode and search that way.
		if ((!(lastAdvParentLink.singleNodeValue))||(lastAdvParentLink.singleNodeValue.textContent != "Last Adventure:")) {
			//Let's try compact mode 
			compactLinkNode = document.evaluate('//a[contains(@title,"Last Adventure:")]',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null);
			if(compactLinkNode) {
				charPaneLinkNode = compactLinkNode.singleNodeValue;
				compactOrFull = 'compact';
			}
			else {
				//Alternate slower way of finding it, in case the first doesn't find the right node for some reason
				var node,s;
				var textNodes = document.evaluate("//text()",document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);
				for (var i=0;i<textNodes.snapshotLength;i++) {
					node = textNodes.snapshotItem(i);
					s=node.data;
					if(s.match("^Last Adventure:$")) {
						lastAdvParentLinkNode = node.parentNode;
						charPaneLinkNode = lastAdvParentLinkNode.parentNode.parentNode.nextSibling.nextSibling.getElementsByTagName("a")[0];
						compactOrFull = 'full';
					}
				}	
			}			
		}
		else {
			//First search found the right node, set the charPaneLinkNode accordingly
			charPaneLinkNode = lastAdvParentLinkNode.parentNode.parentNode.nextSibling.nextSibling.getElementsByTagName("a")[0];
			compactOrFull = 'full';
		}
	}

	if ((prevAbsinthe != curAbsinthe) && ((curAbsinthe == 9) || (curAbsinthe == 5) || (curAbsinthe == 1))) {

		//if functionality mode 3 is activated, and absinthe adventures are at 9,5,1, and not previously warned about this, then we need an alert.  But don't trigger it here because that causes problems.
		if ((mode >= 4) && (mode <= 7) && (prevAbsinthe != curAbsinthe) && ((curAbsinthe == 9) || (curAbsinthe == 5) || (curAbsinthe == 1))) {
			needAlert='true';
		}

		//if mode 1 is active, we need to find and save the current last adventure link so that we can replace it safely
		if ((mode==1)||(mode==3)||(mode==5)||(mode==7)) {

			var linkText;
			var linkLocation = charPaneLinkNode.href;	
			if(compactOrFull == 'full') {
				linkText = charPaneLinkNode.textContent;
			}
			else {
				linkText = charPaneLinkNode.title.split("Last Adventure: ")[1];
			}
			
			//strip off the important part, and save the result
			var relativeLink;
			if (linkLocation.match(".kingdomofloathing.com/")) {
				relativeLink = linkLocation.split(".kingdomofloathing.com/")[1];
			}
			else if (linkLocation.match(/127\.0\.0\.1:\d+\//)) {
				relativeLink = linkLocation.split(/127\.0\.0\.1:\d+\//)[1];
				GM_log("relativeLink: "+relativeLink);
			}
			GM_setValue(charName + '.prevAdventure',relativeLink);
			GM_setValue(charName + '.prevAdventureText',linkText);

			//If we're in full mode, also save the parent.
			if(compactOrFull == 'full') {
				var parentLinkLocation = '' + lastAdvParentLink.singleNodeValue.href;
				parentLinkLocation = parentLinkLocation.split(".kingdomofloathing.com/")[1];
				GM_setValue(charName + '.prevAdventureParent',parentLinkLocation);
			}
		}
	}
}

//Figure out which area should be linked to, what choice adventure we're looking for, and which option to choose if found
curAbsinthe = GM_getValue(charName + '.curAbsinthe');
received9 = GM_getValue(charName + '.received9');
received5 = GM_getValue(charName + '.received5');
targetItem = GM_getValue(charName + '.targetItem');

if ((curAbsinthe <= 9) && (curAbsinthe >= 7) && (received9 == 'false')) {
	//9-7 adventures and haven't gotten the first choice adventure
	step = 9;
	switch(targetItem) {
		case 1: areaNumber=151; choiceNumber=164; optionNumber=2; break;
		case 2: areaNumber=151; choiceNumber=164; optionNumber=2; break;
		case 3: areaNumber=152; choiceNumber=167; optionNumber=3; break;
		case 4: areaNumber=152; choiceNumber=167; optionNumber=3; break;
		case 5: areaNumber=153; choiceNumber=170; optionNumber=1; break;
		case 6: areaNumber=153; choiceNumber=170; optionNumber=1; break;
		case 7: areaNumber=153; choiceNumber=170; optionNumber=3; break;
		case 8: areaNumber=151; choiceNumber=164; optionNumber=1; break;
		case 9: areaNumber=152; choiceNumber=167; optionNumber=2; break;
	}
}
else if ((curAbsinthe <= 5) && (curAbsinthe >= 4) && (received5 == 'false')) {
	//5-4 adventures and haven't gotten the second choice adventure
	step = 5;
	switch(targetItem) {
		case 1: areaNumber=153; choiceNumber=171; optionNumber=3; break;
		case 2: areaNumber=152; choiceNumber=168; optionNumber=2; break;
		case 3: areaNumber=151; choiceNumber=165; optionNumber=2; break;
		case 4: areaNumber=153; choiceNumber=171; optionNumber=1; break;
		case 5: areaNumber=152; choiceNumber=168; optionNumber=3; break;
		case 6: areaNumber=151; choiceNumber=165; optionNumber=1; break;
		case 7: areaNumber=152; choiceNumber=168; optionNumber=1; break;
		case 8: areaNumber=153; choiceNumber=171; optionNumber=2; break;
		case 9: areaNumber=151; choiceNumber=165; optionNumber=3; break;
	}
} 
else if (curAbsinthe == 1) {
	//1 adventure left
	step = 1;
	switch(targetItem) {
		case 1: areaNumber=152; choiceNumber=169; optionNumber=3; break;
		case 2: areaNumber=153; choiceNumber=172; optionNumber=2; break;
		case 3: areaNumber=153; choiceNumber=172; optionNumber=1; break;
		case 4: areaNumber=151; choiceNumber=166; optionNumber=1; break;
		case 5: areaNumber=151; choiceNumber=166; optionNumber=3; break;
		case 6: areaNumber=152; choiceNumber=169; optionNumber=1; break;
		case 7: areaNumber=151; choiceNumber=166; optionNumber=2; break;
		case 8: areaNumber=152; choiceNumber=169; optionNumber=2; break;
		case 9: areaNumber=153; choiceNumber=172; optionNumber=3; break;
	}
}
else {
	step = 0;
}

//Create the page element for functionality mode 2.  Add it to the page if necessary.
if ((step>0)&&((mode == 2)||(mode==3)||(mode==6)||(mode==7))) {
	modeTwoElement = document.createElement('tr');
	var message = '<tr><td><div name="modetwodiv" style="font-family:arial;font-size: 100%;width: 100%;text-align:left;float:left">Absinthe Minder: <a href="adventure.php?snarfblat=' +areaNumber+ '">';
	switch(areaNumber) {
		case 151: message += 'The Stately Pleasure Dome';break;
		case 152: message += 'The Mouldering Mansion';break;
		case 153: message += 'The Rogue Windmill';break;
	}
	message += '</a></div></td></tr>';
	modeTwoElement.innerHTML = message;

	//This is a check to make sure it doesn't get inserted multiple times (by a charpane refresh, for example)
	var m2DivExists = top.frames[2].document.evaluate('//div[@name="modetwodiv"]',top.frames[2].document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null);
	if(!(m2DivExists.singleNodeValue)) {
		AddToTop(modeTwoElement,top.frames[2].document);
		//var element = top.frames[2].document.getElementsByTagName("tr")[0];
		//element.parentNode.insertBefore(modeTwoElement,element);
	}
}

//If mode 1 is active, we may need to replace the last adventure link
//Here is where we do that
//The variables charPaneLinkNode and (possibly) lastAdvParentLink were set in the previous charpane section above and are still valid
if ((window.location.pathname == "/charpane.php") && ((mode==1)||(mode==3)||(mode==5)||(mode==7))) {
	if (step > 0) {
		var areaName;
		switch(areaNumber) {
			case 151: areaName = 'The Stately Pleasure Dome'; break;
			case 152: areaName = 'The Mouldering Mansion'; break;
			case 153: areaName = 'The Rogue Windmill'; break;
		}

		//Replace the current link with a worm wood link
		charPaneLinkNode.href = "adventure.php?snarfblat=" + areaNumber;

		//Also replace "Last Adventure" with "Next Adventure" and fix the area name so people know their links have been messed with
		//And, if we're in full mode, replace the parent area link as well
		if(compactOrFull == 'compact') {
			charPaneLinkNode.title = "Next Adventure: " + areaName;
		}
		else {
			charPaneLinkNode.textContent = areaName;
			lastAdvParentLink.singleNodeValue.textContent = 'Next Adventure:';

			lastAdvParentLink.singleNodeValue.href = 'wormwood.php';
		}		
	}
	else if (((curAbsinthe == 0) || ((step == 0) && (curAbsinthe > 0)))) {
		linkLocation = ''+charPaneLinkNode.href;
		if (((linkLocation.match("snarfblat=151"))||(linkLocation.match("snarfblat=152"))||(linkLocation.match("snarfblat=153")))) {
			//Replace the worm wood link with the saved link

			var prevLinkLocation = GM_getValue(charName + '.prevAdventure');
			var prevLinkText = GM_getValue(charName + '.prevAdventureText');
			var prevLinkParent = GM_getValue(charName + '.prevAdventureParent');

			//Replace the link
			charPaneLinkNode.href = prevLinkLocation;

			//Fix the area name back to what it was, and (in full mode) replace the parent area link as well
			if (compactOrFull == 'compact') {
				charPaneLinkNode.title = "Last Adventure: " + prevLinkText;
			}
			else {
				charPaneLinkNode.textContent = prevLinkText;
				lastAdvParentLink.singleNodeValue.href = prevLinkParent;
			}
		}
	}
}

//automatic choice adventure picking in the worm wood
if (window.location.pathname == "/choice.php") {
	//Attempt to find the desired choice on the page.  If not found, do nothing here
	var theForm = document.evaluate('//form[contains(@name,"choiceform") and input[@name="whichchoice" and @value='+choiceNumber+'] and input[@name="option" and  @value='+optionNumber+']]',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null);
	if (theForm.singleNodeValue) {
		if((step == 5) || (step == 9)) {
			GM_setValue(charName + '.received' + step,'true');	
		}
		//manually set curAbsinthe to zero so it doesn't nag you with a link after receiving this last choice adventure
		if(step==1) {
			GM_setValue(charName + '.curAbsinthe',0);
		}
		theForm.singleNodeValue.submit();
	}
}

//This long long section adds a nice little options menu to the account options page
if (window.location.pathname == "/account.php") {
	//title bar
	var titleBar = document.createElement('div');
	with (titleBar) {
		appendChild(document.createTextNode('Absinthe Minder'));
		style.padding = "1px 0 1px 0";
		style.textAlign = "center";
		style.color = "white";
		style.backgroundColor = "blue";
		style.fontWeight = "bold";
	}

	var optionsForm = document.createElement('form');
	optionsForm.style.textAlign = 'right';

	//Select box to choose the worm wood target item or stat
	var targetSelect = document.createElement('select');
	with(targetSelect) {
		var opt1 = document.createElement('option');
		opt1.value = "1";
		opt1.appendChild(document.createTextNode('Fancy Ball Mask (Mox hat)'));
		if(targetItem == 1) { opt1.selected = 'true'; }
		appendChild(opt1);

		var opt2 = document.createElement('option');
		opt2.value = "2";
		opt2.appendChild(document.createTextNode('Not-a-pipe (Spleen)'));
		if (targetItem == 2) { opt2.selected = 'true'; }
		appendChild(opt2);

		var opt3 = document.createElement('option');
		opt3.value = "3";
		opt3.appendChild(document.createTextNode('Can-Can Skirt (Musc pants)'));
		if (targetItem == 3) { opt3.selected = 'true'; }
		appendChild(opt3);

		var opt4 = document.createElement('option');
		opt4.value = "4";
		opt4.appendChild(document.createTextNode('S.T.L.T. (Food)'));
		if (targetItem == 4) { opt4.selected = 'true'; }
		appendChild(opt4);

		var opt5 = document.createElement('option');
		opt5.value = "5";
		opt5.appendChild(document.createTextNode('Albatross Necklace (Myst Acc.)'));
		if (targetItem == 5) { opt5.selected = 'true'; }
		appendChild(opt5);

		var opt6 = document.createElement('option');
		opt6.value = "6";
		opt6.appendChild(document.createTextNode('Flask of Amontillado (Booze)'));
		if (targetItem == 6) { opt6.selected = 'true'; }
		appendChild(opt6);

		var opt7 = document.createElement('option');
		opt7.value = "7";
		opt7.appendChild(document.createTextNode('Moxie substats'));
		if (targetItem == 7) { opt7.selected = 'true'; }
		appendChild(opt7);

		var opt8 = document.createElement('option');
		opt8.value = "8";
		opt8.appendChild(document.createTextNode('Muscle substats'));
		if (targetItem == 8) { opt8.selected = 'true'; }
		appendChild(opt8);

		var opt9 = document.createElement('option');
		opt9.value = "9";
		opt9.appendChild(document.createTextNode('Myst substats'));
		if (targetItem == 9) { opt9.selected = 'true'; }
		appendChild(opt9);

		addEventListener('change',function(event) {
			var newTarget = this.selectedIndex;
			if((newTarget >= 0) && (newTarget <= 8)) {
				GM_setValue(charName + '.targetItem',newTarget+1);
			}
		},true);
	}
	//Div wrapper to hold the select box
	var targetDiv = document.createElement('div');
	with(targetDiv) {
		appendChild(document.createTextNode('Choose target item or stat:'));
		appendChild(targetSelect);
	}
	optionsForm.appendChild(targetDiv);

	//Checkbox to turn on/off mode one
	var modeOneCheckbox = document.createElement('input');
	with(modeOneCheckbox) {
		type = 'checkbox';

		if((mode==1)||(mode==3)||(mode==5)||(mode==7)) {
			checked = 'true';
		}

		addEventListener('click',function(event) {
			if((mode==1)||(mode==3)||(mode==5)||(mode==7)) {
				mode--;
				GM_setValue(charName + '.mode',mode);
			}
			else {
				mode++;
				GM_setValue(charName + '.mode',mode);
			}
		},true);
	}
	
	//Text and wrapper for the checkbox
	var modeOneDiv = document.createElement('div');
	with(modeOneDiv) {
		style.textAlignment = "right";
		appendChild(document.createTextNode('Replace Last adventure links'));
		appendChild(modeOneCheckbox);
	}
	optionsForm.appendChild(modeOneDiv);

	//Checkbox to turn on/off mode two
	var modeTwoCheckbox = document.createElement('input');
	with(modeTwoCheckbox) {
		type = 'checkbox';

		if((mode==2)||(mode==3)||(mode==6)||(mode==7)) {
			checked = 'true';
		}

		addEventListener('click',function(event) {
			if((mode==2)||(mode==3)||(mode==6)||(mode==7)) {
				mode -= 2;
				GM_setValue(charName + '.mode',mode);
			}
			else {
				mode += 2;
				GM_setValue(charName + '.mode',mode);
			}
		},true);
	}
	//Text and wrapper for the checkbox	
	var modeTwoDiv = document.createElement('div');
	with(modeTwoDiv) {
		style.textAlignment = "right";
		appendChild(document.createTextNode('Add Worm Wood link above page'));
		appendChild(modeTwoCheckbox);
	}
	optionsForm.appendChild(modeTwoDiv);

	//Checkbox to turn on/off mode three
	var modeThreeCheckbox = document.createElement('input');
	with(modeThreeCheckbox) {
		type = 'checkbox';
		style.textAlign = "right";

		if((mode>=4)&&(mode<=7)) {
			checked = 'true';
		}

		addEventListener('click',function(event) {
			if((mode>=4)&&(mode<=7)) {
				mode -= 4;
				GM_setValue(charName + '.mode',mode);
			}
			else {
				mode += 4;
				GM_setValue(charName + '.mode',mode);
			}
		},true);
	}

	//Text and wrapper for the checkbox	
	var modeThreeDiv = document.createElement('div');
	with(modeThreeDiv) {
		style.textAlign = "right";
		style.float = "left";
		appendChild(document.createTextNode('Alert at 9/5/1 adventures'));
		appendChild(modeThreeCheckbox);
	}
	optionsForm.appendChild(modeThreeDiv);

	wrapper = document.createElement('div');
	with(wrapper) {
		style.width = '95%';
		style.border = 'thin solid blue';
		appendChild(titleBar);
		appendChild(optionsForm);
	}


	var loc = document.getElementsByTagName('center')[2];
	if(loc.lastChild.textContent.indexOf("This account will") != 0)var loc = document.getElementsByTagName('center')[3];
	loc.insertBefore(wrapper,loc.lastChild);

}


//Actually trigger the functionality mode 3 alert
if (needAlert == 'true') {
	alert("Warning: " + curAbsinthe + " adventures of Absinthe-Minded remaining.");
}

//insert an element at the top of the page, but under the combat bar if present
function AddToTop(newElement,refDocument) {
	var fightElement = refDocument.evaluate('//b[contains(.,"Combat") and contains(.,"!")]/ancestor::tr[1]',refDocument,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
	if (fightElement) {
		fightElement.parentNode.insertBefore(newElement,fightElement);
	}
	else {
		var element = refDocument.getElementsByTagName("tr")[0];
		element.parentNode.insertBefore(newElement,element);
	}
}

function CheckForUpdates() {
	var scriptUrl = 'http://userscripts.org/scripts/source/16030.user.js';

	var lastUpdateCheck = GM_getValue('lastUpdateCheck','NEVER');
	var curTime = new Date().getTime();
	if ((lastUpdateCheck == 'NEVER') || (parseInt(lastUpdateCheck) < (curTime - 86400000))) {
		GM_setValue('lastUpdateCheck',''+curTime);
		GM_xmlhttpRequest({method: 'GET',url: scriptUrl,
					onload: function(responseDetails) {
						var bodyText = responseDetails.responseText;
						var matches = bodyText.match(/const VERSION=([\d\.]+);(\s+const RELEASECOMMENT='(.*)';)?/);
						var curVersionNum = parseFloat(matches[1]);

						if (matches[3] && matches[3] != '') {
							GM_setValue('releaseComment',matches[3]);
						}
						else {
							GM_setValue('releaseComment','');
						}
						if (curVersionNum > VERSION) {
							GM_setValue('outOfDate','true');
						}
						else {
							GM_setValue('outOfDate','false');
						}
					}
				});
	}
	var curVersion = GM_getValue('curVersion','0');
	if (parseInt(curVersion) != VERSION) {
		GM_setValue('curVersion',VERSION);
		GM_setValue('outOfDate','false');
	}
	//Nag user with update link if the script is out of date
	var outOfDate = GM_getValue('outOfDate');
	if((outOfDate == 'true') && (window.location.pathname != "/charpane.php") && (window.location.pathname != "/login.php")) {
		var releaseComment = GM_getValue('releaseComment','');
		var newElement = document.createElement('center');
		newElement.innerHTML = '<table style="border: 1px solid red; margin-bottom: 4px; color: red; font-size:85%" width=95% cellpadding=1 cellspacing=0><tr><td bgcolor=red style="color:white;">A new version of Absinthe Minder is available!</td></tr><tr style="color:red;"><td><a href="'+scriptUrl+'" target="_blank">Update</a>&nbsp;&nbsp;<a href="http://forums.kingdomofloathing.com:8080/vb/showthread.php?t=144797">Forum thread</a>&nbsp;&nbsp;' + ((releaseComment!='')?('Release notes:&nbsp;'+releaseComment):'') + '</td></tr></table>';

		//insert the counter at the top of the page
		AddToTop(newElement,document);
	}
}