MediaWiki:Common.js: Difference between revisions

From Official Factorio Wiki
Jump to navigation Jump to search
(commented out functions again)
(expanded tab headers to 11)
 
(170 intermediate revisions by 3 users not shown)
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
/* Any JavaScript here will be loaded for all users on every page load. */


/* Infobox updating */
var apiUrl = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + "/api.php"


var version = "0.15.10";
/* Script in here will be executed when the page is "ready" */
$(document).ready(function() {
getNumberOfActiveUsers();
var elem = document.getElementById("evoChecker");
if(elem != null) {
elem.innerHTML =
'Alternatively, enter an evolution factor below to see the chances.<br>' +
'<input style="margin-bottom:10px" type="number" id="evoInput" min=0 max=1 step=0.01 placeholder="Evolution" onchange="calcEvo()"></input><br>' +
'<table style="float:left;margin-right:10px" class="wikitable" id="evoOutputBiter"></table>' +
'<table class="wikitable" id="evoOutputSpitter"></table>';
calcEvo();
}
});


/* $("#RecipeUpdate").click(function(){
/* show correct number of active users on the main page */
    getRecipes();
}); */


function getRecipes() {
function getNumberOfActiveUsers() {
    var Input = prompt("Please enter the recipes");
if (document.getElementById("active-users")) {
    if (Input != null) {
getToken();
var OldContent = "";
var Items = Input.split(/\s\s/g);
console.log(Items.length + " Items detected");
Items.forEach(RemoveDuplicateRecipesAndUpdateInfobox);
    }
};
 
 
function RemoveDuplicateRecipesAndUpdateInfobox(Recipes) {
var ItemNameEnd = Recipes.search("\\|");
var ItemName = Recipes.slice(0, ItemNameEnd);
ItemName = ItemName.trim();
var RecipeStart = Recipes.search("\\|recipe = ") + 10;
if (RecipeStart < 10) {
console.log(ItemName + ": No normal recipe found.");
var Recipe = "";
} else {
var RecipeCut = Recipes.slice(RecipeStart);
var RecipeEnd = RecipeCut.search("\\|");
if (RecipeEnd < 1) {
RecipeEnd = RecipeCut.search("}}");
if (RecipeEnd < 1) {
var Recipe = RecipeCut;
} else {
var Recipe = RecipeCut.slice(0, RecipeEnd);
}
} else {
var Recipe = RecipeCut.slice(0, RecipeEnd);
}
}
var TotalRawStart = Recipes.search("\\|total-raw = ") + 13;
if (TotalRawStart < 13) {
console.log(ItemName + ": No total raw found.");
var TotalRaw = "";
} else {
var TotalRawCut = Recipes.slice(TotalRawStart);
var TotalRawEnd = TotalRawCut.search("\\|");
if (TotalRawEnd < 1) {
TotalRawEnd = TotalRawCut.search("}}");
if (TotalRawEnd < 1) {
var TotalRaw = TotalRawCut;
} else {
var TotalRaw = TotalRawCut.slice(0, TotalRawEnd);
}
} else {
var TotalRaw = TotalRawCut.slice(0, TotalRawEnd);
}
}
var ExpRecipeStart = Recipes.search("\\|expensive-recipe = ") + 20;
if (ExpRecipeStart < 20) {
console.log(ItemName + ": No expensive recipe found.");
var ExpRecipe = "";
} else {
var ExpRecipeCut = Recipes.slice(ExpRecipeStart);
var ExpRecipeEnd = ExpRecipeCut.search("\\|");
if (ExpRecipeEnd < 1) {
ExpRecipeEnd = ExpRecipeCut.search("}}");
if (ExpRecipeEnd < 1) {
var ExpRecipe = ExpRecipeCut;
} else {
var ExpRecipe = ExpRecipeCut.slice(0, ExpRecipeEnd);
}
} else {
var ExpRecipe = ExpRecipeCut.slice(0, ExpRecipeEnd);
}
}
var ExpTotalRawStart = Recipes.search("\\|expensive-total-raw = ") + 23;
if (ExpTotalRawStart < 23) {
console.log(ItemName + ": No expensive total raw found.");
var ExpTotalRaw = "";
} else {
var ExpTotalRawCut = Recipes.slice(ExpTotalRawStart);
var ExpTotalRawEnd = ExpTotalRawCut.search("\\|");
if (ExpTotalRawEnd < 1) {
ExpTotalRawEnd = ExpTotalRawCut.search("}}");
if (ExpTotalRawEnd < 1) {
var ExpTotalRaw = ExpTotalRawCut;
} else {
var ExpTotalRaw = ExpTotalRawCut.slice(0, ExpTotalRawEnd);
}
} else {
var ExpTotalRaw = ExpTotalRawCut.slice(0, ExpTotalRawEnd);
}
}
//remove whitespace
//ItemName = ItemName.trim(); this is done further up for asthestics
Recipe = Recipe.trim();
TotalRaw = TotalRaw.trim();
ExpRecipe = ExpRecipe.trim();
ExpTotalRaw = ExpTotalRaw.trim();
//remove duplicate recipes, but only if the recipe actually exists
if ((ExpTotalRaw == ExpRecipe) && (ExpTotalRaw.length > 0)) {
ExpTotalRaw = "";
console.log(ItemName + ": Removed expensive-total-raw because it was a duplicate of expensive-recipe.");
} else if ((ExpTotalRaw == TotalRaw) && (ExpTotalRaw.length > 0)) {
ExpTotalRaw = "";
console.log(ItemName + ": Removed expensive-total-raw because it was a duplicate of total-raw.");
}
if ((ExpRecipe == Recipe) && (ExpRecipe.length > 0)) {
ExpRecipe = "";
console.log(ItemName + ": Removed expensive-recipe because it was a duplicate of recipe.");
}
if ((TotalRaw == Recipe) && (TotalRaw.length > 0)) {
TotalRaw = "";
console.log(ItemName + ": Removed total-raw because it was a duplicate of recipe.");
}
//Remove Itemnames if the item does not have a page on the wiki, so that the item is removed from the output
var NoInfobox = ["Express loader", "Fast loader", "Loader", "Basic oil processing", "Advanced oil processing", "Coal liquefaction", "Electric energy interface", "Empty barrel", "Heavy oil cracking", "Light oil cracking", "Player port", "Railgun", "Railgun dart", "Small plane", "Solid fuel from heavy oil", "Solid fuel from light oil", "Solid fuel from petroleum gas"]
NoInfobox.forEach(function(InfoboxName) {
if (ItemName == InfoboxName) {
console.log("Removed " + ItemName + " from output.");
ItemName = "";
}
})
var OldContent = "";
if (ItemName.length > 0) {
//get page content of the item -> OldContent
$.ajax({
$.ajax({
url: 'https://wiki.factorio.com/api.php',
url: apiUrl,
data: {
data: {
format: 'json',
format: 'json',
action: 'query',
action: 'query',
titles: ItemName + '/infobox',
list: 'allusers',
prop: 'revisions',
aulimit: 500,
rvprop: 'content'
auactiveusers: true
},
},
async: false,
dataType: 'json',
dataType: 'json',
type: 'GET',
type: 'GET',
success: function( data ) {
success: function(data) {
var pages = data.query.pages;
document.getElementById("active-users").innerHTML = data.query.allusers.length.toString();
var revisions = pages[Object.keys(pages)[0]].revisions[0];
OldContent = revisions[Object.keys(revisions)[2]];
var title = pages[Object.keys(pages)[0]].title;
},
},
error: function( xhr ) {
error: function(xhr) {
alert( 'Error: Request failed.' );
console.log( 'Error: Request failed.' );
OldContent = "";
}
}
});
});
} else {
OldContent = "";
}
}
};
 
if (OldContent.length > 0) {
/* Collapsible list on [[Prototype definitions]] */
//find recipes in page (OldContent)
 
var PageRecipeStart = OldContent.search("\\|recipe") + 7;
$(".prototype-tree li").each(function (index, element) {
if (PageRecipeStart < 7) {
  if ( $( element ).children("ul").length > 0 ) {
console.log(ItemName + ": No normal recipe found on page.");
    $( element ).addClass("prototype-tree-parent");
var PageRecipe = "";
  };
} else {
});
var PageRecipeCut = OldContent.slice(PageRecipeStart);
 
PageRecipeCut.trim(); //removes possible whitespace in front off =
$(".prototype-tree li.prototype-tree-parent").on("click", function(event) {
PageRecipeCut = PageRecipeCut.slice(1); //removes =
// only collapse if I clicked a li or the direct child of a li that is not another list or a link
PageRecipeCut.trim(); //removes possible whitespace after =
  if ( $( event.currentTarget ).children("ul").length > 0 && $( event.target ).get(0).tagName != "UL" && $( event.target ).get(0).tagName != "A" && ($( event.target ).hasClass("prototype-tree-parent") || $( event.target ).parent().hasClass("prototype-tree-parent")) ) {
var PageRecipeEnd = PageRecipeCut.search("\\|");
    $( event.currentTarget ).children("ul")[0].classList.toggle("hidden");
if (PageRecipeEnd < 1) {
    $( event.currentTarget ).toggleClass("prototype-tree-parent-collapsed");
PageRecipeEnd = PageRecipeCut.search("}}");
    return false; // prevents further event bubbling
if (PageRecipeEnd < 1) {
  }
var PageRecipe = PageRecipeCut;
});
} else {
 
var PageRecipe = PageRecipeCut.slice(0, PageRecipeEnd);
/* Evolution calc */
}
 
} else {
//values are in the form [evolution, weight]
var PageRecipe = PageRecipeCut.slice(0, PageRecipeEnd);
const biterSpawner = [
}
["Small Biter",    [[0.0, 0.3], [0.6, 0.0]]],
}
["Medium Biter",  [[0.2, 0.0], [0.6, 0.3], [0.7, 0.1]]],
["Big Biter",      [[0.5, 0.0], [1.0, 0.4]]],
["Behemoth Biter", [[0.9, 0.0], [1.0, 0.3]]]
];
const spitterSpawner = [
["Small Biter",      [[0.0, 0.3], [0.35, 0.0]]],
["Small Spitter",    [[0.25, 0.0], [0.5, 0.3], [0.7, 0.0]]],
["Medium Spitter",  [[0.4, 0.0], [0.7, 0.3], [0.9, 0.1]]],
["Big Spitter",      [[0.5, 0.0], [1.0, 0.4]]],
["Behemoth Spitter", [[0.9, 0.0], [1.0, 0.3]]]
];
 
//calculates the interpolated value
function lerp(low, high, pos) {
const s = high[0] - low[0];
const l = (pos - low[0]) / s;
return (low[1] * (1-l)) + (high[1] * l);
};
 
//gets the weight list
function getValues(map, evo) {
var result = {};
var sum = 0;
map.forEach(function(data) {
const list = data[1];
var low = list[0];
var high = list[list.length-1];
list.forEach(function(val) {
if(val[0] <= evo && val[0] >  low[0])  low = val;
if(val[0] >= evo && val[0] < high[0]) high = val;
});
var val = null;
if(evo <= low[0]) val = low[1];
else if(evo >= high[0]) val = high[1];
else val = lerp(low, high, evo);
sum += val;
result[data[0]] = val;
});
Object.keys(result).forEach(function(data, index) {
result[data] = result[data] / sum;
});
return result;
};
 
function calcEvo() {
const evo = document.getElementById("evoInput").value;
genTable(getValues(biterSpawner, evo), document.getElementById("evoOutputBiter"), "Biter's Nest");
genTable(getValues(spitterSpawner, evo), document.getElementById("evoOutputSpitter"), "Spitter's Nest");
};
 
function percentile(value) {
return (value*100).toFixed(2) + "%";
};
 
function genTable(data, tableElem, title) {
var html = '<tr><th>'+title+'</th><th>Chance</th>';
Object.keys(data).forEach(function(value) {
html += '<tr><td>'+value+'</td><td>'+percentile(data[value])+'</td>';
});
tableElem.innerHTML = html;
};
 
/* Template:Inventory tooltips */
 
var lastTouchTime = 0;
document.addEventListener('touchstart', updateLastTouchTime, true);
function updateLastTouchTime() {
  lastTouchTime = new Date();
}
 
$(".tab-head").mousemove(function(e) {
  if (e.buttons > 0) return;
  if (new Date() - lastTouchTime < 500) return;
  var countCssRules = document.styleSheets[0].cssRules.length;
  var newRule = '.tab-head:hover:after{display: block; left: ' + (e.offsetX + 20) + 'px; top: ' + (e.offsetY + 20) + 'px;}';
  document.styleSheets[0].insertRule(newRule, countCssRules);
});
 
$(".tab .factorio-icon").mousemove(function(e) {
  if (e.buttons > 0) return;
  if (new Date() - lastTouchTime < 500) return;
  var countCssRules = document.styleSheets[0].cssRules.length;
  $(e.currentTarget).children("a").attr("title", "");
  var text = $(e.currentTarget).children("a").children("img").attr("alt");
  var newRule = '.tab .factorio-icon:hover:after{display: block; ' + "content: '" + text + "'}";
  document.styleSheets[0].insertRule(newRule, countCssRules);
});
 
/* Template:BlueprintString */
 
$(".bps-box").click(function(event) {
var copyTarget = document.createElement("input");
copyTarget.setAttribute("value", $( event.target ).children("p").html());
document.body.appendChild(copyTarget);
copyTarget.select();
document.execCommand("copy");
document.body.removeChild(copyTarget);
});
 
/* Template:Inventory */
 
$(".tab-head-1").click(function() {
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-1").show();
});
 
$(".tab-head-2").click(function() {
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-2").show();
});
 
$(".tab-head-3").click(function() {
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-3").show();
});
 
$(".tab-head-4").click(function() {
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-4").show();
});
 
$(".tab-head-5").click(function() {
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-5").show();
});
 
$(".tab-head-6").click(function() {
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-6").show();
});
 
$(".tab-head-7").click(function() {
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-7").show();
});
 
$(".tab-head-8").click(function() {
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-8").show();
});
 
$(".tab-head-9").click(function() {
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-9").show();
});
 
$(".tab-head-10").click(function() {
$(".tab-head").removeClass("tab-head-active");
$(this).addClass("tab-head-active");
$(".tab").hide();
$(".tab-10").show();
});


var PageTotalRawStart = OldContent.search("\\|total-raw") + 10;
$(".tab-head-11").click(function() {
if (PageTotalRawStart < 10) {
$(".tab-head").removeClass("tab-head-active");
console.log(ItemName + ": No total raw found on page.");
$(this).addClass("tab-head-active");
var PageTotalRaw = "";
$(".tab").hide();
} else {
$(".tab-11").show();
var PageTotalRawCut = OldContent.slice(PageTotalRawStart);
});
PageTotalRawCut.trim(); //removes possible whitespace in front off =
PageTotalRawCut = PageTotalRawCut.slice(1); //removes =
PageTotalRawCut.trim(); //removes possible whitespace after =
var PageTotalRawEnd = PageTotalRawCut.search("\\|");
if (PageTotalRawEnd < 1) {
PageTotalRawEnd = PageTotalRawCut.search("}}");
if (PageTotalRawEnd < 1) {
var PageTotalRaw = PageTotalRawCut;
} else {
var PageTotalRaw = PageTotalRawCut.slice(0, PageTotalRawEnd);
}
} else {
var PageTotalRaw = PageTotalRawCut.slice(0, PageTotalRawEnd);
}
}
var PageExpRecipeStart = OldContent.search("\\|expensive-recipe") + 17;
if (PageExpRecipeStart < 17) {
console.log(ItemName + ": No expensive recipe found on page.");
var PageExpRecipe = "";
} else {
var PageExpRecipeCut = OldContent.slice(PageExpRecipeStart);
PageExpRecipeCut.trim(); //removes possible whitespace in front off =
PageExpRecipeCut = PageExpRecipeCut.slice(1); //removes =
PageExpRecipeCut.trim(); //removes possible whitespace after =
var PageExpRecipeEnd = PageExpRecipeCut.search("\\|");
if (PageExpRecipeEnd < 1) {
PageExpRecipeEnd = PageExpRecipeCut.search("}}");
if (PageExpRecipeEnd < 1) {
var PageExpRecipe = PageExpRecipeCut;
} else {
var PageExpRecipe = PageExpRecipeCut.slice(0, PageExpRecipeEnd);
}
} else {
var PageExpRecipe = PageExpRecipeCut.slice(0, PageExpRecipeEnd);
}
}


var PageExpTotalRawStart = OldContent.search("\\|expensive-total-raw") + 20;
//*** Language template ***//
if (PageExpTotalRawStart < 20) {
if($(".languages-flags .flag").length == 0) {
console.log(ItemName + ": No expensive total raw found on page.");
console.log("Not showing languages bar because there's no other language's version of this page.");
var PageExpTotalRaw = "";
$(".languages-container").hide();
} else {
var PageExpTotalRawCut = OldContent.slice(PageExpTotalRawStart);
PageExpTotalRawCut.trim(); //removes possible whitespace in front off =
PageExpTotalRawCut = PageExpTotalRawCut.slice(1); //removes =
PageExpTotalRawCut.trim(); //removes possible whitespace after =
var PageExpTotalRawEnd = PageExpTotalRawCut.search("\\|");
if (PageExpTotalRawEnd < 1) {
PageExpTotalRawEnd = PageExpTotalRawCut.search("}}");
if (PageExpTotalRawEnd < 1) {
var PageExpTotalRaw = PageExpTotalRawCut;
} else {
var PageExpTotalRaw = PageExpTotalRawCut.slice(0, PageExpTotalRawEnd);
}
} else {
var PageExpTotalRaw = PageExpTotalRawCut.slice(0, PageExpTotalRawEnd);
}
}
//remove whitespace
PageRecipe = PageRecipe.trim();
PageTotalRaw = PageTotalRaw.trim();
PageExpRecipe = PageExpRecipe.trim();
PageExpTotalRaw = PageExpTotalRaw.trim();
var Summary = "";
//change page if anything is different (this INCLUDES different formatting)
var NewContent = "";
if ((PageRecipe == Recipe) && (PageTotalRaw == TotalRaw) && (PageExpRecipe == ExpRecipe) && (PageExpTotalRaw == ExpTotalRaw)) {
console.log(ItemName + " page was not changed.")
} else {
if (PageRecipe.length > 0) {
var NewPageRecipeStart = OldContent.search("\\|recipe") + 7;
var NewPageRecipeCut = OldContent.slice(NewPageRecipeStart);
var NewPageRecipeEnd = NewPageRecipeCut.search("\\|");
if (NewPageRecipeEnd < 1) {
NewPageRecipeEnd = NewPageRecipeCut.search("}}");
}
var ActualNewPageRecipeEnd = NewPageRecipeStart + NewPageRecipeEnd;
if (Recipe.length > 0) {
NewContent = OldContent.slice(0, NewPageRecipeStart) + " = " + Recipe + "\n" + OldContent.slice(ActualNewPageRecipeEnd) //I'm just assuming that PageRecipeEnd must exist because the infobox HAS to end with }}
console.log("Replaced " + ItemName + " recipe.");
Summary = Summary + "Updated recipe to " + version + ". ";
} else {
NewPageRecipeStart = NewPageRecipeStart - 7;
NewContent = OldContent.slice(0, NewPageRecipeStart) + OldContent.slice(ActualNewPageRecipeEnd) //I'm just assuming that PageRecipeEnd must exist because the infobox HAS to end with }}
console.log("Removed " + ItemName + " recipe.");
Summary = Summary + "Removed recipe. ";
}
} else if (Recipe.length > 0) {
var InfoboxStart = OldContent.search("{{Infobox") + 9;
if (InfoboxStart < 9) {
InfoboxStart = OldContent.search("{{infobox") + 9;
}
NewContent = OldContent.slice(0, InfoboxStart) + "\n|recipe = " + Recipe + OldContent.slice(InfoboxStart)
console.log("Added " + ItemName + " recipe to the start of the infobox because no recipe existed beforehand.");
Summary = Summary + "Added recipe. ";
}
if (PageTotalRaw.length > 0) {
var NewPageTotalRawStart = NewContent.search("\\|total-raw") + 10;
var NewPageTotalRawCut = NewContent.slice(NewPageTotalRawStart);
var NewPageTotalRawEnd = NewPageTotalRawCut.search("\\|");
if (NewPageTotalRawEnd < 1) {
NewPageTotalRawEnd = NewPageTotalRawCut.search("}}");
}
var ActualNewPageTotalRawEnd = NewPageTotalRawStart + NewPageTotalRawEnd;
if (TotalRaw.length > 0) {
NewContent = NewContent.slice(0, NewPageTotalRawStart) + " = " + TotalRaw + "\n" + NewContent.slice(ActualNewPageTotalRawEnd) //I'm just assuming that NewPageTotalRawEnd must exist because the infobox HAS to end with }}
console.log("Replaced " + ItemName + " total-raw.");
Summary = Summary + "Updated total-raw to " + version + ". ";
} else {
NewPageTotalRawStart = NewPageTotalRawStart - 10;
NewContent = NewContent.slice(0, NewPageTotalRawStart) + NewContent.slice(ActualNewPageTotalRawEnd) //I'm just assuming that NewPageTotalRawEnd must exist because the infobox HAS to end with }}
console.log("Removed " + ItemName + " total-raw. ");
Summary = Summary + "Removed total-raw.";
}
} else if (TotalRaw.length > 0) {
var InfoboxStart = NewContent.search("{{Infobox") + 9;
if (InfoboxStart < 9) {
InfoboxStart = NewContent.search("{{infobox") + 9;
}
NewContent = NewContent.slice(0, InfoboxStart) + "\n|total-raw = " + TotalRaw + NewContent.slice(InfoboxStart)
console.log("Added " + ItemName + " total-raw to the start of the infobox because no total-raw existed beforehand.");
Summary = Summary + "Added total-raw. ";
}
if (PageExpRecipe.length > 0) {
var NewPageExpRecipeStart = NewContent.search("\\|expensive-recipe") + 17;
var NewPageExpRecipeCut = NewContent.slice(NewPageExpRecipeStart);
var NewPageExpRecipeEnd = NewPageExpRecipeCut.search("\\|");
if (NewPageExpRecipeEnd < 1) {
NewPageExpRecipeEnd = NewPageExpRecipeCut.search("}}");
}
var ActualNewPageExpRecipeEnd = NewPageExpRecipeStart + NewPageExpRecipeEnd;
if (ExpRecipe.length > 0) {
NewContent = NewContent.slice(0, NewPageExpRecipeStart) + " = " + ExpRecipe + "\n" + NewContent.slice(ActualNewPageExpRecipeEnd) //I'm just assuming that NewPageExpRecipeEnd must exist because the infobox HAS to end with }}
console.log("Replaced " + ItemName + " expensive-recipe.");
Summary = Summary + "Updated expensive-recipe to " + version + ". ";
} else {
NewPageExpRecipeStart = NewPageExpRecipeStart - 17;
NewContent = NewContent.slice(0, NewPageExpRecipeStart) + NewContent.slice(ActualNewPageExpRecipeEnd) //I'm just assuming that NewPageExpRecipeEnd must exist because the infobox HAS to end with }}
console.log("Removed " + ItemName + " expensive-recipe.");
Summary = Summary + "Removed expensive-recipe. ";
}
} else if (ExpRecipe.length > 0) {
var InfoboxStart = NewContent.search("{{Infobox") + 9;
if (InfoboxStart < 9) {
InfoboxStart = NewContent.search("{{infobox") + 9;
}
NewContent = NewContent.slice(0, InfoboxStart) + "\n|expensive-recipe = " + ExpRecipe + NewContent.slice(InfoboxStart)
console.log("Added " + ItemName + " expensive-recipe to the start of the infobox because no expensive-recipe existed beforehand.");
Summary = Summary + "Added expensive-recipe. ";
}
if (PageExpTotalRaw.length > 0) {
var NewPageExpTotalRawStart = NewContent.search("\\|expensive-total-raw") + 20;
var NewPageExpTotalRawCut = NewContent.slice(NewPageExpTotalRawStart);
var NewPageExpTotalRawEnd = NewPageExpTotalRawCut.search("\\|");
if (NewPageExpTotalRawEnd < 1) {
NewPageExpTotalRawEnd = NewPageExpTotalRawCut.search("}}");
}
var ActualNewPageExpTotalRawEnd = NewPageExpTotalRawStart + NewPageExpTotalRawEnd;
if (ExpTotalRaw.length > 0) {
NewContent = NewContent.slice(0, NewPageExpTotalRawStart) + " = " + ExpTotalRaw + "\n" + NewContent.slice(ActualNewPageExpTotalRawEnd) //I'm just assuming that NewPageExpTotalRawEnd must exist because the infobox HAS to end with }}
console.log("Replaced " + ItemName + " expensive-total-raw.");
Summary = Summary + "Updated expensive-total-raw to " + version + ". ";
} else {
NewPageExpTotalRawStart = NewPageExpTotalRawStart - 20;
NewContent = NewContent.slice(0, NewPageExpTotalRawStart) + NewContent.slice(ActualNewPageExpTotalRawEnd) //I'm just assuming that NewPageExpTotalRawEnd must exist because the infobox HAS to end with }}
console.log("Removed " + ItemName + " expensive-total-raw.");
Summary = Summary + "Removed expensive-total-raw. ";
}
} else if (ExpTotalRaw.length > 0) {
var InfoboxStart = NewContent.search("{{Infobox") + 9;
if (InfoboxStart < 9) {
InfoboxStart = NewContent.search("{{infobox") + 9;
}
NewContent = NewContent.slice(0, InfoboxStart) + "\n|expensive-total-raw = " + ExpTotalRaw +  NewContent.slice(InfoboxStart)
console.log("Added " + ItemName + " expensive-total-raw to the start of the infobox because no expensive-total-raw existed beforehand.");
Summary = Summary + "Added expensive-total-raw. ";
}
}
//alright, NewContent should be defined, change page:
if (NewContent.length > 0) {
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: 'json',
action: 'edit',
title: ItemName + '/infobox',
text: NewContent,
token: globalToken,
summary: Summary,
bot: true,
nocreate: true
},
async: false,
dataType: 'json',
type: 'POST',
success: function( data ) {
  console.log("Updated " + ItemName);
},
error: function( xhr ) {
console.log("Failed to update " + ItemName);
}
});
}
}
}
}


