MediaWiki:Common.js

From IdleOn MMO Wiki
Revision as of 03:37, 23 July 2024 by Nads (talk | contribs)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/* Any JavaScript here will be loaded for all users on every page load. */
function nFormatter(num, digits) {
  var si = [
    { value: 1, symbol: "" },
    { value: 1E3, symbol: "k" },
    { value: 1E6, symbol: "M" },
    { value: 1E9, symbol: "B" },
    { value: 1E12, symbol: "T" },
    { value: 1E15, symbol: "Q" },
    { value: 1E18, symbol: "QQ" },
    { value: 1E21, symbol: "QT" }
  ];
  var rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
  var i;
  for (i = si.length - 1; i > 0; i--) {
    if (num >= si[i].value) {
      break;
    }
  }
  return (num / si[i].value).toFixed(digits).replace(rx, "$1 ") + si[i].symbol;
}

function deliminateNumber(number){
	decimal = round(number % 1, 10);
	number = Math.floor(number).toString();
	deliminated = '';
	while (number.length >= 3) {
		section = number.slice(-3);
		number = number.substring(0, number.length-3);
		deliminated = "," + section + deliminated;
	}
	deliminated = number + deliminated; // Any additional remaining numbers prepend.
	if (deliminated.substring(0,1) == ',') {deliminated = deliminated.substring(1); } // Removes extra delimiters in front.
	if (decimal > 0.0) {deliminated = deliminated + decimal.toString().substring(1); } // Converts to decimal to string, and adds the decimal without 0 integer.
	return deliminated;
}

function nTooltipFormat(number){
	if (number < 1e5) { return number; }
	delimitedNum = deliminateNumber(number);
	formattedNum = nFormatter(number);
	return '<span class="simple-tooltip simple-tooltip-inline tooltipstered" data-simple-tooltip="'+delimitedNum+'">'+formattedNum+'</span>';
}

function getCostTotal(base,level,cLevel) {
	var res = base;
	for (i = 1; i < level;i++){
		res += base + i*cLevel;
	console.log(res);
	}
	if (level == 0){
		return 0;
	} else {
		return res;
	}
}


function coindisplay(coins) {
    var n = coins;
    var ret = "";
    var imgs = ["4/43/Copper", "4/4e/Silver", "1/1f/Gold", "2/2c/Platinum", "5/53/Dementia", 
    			"d/d5/Void", "1/11/Lustre", "8/83/Starfire", "8/8b/Dreadlo", "e/e6/Godshard", 
    			"2/2b/Sunder", "b/bd/Tydal", "b/bf/Marbiglass", "4/42/Orberal", "f/f1/Eclipse"];
    var i = 28;
    do {
        var expo = Math.pow(10, i);
        if (n > expo) { 
            var num = Math.floor(n/expo);
                ret += "<img src=https://idleon.wiki/wiki/images/" + imgs[(i/2)] + "_Coin.png>" + num + " ";
            n = n % expo;
        }
        i -= 2;
    } while(i >= 0);
    return ret;
}