/* $("#ConsumerUpdate").click(function(){
//Spoiler template
    getConsumers();
$(".spoiler-container .button").click(function() {
}); */
$(this).siblings(".text").toggle("slow");
});
 
//* General/generic functions *//
 
/* User is bot if userGroup.some(isBot) == true */
 
var userGroup = "";


function getConsumers() {
function getUserGroup() {
    var Input = prompt("Please enter the consumers");
$.ajax({
    if (Input != null) {
url: apiUrl,
getToken();
data: {
var Items = Input.split(/\s\s/g);
format: 'json',
console.log(Items.length + " Items detected");
action: 'query',
Items.forEach(UpdateInfoboxWithConsumers);
meta: 'userinfo',
    }
uiprop: 'groups',
},
async: false,
dataType: 'json',
type: 'GET',
success: function(data) {
userGroup = data.query.userinfo.groups
},
});
};
};


function UpdateInfoboxWithConsumers(Inputt) {
function isBot(group) {
var ItemNameEnd = Inputt.search("\\|");
return group == "bot";
var ItemName = Inputt.slice(0, ItemNameEnd);
ItemName = ItemName.trim();
var ConsumersStart = Inputt.search("\\|consumers = ") + 13;
var Consumers = Inputt.slice(ConsumersStart);
Consumers = Consumers.trim();
//Remove Itemnames if the item does not have a page on the wiki, so that the item is removed from the output
var NoInfobox = ["Express loader", "Fast loader", "Loader", "Basic oil processing", "Advanced oil processing", "Coal liquefaction", "Electric energy interface", "Empty barrel", "Heavy oil cracking", "Light oil cracking", "Player port", "Railgun", "Railgun dart", "Small plane", "Solid fuel from heavy oil", "Solid fuel from light oil", "Solid fuel from petroleum gas"]
NoInfobox.forEach(function(InfoboxName) {
if (ItemName == InfoboxName) {
console.log("Removed " + ItemName + " from output.");
ItemName = "";
}
})
var OldContent = "";
if (ItemName.length > 0) {
//get page content of the item -> OldContent
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: 'json',
action: 'query',
titles: ItemName + '/infobox',
prop: 'revisions',
rvprop: 'content'
},
async: false,
dataType: 'json',
type: 'GET',
success: function( data ) {
var pages = data.query.pages;
var revisions = pages[Object.keys(pages)[0]].revisions[0];
OldContent = revisions[Object.keys(revisions)[2]];
var title = pages[Object.keys(pages)[0]].title;
},
error: function( xhr ) {
alert( 'Error: Request failed.' );
OldContent = "";
}
});
} else {
OldContent = "";
}
if (OldContent.length > 0) {
//find recipes in page (OldContent)
var PageConsumersStart = OldContent.search("\\|consumers") + 10;
if (PageConsumersStart < 10) {
console.log(ItemName + ": No consumers found on page.");
var PageConsumers = "";
} else {
var PageConsumersCut = OldContent.slice(PageConsumersStart);
PageConsumersCut.trim(); //removes possible whitespace in front off =
PageConsumersCut = PageConsumersCut.slice(1); //removes =
PageConsumersCut.trim(); //removes possible whitespace after =
var PageConsumersEnd = PageConsumersCut.search("\\|");
if (PageConsumersEnd < 1) {
PageConsumersEnd = PageConsumersCut.search("}}");
if (PageConsumersEnd < 1) {
var PageConsumers = PageConsumersCut;
} else {
var PageConsumers = PageConsumersCut.slice(0, PageConsumersEnd);
}
} else {
var PageConsumers = PageConsumersCut.slice(0, PageConsumersEnd);
}
}
PageConsumers = PageConsumers.trim();
var Summary = "";
//change page if anything is different (this INCLUDES different formatting)
var NewContent = "";
if (PageConsumers == Consumers) {
console.log(ItemName + " page was not changed.")
} else {
if (PageConsumers.length > 0) {
var NewPageConsumersStart = OldContent.search("\\|consumers") + 10;
var NewPageConsumersCut = OldContent.slice(NewPageConsumersStart);
var NewPageConsumersEnd = NewPageConsumersCut.search("\\|");
if (NewPageConsumersEnd < 1) {
NewPageConsumersEnd = NewPageConsumersCut.search("}}");
}
var ActualNewPageConsumersEnd = NewPageConsumersStart + NewPageConsumersEnd;
NewContent = OldContent.slice(0, NewPageConsumersStart) + " = " + Consumers + "\n" + OldContent.slice(ActualNewPageConsumersEnd) //I'm just assuming that PageRecipeEnd must exist because the infobox HAS to end with }}
console.log("Replaced " + ItemName + " consumers.");
Summary = Summary + "Updated consumers to " + version + ". ";
} else if (Consumers.length > 0) {
var InfoboxEnd = OldContent.search("}}");
NewContent = OldContent.slice(0, InfoboxEnd) + "|consumers = " + Consumers + "\n" +  OldContent.slice(InfoboxEnd)
console.log("Added " + ItemName + " consumers to the end of the infobox because no consumers existed beforehand.");
Summary = Summary + "Added consumers. ";
}
}
//alright, NewContent should be defined, change page:
if (NewContent.length > 0) {
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: 'json',
action: 'edit',
title: ItemName + '/infobox',
text: NewContent,
token: globalToken,
summary: Summary,
bot: true,
nocreate: true
},
async: false,
dataType: 'json',
type: 'POST',
success: function( data ) {
  console.log("Updated " + ItemName);
},
error: function( xhr ) {
console.log("Failed to update " + ItemName);
}
});
}
}
}
}
/* Get token of this session */


var globalToken;
var globalToken;
Line 554: Line 287:
function getToken() {
function getToken() {
     $.ajax({
     $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         url: apiUrl,
         data: {
         data: {
             format: 'json',
             format: 'json',
Line 568: Line 301:
         },
         },
         error: function( xhr ) {
         error: function( xhr ) {
             console.log("Failed to perform null edit");
             console.log("Failed to get token.");
         }
         }
     });
     });
}
}


/*** Language template ***/
if($(".languages-flags .flag").length == 0) {
console.log("Not showing languages bar because there's no other language's version of this page.");
$(".languages-container").hide();
}


//Spoiler template JavaScript
function genericEditPage(title, content, summary) {
$(".spoiler-container .button").click(function() {
$.ajax({
  $(this).siblings(".text").toggle("slow");
url: apiUrl,
});
data: {
 
format: 'json',
var wantedPagesListsLocation = "User:TheWombatGuru/WantedPages"
action: 'edit',
//Commented out this function to prevent non-admin users from using the bot because their api limits are too low to use it properly
title: title,
/* $("#create-wanted-pages-list").click(function(){
text: content,
    getToken();
token: globalToken,
    createWantedPagesLists();
summary: summary,
}); */
bot: true,
 
nocreate: true
function createWantedPagesLists() {
},
    var wantedPages = getWantedPages();
dataType: 'json',
    wantedPages = wantedPages.sort(compare);
type: 'POST',
 
success: function( data ) {
    splitWantedPagesIntoDifferentLanguages(wantedPages);
console.log("Edited " + title);
},
error: function( xhr ) {
alert("Failed to edit " + title);
}
});
};
};