//  Formatted version of a popular md5 implementation
//  Original copyright (c) Paul Johnston & Greg Holt.
function md5(inputString) {
    var hc="0123456789abcdef";
    function rh(n) {var j,s="";for(j=0;j<=3;j++) s+=hc.charAt((n>>(j*8+4))&0x0F)+hc.charAt((n>>(j*8))&0x0F);return s;}
    function ad(x,y) {var l=(x&0xFFFF)+(y&0xFFFF);var m=(x>>16)+(y>>16)+(l>>16);return (m<<16)|(l&0xFFFF);}
    function rl(n,c)            {return (n<<c)|(n>>>(32-c));}
    function cm(q,a,b,x,s,t)    {return ad(rl(ad(ad(a,q),ad(x,t)),s),b);}
    function ff(a,b,c,d,x,s,t)  {return cm((b&c)|((~b)&d),a,b,x,s,t);}
    function gg(a,b,c,d,x,s,t)  {return cm((b&d)|(c&(~d)),a,b,x,s,t);}
    function hh(a,b,c,d,x,s,t)  {return cm(b^c^d,a,b,x,s,t);}
    function ii(a,b,c,d,x,s,t)  {return cm(c^(b|(~d)),a,b,x,s,t);}
    function sb(x) {
        var i;var nblk=((x.length+8)>>6)+1;var blks=new Array(nblk*16);for(i=0;i<nblk*16;i++) blks[i]=0;
        for(i=0;i<x.length;i++) blks[i>>2]|=x.charCodeAt(i)<<((i%4)*8);
        blks[i>>2]|=0x80<<((i%4)*8);blks[nblk*16-2]=x.length*8;return blks;
    }
    var i,x=sb(""+inputString),a=1732584193,b=-271733879,c=-1732584194,d=271733878,olda,oldb,oldc,oldd;
    for(i=0;i<x.length;i+=16) {olda=a;oldb=b;oldc=c;oldd=d;
        a=ff(a,b,c,d,x[i+ 0], 7, -680876936);d=ff(d,a,b,c,x[i+ 1],12, -389564586);c=ff(c,d,a,b,x[i+ 2],17,  606105819);
        b=ff(b,c,d,a,x[i+ 3],22,-1044525330);a=ff(a,b,c,d,x[i+ 4], 7, -176418897);d=ff(d,a,b,c,x[i+ 5],12, 1200080426);
        c=ff(c,d,a,b,x[i+ 6],17,-1473231341);b=ff(b,c,d,a,x[i+ 7],22,  -45705983);a=ff(a,b,c,d,x[i+ 8], 7, 1770035416);
        d=ff(d,a,b,c,x[i+ 9],12,-1958414417);c=ff(c,d,a,b,x[i+10],17,     -42063);b=ff(b,c,d,a,x[i+11],22,-1990404162);
        a=ff(a,b,c,d,x[i+12], 7, 1804603682);d=ff(d,a,b,c,x[i+13],12,  -40341101);c=ff(c,d,a,b,x[i+14],17,-1502002290);
        b=ff(b,c,d,a,x[i+15],22, 1236535329);a=gg(a,b,c,d,x[i+ 1], 5, -165796510);d=gg(d,a,b,c,x[i+ 6], 9,-1069501632);
        c=gg(c,d,a,b,x[i+11],14,  643717713);b=gg(b,c,d,a,x[i+ 0],20, -373897302);a=gg(a,b,c,d,x[i+ 5], 5, -701558691);
        d=gg(d,a,b,c,x[i+10], 9,   38016083);c=gg(c,d,a,b,x[i+15],14, -660478335);b=gg(b,c,d,a,x[i+ 4],20, -405537848);
        a=gg(a,b,c,d,x[i+ 9], 5,  568446438);d=gg(d,a,b,c,x[i+14], 9,-1019803690);c=gg(c,d,a,b,x[i+ 3],14, -187363961);
        b=gg(b,c,d,a,x[i+ 8],20, 1163531501);a=gg(a,b,c,d,x[i+13], 5,-1444681467);d=gg(d,a,b,c,x[i+ 2], 9,  -51403784);
        c=gg(c,d,a,b,x[i+ 7],14, 1735328473);b=gg(b,c,d,a,x[i+12],20,-1926607734);a=hh(a,b,c,d,x[i+ 5], 4,    -378558);
        d=hh(d,a,b,c,x[i+ 8],11,-2022574463);c=hh(c,d,a,b,x[i+11],16, 1839030562);b=hh(b,c,d,a,x[i+14],23,  -35309556);
        a=hh(a,b,c,d,x[i+ 1], 4,-1530992060);d=hh(d,a,b,c,x[i+ 4],11, 1272893353);c=hh(c,d,a,b,x[i+ 7],16, -155497632);
        b=hh(b,c,d,a,x[i+10],23,-1094730640);a=hh(a,b,c,d,x[i+13], 4,  681279174);d=hh(d,a,b,c,x[i+ 0],11, -358537222);
        c=hh(c,d,a,b,x[i+ 3],16, -722521979);b=hh(b,c,d,a,x[i+ 6],23,   76029189);a=hh(a,b,c,d,x[i+ 9], 4, -640364487);
        d=hh(d,a,b,c,x[i+12],11, -421815835);c=hh(c,d,a,b,x[i+15],16,  530742520);b=hh(b,c,d,a,x[i+ 2],23, -995338651);
        a=ii(a,b,c,d,x[i+ 0], 6, -198630844);d=ii(d,a,b,c,x[i+ 7],10, 1126891415);c=ii(c,d,a,b,x[i+14],15,-1416354905);
        b=ii(b,c,d,a,x[i+ 5],21,  -57434055);a=ii(a,b,c,d,x[i+12], 6, 1700485571);d=ii(d,a,b,c,x[i+ 3],10,-1894986606);
        c=ii(c,d,a,b,x[i+10],15,   -1051523);b=ii(b,c,d,a,x[i+ 1],21,-2054922799);a=ii(a,b,c,d,x[i+ 8], 6, 1873313359);
        d=ii(d,a,b,c,x[i+15],10,  -30611744);c=ii(c,d,a,b,x[i+ 6],15,-1560198380);b=ii(b,c,d,a,x[i+13],21, 1309151649);
        a=ii(a,b,c,d,x[i+ 4], 6, -145523070);d=ii(d,a,b,c,x[i+11],10,-1120210379);c=ii(c,d,a,b,x[i+ 2],15,  718787259);
        b=ii(b,c,d,a,x[i+ 9],21, -343485551);a=ad(a,olda);b=ad(b,oldb);c=ad(c,oldc);d=ad(d,oldd);
    }
    return rh(a)+rh(b)+rh(c)+rh(d);
}