function splitWantedPagesIntoDifferentLanguages(wantedPages) {
  var czechWantedPages = [];
  var germanWantedPages = [];
  var spanishWantedPages = [];
  var frenchWantedPages = [];
  var italianWantedPages = [];
  var japaneseWantedPages = [];
  var dutchWantedPages = [];
  var polishWantedPages = [];
  var portugueseWantedPages = [];
  var russianWantedPages = [];
  var swedishWantedPages = [];
  var ukrainianWantedPages = [];
  var chineseWantedPages = [];
  var turkishWantedPages = [];
  var wantedFiles = [];
  var wantedTemplates = [];
  var otherWantedPages = [];


  for (var i = 0; i < wantedPages.length; i++) {
function createPage(pageTitle, content, summary) {
     switch (wantedPages[i].title.slice(-3)) {//"/cs", "/de", "/es", "/fr", "/it", "/ja", "/nl", "/pl", "/-br", "/ru", "/sv", "/uk", "/zh", "/tr"
     $.ajax({
      case "/cs": czechWantedPages.push(wantedPages[i]); break;
        url: apiUrl,
      case "/de": germanWantedPages.push(wantedPages[i]); break;
        data: {
      case "/es": spanishWantedPages.push(wantedPages[i]); break;
format: 'json',
      case "/fr": frenchWantedPages.push(wantedPages[i]); break;
action: 'edit',
      case "/it": italianWantedPages.push(wantedPages[i]); break;
title: pageTitle,
      case "/ja": japaneseWantedPages.push(wantedPages[i]); break;
text: content,
      case "/nl": dutchWantedPages.push(wantedPages[i]); break;
token: globalToken,
      case "/pl": polishWantedPages.push(wantedPages[i]); break;
summary: summary,
      case "-br": portugueseWantedPages.push(wantedPages[i]); break;
bot: true
      case "/ru": russianWantedPages.push(wantedPages[i]); break;
        },
      case "/sv": swedishWantedPages.push(wantedPages[i]); break;
        async: false,
      case "/uk": ukrainianWantedPages.push(wantedPages[i]); break;
        dataType: 'json',
      case "/zh": chineseWantedPages.push(wantedPages[i]); break;
        type: 'POST',
      case "/tr": turkishWantedPages.push(wantedPages[i]); break;
        success: function( data ) {
      default: if (wantedPages[i].title.slice(0, 5) == "File:") {wantedFiles.push(wantedPages[i])} else if (wantedPages[i].title.slice(0, 9) == "Template:") {wantedTemplates.push(wantedPages[i])} else {otherWantedPages.push(wantedPages[i])}; break;
console.log("Created page: " + pageTitle);
    }
        },
  }
        error: function( xhr ) {
 
console.log("Failed to create page");
  createWantedPagesPage("cs", czechWantedPages, "Czech");
        }
  createWantedPagesPage("de", germanWantedPages, "German");
    });
  createWantedPagesPage("es", spanishWantedPages, "Spanish");
  createWantedPagesPage("fr", frenchWantedPages, "French");
  createWantedPagesPage("it", italianWantedPages, "Italian");
  createWantedPagesPage("ja", japaneseWantedPages, "Japanese");
  createWantedPagesPage("nl", dutchWantedPages, "Dutch");
  createWantedPagesPage("pl", polishWantedPages, "Polish");
  createWantedPagesPage("pt-br", portugueseWantedPages, "Portuguese");
  createWantedPagesPage("ru", russianWantedPages, "Russian");
  createWantedPagesPage("sv", swedishWantedPages, "Swedish");
  createWantedPagesPage("uk", ukrainianWantedPages, "Ukrainian");
  createWantedPagesPage("zh", chineseWantedPages, "Chinese");
  createWantedPagesPage("tr", turkishWantedPages, "Turkish");
 
  createWantedPagesPage("file", wantedFiles, "Files");
  createWantedPagesPage("template", wantedTemplates, "Templates");
  createWantedPagesPage("other", otherWantedPages, "Other");
}
}


function createWantedPagesPage(location, wantedPages, language) {
function getBacklinks(page) {
  var formattedWantedPages = "Number of wanted pages in " + language + ": " + wantedPages.length + "\n{|class=wikitable\n!#\n!Page\n!Links to this page";
var backlinks = [];
$.ajax({
url: apiUrl,
data: {
format: 'json',
action: 'query',
list: 'backlinks',
bltitle: page,
bllimit: 1000,
},
async: false,
type: 'GET',
success: function( data ) {
backlinks = data.query.backlinks;
},
error: function( xhr ) {
alert( 'Error: Backlinks request failed.' );
}
});
return backlinks;
};


  for (var i = 0; i < wantedPages.length; i++) {
function getFileUsage(file) {
    formattedWantedPages = formattedWantedPages.concat("\n|-\n|" + (i + 1) + "\n|[https://wiki.factorio.com/index.php?title=" + encodeURI(wantedPages[i].title) + " " + wantedPages[i].title + "]\n|[https://wiki.factorio.com/index.php?title=Special:WhatLinksHere/" + encodeURI(wantedPages[i].title) + " " + wantedPages[i].value + "]");
var imageusage = [];
  }
$.ajax({
 
url: apiUrl,
  formattedWantedPages = formattedWantedPages.concat("\n|}");
data: {
 
format: 'json',
  createPage(wantedPagesListsLocation + "/" + location, formattedWantedPages, "(BOT) - Update the list of wanted pages for " + language + ".");
action: 'query',
}
list: 'imageusage',
iutitle: file,
iulimit: 1000
},
async: false,
type: 'GET',
success: function( data ) {
imageusage = data.query.imageusage;
},
error: function( xhr ) {
alert( 'Error: Imageusage request failed.' );
}
});
return imageusage;
};