function calcBubbleMatCost(bubbleLvl, baseCost, matType, bubbleNumber, cauldCostReduxLvl, bubbleCostBubbleLvl, bubbleCostVialLvl, bubbleBargainLvl, bubbleMultClassLvl, shopBargainBought, riftVialMastery, smrtAchievement) {
	const shopBargainBoost = Math.max(0.1, Math.pow(0.75, shopBargainBought));
	if (matType == '1'){ // Liquids
		return baseCost + Math.floor(bubbleLvl / 20);
	} else if (matType == '2') { // Bits
		return baseCost * Math.pow(2, bubbleLvl) * shopBargainBoost * (1 - 0.1 * smrtAchievement);
	} else { // Materials
		if( 15 < bubbleNumber ) {
			first = baseCost * Math.pow( 1.37 - (0.28 * bubbleLvl)/ (60 + bubbleLvl), bubbleLvl);
		} else {
			first = baseCost * Math.pow( 1.35 - (0.3 * bubbleLvl)/ (50 + bubbleLvl), bubbleLvl);
		}
		const cauldCostReduxBoost = Math.max(
			0.1, 
			1 - (Math.round(10 * lavaFunc("decay",cauldCostReduxLvl, 90, 100)) / 10) / 100
			);
		const bubbleCostBubbleBoost = Math.max(
			0.05, 
			1 - (lavaFunc("decay",bubbleCostBubbleLvl, 40, 70) + (lavaFunc("add",bubbleCostVialLvl, 1, 0) * (1 + 0.02 * riftVialMastery))) / 100
			);
		const bubbleBargainBoost = Math.max(
			0.05,
			1 - (lavaFunc("decay",bubbleBargainLvl,40,12)/100) * lavaFunc("decayMulti",bubbleMultClassLvl, 2, 50)
			);
		return Math.min(1000000000, Math.round(first * cauldCostReduxBoost * bubbleBargainBoost * bubbleCostBubbleBoost * shopBargainBoost * (1 - 0.1 * smrtAchievement)));
	}
}
function round(num, decimal){
	decimal = typeof decimal !== 'undefined' ? decimal : 0; // Default parameters aren't available until ES6. This is the next best solution.
	return Math.round((num + Number.EPSILON) * Math.pow(10, decimal)) / Math.pow(10, decimal);
}
function lavaLog(num){
	return Math.log(Math.max(num, 1)) / 2.303;
}

function goldFoodBonus(amount,stack){
	return round(amount*0.05*lavaLog(1+stack)*(1+ lavaLog(1+stack)/2.14), 2);
}