function performNullEdit(pageTitle, summary) {
function performNullEdit(pageTitle, summary) {
     $.ajax({
     $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         url: apiUrl,
         data: {
         data: {
             format: 'json',
             format: 'json',
Line 696: Line 429:
function purgeWhatLinksHere(pageTitle) {
function purgeWhatLinksHere(pageTitle) {
     $.ajax({
     $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         url: apiUrl,
         data: {
         data: {
             format: "json",
             format: "json",
Line 721: Line 454:
function purgePage(pageTitle) {
function purgePage(pageTitle) {
     $.ajax({
     $.ajax({
         url: 'https://wiki.factorio.com/api.php',
         url: apiUrl,
         data: {
         data: {
             action: 'purge',
             action: 'purge',
Line 739: Line 472:
     });
     });
}
}
function compare(a,b) {
  if (parseInt(a.value) > parseInt(b.value))
    return -1;
  if (parseInt(a.value) < parseInt(b.value))
    return 1;
  if (a.title < b.title)
    return -1;
  if (a.title > b.title)
    return 1;
  return 0;
}
function createPage(pageTitle, content, summary) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            text: content,
            token: globalToken,
            summary: summary,
            bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
          console.log("created page");
        },
        error: function( xhr ) {
            console.log("failed to create page");
        }
    });
}
function getWantedPages() {
  var wantedPages = [];
  $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            list: 'querypage',
            qppage: 'Wantedpages',
            qplimit: '5000',
        },
        async: false,
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var results = data.query.querypage.results;
            for (var i = 0; i < results.length; i++) {
              var pageObject = new WantedPage(results[i].title, results[i].value);
              var alreadyInArray = false;
              for (var j = 0; j < wantedPages.length; j++) {
                if (wantedPages[j].title == pageObject.title) {
                    alreadyInArray = true;
                }
              }
              if (!alreadyInArray) {
                wantedPages.push(pageObject);
              }
              if (pageObject.title == "Rocket defense/it") {
              }
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed. Category' );
        }
  });
$.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            list: 'querypage',
            qppage: 'Wantedpages',
            qplimit: '5000',
            qpoffset: '3000',
        },
        async: false,
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var results = data.query.querypage.results;
            for (var i = 0; i < results.length; i++) {
              var pageObject = new WantedPage(results[i].title, results[i].value);
              var alreadyInArray = false;
              for (var j = 0; j < wantedPages.length; j++) {
                if (wantedPages[j].title == pageObject.title) {
                    alreadyInArray = true;
                }
              }
              if (!alreadyInArray) {
                wantedPages.push(pageObject);
              }
              if (pageObject.title == "Rocket defense/it") {
              }
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed. Category' );
        }
  });
  return wantedPages;
};
function WantedPage(pageTitle, pageValue) {
  this.title = pageTitle;
  this.value = pageValue;
}
/* OLD INFOBOX CONVERSION TOOLS */
/*function targetAllPagesInCategory(category) {
    var languageSuffixes = ["/fr", "/ru", "/de"]; //, "/cs", "/de", "/es", "/fr", "/it", "/nl", "/pl", "/pt-br", "/ru", "/sv", "/uk", "/zh", ""];
    for (var j = 0; j < languageSuffixes.length; j++) {
      $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            list: 'categorymembers',
            cmtitle: (category + languageSuffixes[j]),
            cmlimit: 500
        },
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var pages = data.query.categorymembers;
            for (var i = 0; i < pages.length; i++) {
                    //purgePage(pages[i].title);
                    extractPageInfo(pages[i].title, "9c28a1344a20bf189fda7d58339e518257f2dd9b+\\");
               
            }
            if ( data && data.query && data.query.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info + 'Category' );
            } else {
                //alert( 'Error: Unknown result from API. Category' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed. Category' );
        }
    });
  }
}
function extractPageInfo(pageTitle, token) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'query',
            titles: pageTitle,
            prop: 'revisions',
            rvprop: 'content'
        },
        async: false,
        dataType: 'json',
        type: 'GET',
        success: function( data ) {
            var pages = data.query.pages;
            var revisions = pages[Object.keys(pages)[0]].revisions[0];
            var content = revisions[Object.keys(revisions)[2]]
            var title = pages[Object.keys(pages)[0]].title;
            createNewInfoboxPage(title, content, token);
            if ( data && data.query && data.query.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
            } else {
                //alert( 'Error: Unknown result from API.' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
        }
    });
}
function createNewInfoboxPage(page, contentOfMainPage, token) {
    var infoboxText = getInfoboxFromFullPageContent(contentOfMainPage);
    var infoboxPageTitle = page.replace(/\/(de|fr|nl|it|es|ru|pt\-br|cs|pl|sv|uk|zh)/g, function(piece) {return "";}).concat("/infobox");
    var oldPageRevisedText = getOldPageRevisedText(page, contentOfMainPage, infoboxPageTitle);
    removeInfoboxFromMain(page, oldPageRevisedText, token);
    if (infoboxText != null) {
      if (/\/(de|fr|nl|it|es|ru|pt\-br|cs|pl|sv|uk|zh)/g.test(page)) {
        return;
      }
      var newPageTitle = page.concat("/infobox");
      var convertedInfoboxText = convertInfobox(infoboxText, token);
      createPage(newPageTitle, convertedInfoboxText, token, page, contentOfMainPage);
    }
}
function getOldPageRevisedText(pageTitle, content, infoboxPageTitle) {
    content = content.replace(/{{\bCombat\b(\s+(\||{).+)+\s}}/gi, function (piece) {
        return "{{:" + infoboxPageTitle + "}}";
    });
    return content;
}
function removeInfoboxFromMain(pageTitle, content, token) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            text: content,
            bot: true,
            token: token,
            summary: "(BOT) - Replaced old infobox with a link to the /infobox subpage"
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
            if ( data && data.edit && data.edit.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
            } else {
                //alert( 'Error: Unknown result from API.' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
        }
    })
};
function getInfoboxFromFullPageContent(contentOfPage) {
    var matches = contentOfPage.match(/{{\bCombat\b(\s+\|.+)+\s}}/gi);
if (matches != null && matches.length > 0) {
infoboxText = matches[0];
} else {
infoboxText = null;
}
    return infoboxText;
}
function convertInfobox(text) {
    text = text.replace(/{{(\w+)/g, function (piece, $1) {
        var returnText = "{{Infobox\n| category = ";
        $1 = $1.toLowerCase();
        switch ($1) {
            case "item":
                returnText = returnText.concat("Items");
                break;
            case "machinery":
                returnText = returnText.concat("Machinery");
                break;
            case "combat":
                returnText = returnText.concat("Combat");
                break;
            case "technology":
                returnText = returnText.concat("Technology");
        }
        switch ($1) {
            case "machinery":
                returnText = returnText.concat("\n| category-name = Machine");
                break;
            case "item":
                returnText = returnText.concat("\n| category-name = Item");
                break;
        }
        return returnText;
    });
    text = text.replace("stack_size", "stack-size");
    text = text.replace("poweroutput", "power-output");
    text = text.replace("input", "recipe");
    text = text.replace("raw", "total-raw");
    text = text.replace("technologies", "required-technologies");
    text = text.replace("costmultiplier", "cost-multiplier");
    text = text.replace("requirements", "required-technologies");
    text = text.replace("walkingspeed", "walking-speed");
    text = text.replace("storagesize", "storage-size");
    text = text.replace("gridsize", "grid-size");
    text = text.replace("shootingspeed", "shooting-speed");
    text = text.replace("damagebonus", "damage-bonus");
    text = text.replace("clustersize", "cluster-size");
    text = text.replace("aoesize", "area-of-effect-size");
    text = text.replace("magazinesize", "magazine-size");
    text = text.replace("recharge", "robot-recharge-rate");
    text = text.replace("rechargebuffer", "internal-buffer-recharge-rate");
    text = text.replace("wirereach", "wire-reach");
    text = text.replace("craftingspeed", "crafting-speed");
    text = text.replace("smeltingspeed", "smelting-speed");
    text = text.replace("miningpower", "mining-power");
    text = text.replace("miningspeed", "mining-speed");
    text = text.replace("miningarea", "mining-area");
    text = text.replace("supplyarea", "supply-area");
    text = text.replace("constructionarea", "construction-area");
    text = text.replace("lifetime", "lifespan");
    text = text.replace("inventorysizebonus", "inventory-size-bonus");
    text = text.replace("gridsize", "grid-size");
    text = text.replace("boosttechs", "boosting-technologies");
    text = text.replace("allowstech", "allows");
    text = text.replace("storage", "storage-size");
    text = text.replace(/\|\s*\brecipe\b\s*=\s*(.+)\n\|\s*\boutput\b\s*=\s*(.+)/g, function (piece, $1, $2) {
        return "| recipe = " + $1 + " = " + $2;
    });
    text = text.concat("<noinclude>[[Category:Infobox page]]</noinclude>");
    return text;
}
function createPage(pageTitle, content, token, page, contentOfMainPage) {
    $.ajax({
        url: 'https://wiki.factorio.com/api.php',
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            text: content,
            bot: true,
            createonly: true,
            token: token,
            summary: "(BOT) - Created infobox sub page for " + page
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
         
            if ( data && data.edit && data.edit.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                //alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
            } else {
                //alert( 'Error: Unknown result from API.' );
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
        }
    });
}*/
/* END OF OLD INFOBOX CONVERSION TOOL */

Latest revision as of 07:44, 21 October 2024

/* Any JavaScript here will be loaded for all users on every page load. */

var apiUrl = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + "/api.php"

/* Script in here will be executed when the page is "ready" */
$(document).ready(function() {
	getNumberOfActiveUsers();
	var elem = document.getElementById("evoChecker");
	if(elem != null) {
		elem.innerHTML =
		'Alternatively, enter an evolution factor below to see the chances.<br>' +
		'<input style="margin-bottom:10px" type="number" id="evoInput" min=0 max=1 step=0.01 placeholder="Evolution" onchange="calcEvo()"></input><br>' +
		'<table style="float:left;margin-right:10px" class="wikitable" id="evoOutputBiter"></table>' +
		'<table class="wikitable" id="evoOutputSpitter"></table>';
		calcEvo();
	}
});

/* show correct number of active users on the main page */

function getNumberOfActiveUsers() {
	if (document.getElementById("active-users")) {
		$.ajax({
			url: apiUrl,
			data: {
				format: 'json',
				action: 'query',
				list: 'allusers',
				aulimit: 500,
				auactiveusers: true
			},
			dataType: 'json',
			type: 'GET',
			success: function(data) {
				document.getElementById("active-users").innerHTML = data.query.allusers.length.toString();
			},
			error: function(xhr) {
				console.log( 'Error: Request failed.' );
			}
		});
	}
};

/* Collapsible list on [[Prototype definitions]] */

$(".prototype-tree li").each(function (index, element) {
  if ( $( element ).children("ul").length > 0 ) {
    $( element ).addClass("prototype-tree-parent");
  };
});

$(".prototype-tree li.prototype-tree-parent").on("click", function(event) {
 // only collapse if I clicked a li or the direct child of a li that is not another list or a link
  if ( $( event.currentTarget ).children("ul").length > 0 && $( event.target ).get(0).tagName != "UL" && $( event.target ).get(0).tagName != "A" && ($( event.target ).hasClass("prototype-tree-parent") || $( event.target ).parent().hasClass("prototype-tree-parent")) ) {
    $( event.currentTarget ).children("ul")[0].classList.toggle("hidden");
    $( event.currentTarget ).toggleClass("prototype-tree-parent-collapsed");
    return false; // prevents further event bubbling
  }
});

/* Evolution calc */

//values are in the form [evolution, weight]
const biterSpawner = [
	["Small Biter",    [[0.0, 0.3], [0.6, 0.0]]],
	["Medium Biter",   [[0.2, 0.0], [0.6, 0.3], [0.7, 0.1]]],
	["Big Biter",      [[0.5, 0.0], [1.0, 0.4]]],
	["Behemoth Biter", [[0.9, 0.0], [1.0, 0.3]]]
];
const spitterSpawner = [
	["Small Biter",      [[0.0, 0.3], [0.35, 0.0]]],
	["Small Spitter",    [[0.25, 0.0], [0.5, 0.3], [0.7, 0.0]]],
	["Medium Spitter",   [[0.4, 0.0], [0.7, 0.3], [0.9, 0.1]]],
	["Big Spitter",      [[0.5, 0.0], [1.0, 0.4]]],
	["Behemoth Spitter", [[0.9, 0.0], [1.0, 0.3]]]
];

//calculates the interpolated value
function lerp(low, high, pos) {
	const s = high[0] - low[0];
	const l = (pos - low[0]) / s;
	return (low[1] * (1-l)) + (high[1] * l);
};

//gets the weight list
function getValues(map, evo) {
	var result = {};
	var sum = 0;
	map.forEach(function(data) {
		const list = data[1];
		var low = list[0];
		var high = list[list.length-1];
		list.forEach(function(val) {
			if(val[0] <= evo && val[0] >  low[0])  low = val;
			if(val[0] >= evo && val[0] < high[0]) high = val;
		});
		var val = null;
		if(evo <= low[0]) val = low[1];
		else if(evo >= high[0]) val = high[1];
		else val = lerp(low, high, evo);
		sum += val;
		result[data[0]] = val;
	});
	Object.keys(result).forEach(function(data, index) {
		result[data] = result[data] / sum;
	});
	return result;
};

function calcEvo() {
	const evo = document.getElementById("evoInput").value;
	genTable(getValues(biterSpawner, evo), document.getElementById("evoOutputBiter"), "Biter's Nest");
	genTable(getValues(spitterSpawner, evo), document.getElementById("evoOutputSpitter"), "Spitter's Nest");
};

function percentile(value) {
	return (value*100).toFixed(2) + "%";
};

function genTable(data, tableElem, title) {
	var html = '<tr><th>'+title+'</th><th>Chance</th>';
	Object.keys(data).forEach(function(value) {
		html += '<tr><td>'+value+'</td><td>'+percentile(data[value])+'</td>';
	});
	tableElem.innerHTML = html;
};

/* Template:Inventory tooltips */

var lastTouchTime = 0;
document.addEventListener('touchstart', updateLastTouchTime, true);
function updateLastTouchTime() {
  lastTouchTime = new Date();
}

$(".tab-head").mousemove(function(e) {
  if (e.buttons > 0) return;
  if (new Date() - lastTouchTime < 500) return;
  var countCssRules = document.styleSheets[0].cssRules.length;
  var newRule = '.tab-head:hover:after{display: block; left: ' + (e.offsetX + 20) + 'px; top: ' + (e.offsetY + 20) + 'px;}';
  document.styleSheets[0].insertRule(newRule, countCssRules);
});

$(".tab .factorio-icon").mousemove(function(e) {
  if (e.buttons > 0) return;
  if (new Date() - lastTouchTime < 500) return;
  var countCssRules = document.styleSheets[0].cssRules.length;
  $(e.currentTarget).children("a").attr("title", "");
  var text = $(e.currentTarget).children("a").children("img").attr("alt");
  var newRule = '.tab .factorio-icon:hover:after{display: block; ' + "content: '" + text + "'}";
  document.styleSheets[0].insertRule(newRule, countCssRules);
});

/* Template:BlueprintString */

$(".bps-box").click(function(event) {
	var copyTarget = document.createElement("input");
	copyTarget.setAttribute("value", $( event.target ).children("p").html());
	document.body.appendChild(copyTarget);
	copyTarget.select();
	document.execCommand("copy");
	document.body.removeChild(copyTarget);
});

/* Template:Inventory */

$(".tab-head-1").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-1").show();
});

$(".tab-head-2").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-2").show();
});