function lavaFunc(func,level,x1,x2) {
	var result = 0;
	switch(func) {
    	case 'add':
			if (x2 != 0) {
			  result = (((x1+x2)/x2 +0.5*(level-1))/(x1/x2))*level*x1;
			} else {
				result = level*x1;
			}
			break;
		case 'decay':
			result = (level*x1)/(level+x2);
			break;
		case 'intervalAdd':
			result = x1 + Math.floor(level/x2);
			break;
		case 'decayMulti':
			result = 1 + (level*x1)/(level+x2);
			break;
		case 'bigBase':
			result = x1 + x2*level;
			break;
		case 'addLower':
			result = x1 + x2 * (level + 1);
			break;
		case 'decayLower':
		case 'decayMultiLower': //DecaMultiLower is literally the exact same function as DecayLower.
			result = x1 * (level + 1) / (level + 1 + x2) - x1 * level / (level + x2);
			break;
		case 'bigBaseLower':
			result = x2;
			break;
		case 'intervalAddLower':
			result = Math.max(Math.floor((level + 1) / x2), 0) - Math.max(Math.floor(level / x2), 0);
			break;
		case 'reduce':
			result = x1 - x2 * level;
			break;
		case 'reduceLower':
			result = x1 - x2 * (level + 1);
			break;
		case 'PtsSpentOnGuildBonus':
			result = ((x1 + x2) / x2 + 0.5 * (level - 1)) / (x1 / x2) * level * x1 - x2 * level;
			break;
		case 'special1':
			result = 100 - (level*x1)/(level+x2);
			break;
		default:
			result = 0;
	}
	return round(result, 3);
}

$(document).ready(function(){ // Testing an icon toggle injection.
	var userTools = document.getElementById('user-tools');
	var darkmodeDiv = document.createElement('div');
	darkmodeDiv.setAttribute('id', 'darkmode-toggle');
	darkmodeDiv.setAttribute('style', 'display: inline-flex; width: 30px; height: 37.98px; position: relative; justify-content: center; flex-wrap: wrap; align-content: center;');
	var darkmodeButton = document.createElement('a');
	darkmodeButton.setAttribute('href', '#');
	darkmodeButton.setAttribute('id', 'darkmode-button');
	darkmodeButton.setAttribute('class', 'ext-darkmode-link');
	var darkmodeIcon = document.createElement('div');
	darkmodeIcon.setAttribute('class', 'darkmode-icon');
	darkmodeIcon.setAttribute('style', 'height: 20px; width: 20px;');
	
	darkmodeButton.appendChild(darkmodeIcon);
	darkmodeDiv.appendChild(darkmodeButton);
	userTools.insertBefore(darkmodeDiv, userTools.firstChild);
});