$(".tab-head-3").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-3").show();
});

$(".tab-head-4").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-4").show();
});

$(".tab-head-5").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-5").show();
});

$(".tab-head-6").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-6").show();
});

$(".tab-head-7").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-7").show();
});

$(".tab-head-8").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-8").show();
});

$(".tab-head-9").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-9").show();
});

$(".tab-head-10").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-10").show();
});

$(".tab-head-11").click(function() {
	$(".tab-head").removeClass("tab-head-active");
	$(this).addClass("tab-head-active");
	$(".tab").hide();
	$(".tab-11").show();
});

//*** Language template ***//
if($(".languages-flags .flag").length == 0) {
	console.log("Not showing languages bar because there's no other language's version of this page.");
	$(".languages-container").hide();
}

//Spoiler template
$(".spoiler-container .button").click(function() {
	$(this).siblings(".text").toggle("slow");
});

//* General/generic functions *//

/* User is bot if userGroup.some(isBot) == true */

var userGroup = "";

function getUserGroup() {
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'query',
			meta: 'userinfo',
			uiprop: 'groups',
		},
		async: false,
		dataType: 'json',
		type: 'GET',
		success: function(data) {
			userGroup = data.query.userinfo.groups
		},
	});
};

function isBot(group) {
	return group == "bot";
}

/* Get token of this session */

var globalToken;

function getToken() {
    $.ajax({
        url: apiUrl,
        data: {
            format: 'json',
            action: 'query',
            meta: 'tokens',
            bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
           globalToken = data.query.tokens.csrftoken;
        },
        error: function( xhr ) {
            console.log("Failed to get token.");
        }
    });
}


function genericEditPage(title, content, summary) {
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'edit',
			title: title,
			text: content,
			token: globalToken,
			summary: summary,
			bot: true,
			nocreate: true
		},
		dataType: 'json',
		type: 'POST',
		success: function( data ) {
			console.log("Edited " + title);
		},
		error: function( xhr ) {
			alert("Failed to edit " + title);
		}
	});
};


function createPage(pageTitle, content, summary) {
    $.ajax({
        url: apiUrl,
        data: {
			format: 'json',
			action: 'edit',
			title: pageTitle,
			text: content,
			token: globalToken,
			summary: summary,
			bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
			console.log("Created page: " + pageTitle);
        },
        error: function( xhr ) {
			console.log("Failed to create page");
        }
    });
}

function getBacklinks(page) {
	var backlinks = [];
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'query',
			list: 'backlinks',
			bltitle: page,
			bllimit: 1000,
		},
		async: false,
		type: 'GET',
		success: function( data ) {
			backlinks = data.query.backlinks;
		},
		error: function( xhr ) {
			alert( 'Error: Backlinks request failed.' );
		}
	});
	return backlinks;
};

function getFileUsage(file) {
	var imageusage = [];
	$.ajax({
		url: apiUrl,
		data: {
			format: 'json',
			action: 'query',
			list: 'imageusage',
			iutitle: file,
			iulimit: 1000
		},
		async: false,
		type: 'GET',
		success: function( data ) {
			imageusage = data.query.imageusage;
		},
		error: function( xhr ) {
			alert( 'Error: Imageusage request failed.' );
		}
	});
	return imageusage;
};

function performNullEdit(pageTitle, summary) {
    $.ajax({
        url: apiUrl,
        data: {
            format: 'json',
            action: 'edit',
            title: pageTitle,
            section: 0,
            text: "",
            token: globalToken,
            summary: summary,
            bot: true
        },
        async: false,
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
           console.log("Performed null edit");
        },
        error: function( xhr ) {
            console.log("Failed to perform null edit");
        }
    });
}

function purgeWhatLinksHere(pageTitle) {
    $.ajax({
        url: apiUrl,
        data: {
            format: "json",
            action: 'query',
            list: "backlinks",
            bltitle: pageTitle,
            bllimit: 500
        },
        async: true,
        type: 'GET',
        success: function( data ) {
            console.log(data);
            for (var i = 0; i < data.query.backlinks.length; i++) {
                purgePage(data.query.backlinks[i].title);
            }
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
            console.log("Failed purging");
        }
    });
}

function purgePage(pageTitle) {
    $.ajax({
        url: apiUrl,
        data: {
            action: 'purge',
            forcelinkupdate: true,
            titles: pageTitle,
            prop: "info"
        },
        async: true,
        type: 'GET',
        success: function( data ) {
            console.log("purging " + pageTitle);
        },
        error: function( xhr ) {
            //alert( 'Error: Request failed.' );
            console.log("Failed purging");
        }
    });
}