$(document).ready(function(){
	$.each($('.username'), function(){
		var username = mw.config.get('wgUserName');
		if (!username) {
			username = "Pro Gamer";
		}
	 	$(this).text(username);
	});
    $.each($('.skillDiv'), function(){
    	var container = $(this);
    	var x1 = parseFloat($(this).data('x1'));
    	var x2 = parseFloat($(this).data('x2'));
    	var max = parseFloat($(this).data('max'));
    	var func1 = $(this).data('func1');
    	var y1 = parseFloat($(this).data('y1'));
    	var y2 = parseFloat($(this).data('y2'));
    	var func2 = $(this).data('func2');
    	$('.result1', container).text(0);
    	$('.result2', container).text(0);
    	$('.valInput', this).html('(<input id="inField" type="number" min="0" max="'+max+'" placeholder=" Level "/>) ');
    	$("#inField", this).change(function(){
    		var inVal = parseInt($(this).val());
    		$('.result1', container).text(lavaFunc(func1,inVal,x1,x2));
    		$('.result2', container).text(lavaFunc(func2,inVal,y1,y2));
    	});
    });
    $.each($('.familyBonusDiv'), function(){
    	var container = $(this);
    	var x1 = parseFloat($(this).data('x1'));
    	var x2 = parseFloat($(this).data('x2'));
    	var tierReduction = parseInt($(this).data('tier'));
    	var func = $(this).data('func');
    	var inVal1 = 0;
    	var inVal2 = 1;
    	$('.result', container).text(0);
    	$('.valInput1', this).html('<input id="inField1" type="number" min="'+(tierReduction+1)+'" placeholder=" Class Level "/> ');
    	$('.valInput2', this).html('<input id="inField2" type="number" min="'+(tierReduction+1)+'" placeholder=" Talent Level "/> ');
    	$("#inField1", this).change(function(){
			inVal1 = parseInt($(this).val()) - tierReduction;
			$('.result', container).text(Math.max(lavaFunc(func,inVal1,x1,x2) * inVal2, 0).toFixed(2));
    	});
    	$("#inField2", this).change(function(){
    		inVal2 = 1 + (lavaFunc('decay',parseInt($(this).val()),40,100) / 100);
			$('.result', container).text(Math.max(lavaFunc(func,inVal1,x1,x2) * inVal2, 0).toFixed(2));
    	});
    });
    $.each($('.farmMarketDiv'), function(){
    	var container = $(this);
    	var marketType = $(this).data('markettype');
    	var cropId = Number($(this).data('cropid'));
    	var cropIdIncrement = parseFloat($(this).data('cropidincrement'));
    	var cost = parseInt($(this).data('cost'));
    	var costExponent = parseFloat($(this).data('costexponent'));
    	var bonusPerLvl = parseFloat($(this).data('bonusperlvl'));
    	var max = parseInt($(this).data('max'));
    	
    	$('.result1', container).text(0);
    	$('.result2', container).text(0);
    	$('.valInput', this).html('<input id="inField" type="number" min="0" max="'+max+'" placeholder="  Level "/> ');
    	$("#inField", this).change(function(){
    		var level = parseInt($(this).val());
    		// Get Bonus Value
    		var bonusValue = round(bonusPerLvl * level, 2);
			$('.result1', container).text(bonusValue);
    		
    		// Get Cost Value
    		var costValue = deliminateNumber(Math.floor(cost * Math.pow(costExponent, level)));
    		$('.result2', container).text(costValue);
    		
    		// Get Crop.
    		var crop;
    		if (marketType == "Night") {
    			crop = 'Bean';
    		} else if (marketType == "First") {
    			crop = Math.floor(cropId + cropIdIncrement * (level + (2 * Math.floor(level / 3) + Math.floor(level / 4))));
    		} else {
				crop = Math.floor(cropId + cropIdIncrement * level);
    		}
    		var imageName = "FarmCrop"+crop+".png"; 
    		var hash = md5(imageName);
    		var newUrl = '/wiki/images/' + hash.substring(0, 1) + '/' + hash.substring(0, 2) + '/' + imageName;
			var imageElement = $('img', $('.imgContainer', container)); // Img Element inside the imgContainer span.
			imageElement.attr("src", newUrl); 
    	});
    });
    $.each($('.guildBonusDiv'), function(){
    	var container = $(this);
    	var x1 = parseFloat($(this).data('x1'));
    	var x2 = parseFloat($(this).data('x2'));
    	var max = parseFloat($(this).data('max'));
    	var func1 = $(this).data('func');
    	var baseC = parseFloat($(this).data('basec'));
    	var incC = parseFloat($(this).data('incc'));
    	$('.result1', container).text(0);
    	$('.result2', container).text(0);
    	$('.cost', container).text(baseC);
    	$('.valInput', this).html('(<input id="inField" type="number" min="0" max="'+max+'" placeholder=" Level "/>) ');
    	$("#inField", this).change(function(){
    		var inVal = parseInt($(this).val());
    		$('.result1', container).text(lavaFunc(func1,inVal,x1,x2));
    		$('.result2', container).text(10+inVal);
    		$('.cost', container).text(baseC + inVal * incC);
    		$('.tcost', container).text(getCostTotal(baseC,inVal,incC));
    	});
    });
	//assign custom sidebar collapsible classes
	$("#site-navigation > .sidebar-inner > div > h3").addClass("sidebar-collapsible");
	$("#site-navigation > .sidebar-inner > div > div.mw-portlet-body").addClass("sidebar-collapsible-content");
	$("#site-navigation > .sidebar-inner").html("<div id=\"sidebar-collapsible-toggle\">Expand All</div>" + $("#site-navigation > .sidebar-inner").html());
	
	//hide content except for the ones specified as expanded
	var expandedContentTitles = ['Navigation', 'Characters', 'Universe']; // Edit Pre-expand headers here.
	$(".sidebar-collapsible-content").each(function() {
		if (!expandedContentTitles.includes(this.previousSibling.textContent)) {
			$(this.previousSibling).addClass('closed');
		} else {
			$(this.previousSibling).addClass('open');
		}
	});
	// on section title click, show/hide contents and toggle between little right/down arrow.
	$(".sidebar-collapsible").click(function() {
		$(this).toggleClass('open closed');
	
	});
	// On Expand/Close All click, show/hide all contents and toggle text.
	$("#sidebar-collapsible-toggle").click(function() {
		if($("#sidebar-collapsible-toggle").text() == "Expand All") {
			$(".sidebar-collapsible").css('display', '');
			$(".sidebar-collapsible").addClass('open');
			$(".sidebar-collapsible").removeClass('closed');
			$("#sidebar-collapsible-toggle").text("Close All");
		} else {
			$(".sidebar-collapsible").addClass('closed');
			$(".sidebar-collapsible").removeClass('open');
			$("#sidebar-collapsible-toggle").text("Expand All");
		}
	});
    $.each($('.boxDiv'), function(){
	    var container = $(this);
	    var func1 = $(this).data('func1');
	    var x1 = $(this).data('x1');
	    var x2 = $(this).data('x2');
	    var func2 = $(this).data('func2');
	    var y1 = $(this).data('y1');
	    var y2 = $(this).data('y2');
	    var offset2 = $(this).data('offset2');
	    var func3 = $(this).data('func3');
	    var z1 = $(this).data('z1');
	    var z2 = $(this).data('z2');
	    var offset3 = $(this).data('offset3');
	    $('.result1', container).text(0);
	    $('.result2', container).text(0);
	    $('.result3', container).text(0);
	    $('.valInput', this).html('<input id="inField" type="number" min="0" placeholder=" Level " style="max-width: 100px;"/>');
	    $("#inField", this).change(function(){
	        var inVal = parseInt($(this).val());
	        $('.result1', container).text(Math.max(0,lavaFunc(func1,inVal,x1,x2)));
	        $('.result2', container).text(Math.max(0,lavaFunc(func2,inVal-offset2,y1,y2)));
	        $('.result3', container).text(Math.max(0,lavaFunc(func3,inVal-offset3,z1,z2)));
	    });
	});
    $.each($('.stampDiv'), function(){
    	var container = $(this);
    	var x1 = parseFloat($(this).data('x1'));
    	var x2 = parseFloat($(this).data('x2'));
    	var func = $(this).data('func');
    	var i4 = parseFloat($(this).data('i4'));
    	var i6 = parseFloat($(this).data('i6'));
    	var i7 = parseFloat($(this).data('i7'));
    	var i8 = parseFloat($(this).data('i8'));
    	var i9 = parseFloat($(this).data('i9'));
    	var offset = parseInt($(this).data('offset'));
    	$('.resultB', container).text(0);
    	$('.resultC', container).text(0);
    	$('.resultM', container).text(0);
    	$('.valInput', this).html('<input id="inField" type="number" min="0" placeholder=" Level " style="max-width: 100px;"/>');
    	$("#inField", this).change(function(){
    		var inVal = parseInt($(this).val());
    		var goldCost = i8 * Math.pow(i9 - (inVal / (inVal + 5 * i4)) * 0.25, inVal * (10 / i4));
			var materialCost = i6 * Math.pow(i7, Math.pow(Math.round(inVal / i4) - 1, 0.8));
    		$('.resultB', container).text(lavaFunc(func,inVal,x1,x2));
    		$('.resultC', container).html(coindisplay(Math.floor(goldCost)));
    		if (inVal % i4 == offset){
    			$('.resultM', container).text(Math.floor(materialCost).toLocaleString());
    			$('.resultN', container).text("");
    		} else if (inVal < offset) {
    			$('.resultM', container).text((offset - inVal) + " Upgrades left before you need to increase the max level with");
    			$('.resultN', container).text(" Upgrades left before you need to increase the max level with");
    		} else {
    			$('.resultM', container).text(i4 - ((inVal + offset) % i4));
    			$('.resultN', container).text(" Upgrades left before you need to increase the max level with");
    		}
    	});
    });
	$.each($('.prayerDiv'), function(){
    	var container = $(this);
    	var bonus = parseInt($(this).data('bonus'));
    	var curse = parseInt($(this).data('curse'));
    	var multiplier = parseInt($(this).data('mult'));
    	var max = parseFloat($(this).data('max'));
    	var id = parseInt($(this).data('id'));
    	var factor = (!($(this).data('name') == 'The Royal Sampler') ? 1 : 2);
    	var pow = (!($(this).data('name') == 'The Royal Sampler') ? 1.12 : 1.3); //If not The Royal Sampler then 1.12.
    	$('.result1', container).text(bonus);
    	$('.result2', container).text(curse);
    	$('.result3', container).text(0);
    	$('.valInput', this).html('<input id="inField" type="number" min="1" max="'+max+'" placeholder=" Level " style="max-width: 100px;"/>');
    	$("#inField", this).change(function(){
    		var inVal = parseInt($(this).val());
    		$('.result1', container).text(bonus + (bonus *(inVal - 1))/10);
    		$('.result2', container).text(curse + (curse *(inVal - 1))/10);
            if (6 > inVal){
                $('.result3', container).text(Math.round(multiplier * (1 + (4 + (id/25)) * inVal)).toLocaleString());
            } else {
                $('.result3', container).text(Math.round(Math.min(2000000000, multiplier * (1 + (factor + (id/25)) * inVal) * Math.pow(pow, inVal - 5))).toLocaleString());
            };
    	});
    });
    $.each($('.gfoodDiv'), function(){
    	var container = $(this);
    	var amount = parseFloat($(this).data('amount'));
    	$('.result', container).text(0);
    	$('.valInput', this).html('<input id="inField" type="number" min="0" placeholder=" Quantity " style="max-width: 100px;"/>');
    	$("#inField", this).change(function(){
    		var inVal = parseInt($(this).val());
    		$('.result', container).text(goldFoodBonus(amount,inVal));
    	});
    });
    $.each($('.statueDiv'), function(){
    	var container = $(this);
    	var perLv = parseFloat($(this).data('amount'));
    	$('.result1', container).text(0);
    	$('.result2', container).text(0);
    	$('.valInput', this).html('<input id="inField" type="number" min="0" placeholder=" Level " style="max-width: 100px;"/>');
    	$("#inField", this).change(function(){
    		var inVal = parseInt($(this).val());
    		$('.result1', container).text(round(inVal*perLv));
    		$('.result2', container).text(Math.round(Math.pow(inVal,1.17)*Math.pow(1.35,inVal/10)+1));
    	});
    });
    $.each($('.cauldDiv'), function(){
    	var cauldCostReduxLvl = 0;
    	var bubbleCostBubbleLvl = 0;
    	var bubbleCostVialLvl = 0;
    	var bubbleBargainLvl = 0;
    	var bubbleMultClassLvl = 0;
    	var shopBargainBought = 0;
    	var riftVialMastery = 0;
    	var smrtAchievement = 0;
    	$('.cauldCostReduxLvlInput', this).html('<input id="inCauldCostReduxLvl" type="number" min="0" placeholder=" Level "/>');
    	$('.bubbleCostBubbleInput', this).html('<input id="inBubbleCostBubbleLvl" type="number" min="0" placeholder=" Level "/>');
    	$('.bubbleCostVialInput', this).html('<input id="inBubbleCostVialLvl" type="number" min="0" placeholder=" Level "/>');
    	$('.bubbleMultClassInput', this).html('<input id="inBubbleMultClassLvl" type="number" min="0" placeholder=" Level "/>');
    	$('.bubbleBargainInput', this).html('<input id="inBubbleBargainLvl" type="number" min="0" placeholder=" Level "/>');
    	$('.shopBargainInput', this).html('<input id="inShopBargainBought" type="number" min="0" placeholder=" Level "/>');
    	$('.riftVialMasteryInput', this).html('<input id="inRiftVialMasteryCount" type="number" min="0" placeholder=" Lvl 13 Vials " />');
    	$('.smrtBubbleInput', this).html('<input id="inSMRTAchievementUnlocked" type="checkbox" />');
    	$("#inCauldCostReduxLvl", this).change(function(){
    		cauldCostReduxLvl = parseInt($(this).val());
    	});
    	$("#inBubbleCostBubbleLvl", this).change(function(){
    		bubbleCostBubbleLvl = parseInt($(this).val());
    	});
    	$("#inBubbleCostVialLvl", this).change(function(){
    		bubbleCostVialLvl = parseInt($(this).val());
    	});
    	$("#inBubbleBargainLvl", this).change(function(){
    		bubbleBargainLvl = parseInt($(this).val());
    	});
    	$("#inBubbleMultClassLvl", this).change(function(){
    		bubbleMultClassLvl = parseInt($(this).val());
    	});
    	$("#inShopBargainBought", this).change(function(){
    		shopBargainBought = parseInt($(this).val());
    	});
    	$("#inRiftVialMasteryCount", this).change(function(){
    		riftVialMastery = parseInt($(this).val());
    	});
    	$("#inSMRTAchievementUnlocked", this).change(function(){
    		smrtAchievement = $(this).is(':checked') ? 1 : 0;
    	});
    	$.each($('.bubbleDiv'), function(){
    		var container = $(this);
    		var baseCost = $(this).data('basecost').split(',');
    		var matType = $(this).data('mattype').split(',');
    		var bubbleN = $(this).data('number');
    		var x1 = parseFloat($(this).data('x1'));
    		var x2 = parseFloat($(this).data('x2'));
    		var func = $(this).data('func');
    		var atoms = 0;
    		$('.valInput', this).html('<input id="inField" type="number" min="0" placeholder=" Level "/>');
    		for(i=0;i<baseCost.length;i++){
				var div = '.material' +(i+1);
				$(div, container).text(0);
			}
			$(".bonusOut", container).text(0);
    		$("#inField", this).change(function(){
    			var inVal = parseInt($(this).val());
				for(i=0;i<baseCost.length;i++){
					var div = '.material' +(i+1);
					var cost = calcBubbleMatCost(
						inVal, 
						parseInt(baseCost[i]),
						matType[i], 
						parseInt(bubbleN),
						cauldCostReduxLvl, 
						bubbleCostBubbleLvl, 
						bubbleCostVialLvl, 
						bubbleBargainLvl, 
						bubbleMultClassLvl, 
						shopBargainBought,
						riftVialMastery,
						smrtAchievement
						);
					if (i==0) {
						if (matType[0] == 0 && cost >= 1e8) {
							atomCost = Math.floor((cost / 1e9) * (bubbleN) * Math.pow(1.04, bubbleN - 1) * 100); // bubbleN starts at 1, but the needed value starts at 0.
							$('.atoms', container).html('<span class="tooltip"> ' + nFormatter(atomCost,2) + '<span>' + atomCost + '</span></span>');
						} else {
							$('.atoms', container).html('<span class="tooltip"> N/A<span>Unable to use Atoms.</span></span>');
						}
					}
					$(div, container).html('<span class="tooltip"> ' + nFormatter(cost,2) + '<span>' + cost + '</span></span>');
				}
				$(".bonusOut", container).text(round(lavaFunc(func,inVal,x1,x2), 3));
    		});	
    	});
    });
});

mw.loader.using('mobile.site.styles');

/* Sets the top property for stickyHeader tables */
/* Code borrowed with full permission from Coolrox95 on the Melvor Idle Wiki */
function setStickyHeaderTop() {
  const stickyTables = document.getElementsByClassName('stickyHeader');
  const headHeight = document.getElementById('mw-header-container').offsetHeight;
  for (i = 0; i < stickyTables.length; i++) {
    const firstRow = stickyTables[i].getElementsByClassName('headerRow-0');
    const secondRow = stickyTables[i].getElementsByClassName('headerRow-1');
    var firstHeight = 0;
    if (firstRow.length > 0) {
      firstHeight = firstRow[0].offsetHeight;
      const firstHeaders = firstRow[0].getElementsByTagName('th');
      for (j = 0; j < firstHeaders.length; j++) {
        firstHeaders[j].style.top = headHeight + 'px';
      }
      if (secondRow.length > 0) {
        const secondHeaders = secondRow[0].getElementsByTagName('th');
        var secondHeight = headHeight + firstHeight;
        for (j = 0; j < secondHeaders.length; j++) {
          secondHeaders[j].style.top = secondHeight + 'px';
        }
      }
    }
  }
}
$(document).ready(function () {
  if (document.getElementsByClassName('stickyHeader').length > 0) {
    setStickyHeaderTop();
    $(window).resize(setStickyHeaderTop);
  }
}
);


/*
================================================================================
Bandaid fix for dark mode not working due to caching.
================================================================================
*/
$(function() {
	if ($.cookie('darkModeOn') === 'true') {
		$('html').addClass('client-darkmode');
	} else {
		$('html').removeClass('client-darkmode');
	}
});