MediaWiki:Common.js
Jump to navigation
Jump to search
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. */
/* Script in here will be executed when the page is "ready" */
$(document).ready(getNumberOfActiveUsers);
/* show correct number of active users on the main page */
function getNumberOfActiveUsers() {
if (document.getElementById("active-users")) {
$.ajax({
url: 'https://wiki.factorio.com/api.php',
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.' );
}
});
}
};
/* User is bot if userGroup.some(isBot) == true */
var userGroup = "";
function getUserGroup() {
$.ajax({
url: 'https://wiki.factorio.com/api.php',
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";
}
var globalToken;
function getToken() {
$.ajax({
url: 'https://wiki.factorio.com/api.php',
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.");
}
});
}
/* Infobox more info in header */
$(".more-button").click(function() {
$(".more-content").toggle("fast");
});
/* 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();
});
//*** 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
$(".spoiler-container .button").click(function() {
$(this).siblings(".text").toggle("slow");
});
var wantedPagesListsLocation = "Factorio:Wanted pages";
var enPageLength = {};
var stubs = {};
function getStubs() {
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: 'json',
action: 'query',
list: 'categorymembers',
cmtitle: 'Category:Stubs',
cmlimit: 400,
cmprop: 'title'
},
async: false,
dataType: 'json',
type: 'GET',
success: function( data ) {
var categorymembers = data.query.categorymembers;
console.log('Found ' + categorymembers.length + ' stubs.');
for (var i = 0; i < categorymembers.length; i++) {
stubs[categorymembers[i].title] = true;
}
},
error: function( xhr ) {
alert( 'Error: Request failed.' );
}
});
};
$("#create-wanted-pages-list").click(function(){
getToken();
createWantedPagesLists();
});
function createWantedPagesLists() {
getUserGroup();
if (userGroup.some(isBot) == false) return;
enPageLength = {};
var wantedPages = getWantedPages();
wantedPages = wantedPages.sort(compare);
splitWantedPagesIntoDifferentLanguages(wantedPages);
};
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 koreanWantedPages = [];
var wantedFiles = [];
var wantedFileTalk = [];
var wantedTemplates = [];
var otherWantedPages = [];
for (var i = 0; i < wantedPages.length; i++) {
switch (wantedPages[i].title.slice(-3)) {//"/cs", "/de", "/es", "/fr", "/it", "/ja", "/nl", "/pl", "/-br", "/ru", "/sv", "/uk", "/zh", "/tr", "/kr"
case "/cs": czechWantedPages.push(wantedPages[i]); break;
case "/de": germanWantedPages.push(wantedPages[i]); break;
case "/es": spanishWantedPages.push(wantedPages[i]); break;
case "/fr": frenchWantedPages.push(wantedPages[i]); break;
case "/it": italianWantedPages.push(wantedPages[i]); break;
case "/ja": japaneseWantedPages.push(wantedPages[i]); break;
case "/nl": dutchWantedPages.push(wantedPages[i]); break;
case "/pl": polishWantedPages.push(wantedPages[i]); break;
case "-br": portugueseWantedPages.push(wantedPages[i]); break;
case "/ru": russianWantedPages.push(wantedPages[i]); break;
case "/sv": swedishWantedPages.push(wantedPages[i]); break;
case "/uk": ukrainianWantedPages.push(wantedPages[i]); break;
case "/zh": chineseWantedPages.push(wantedPages[i]); break;
case "/tr": turkishWantedPages.push(wantedPages[i]); break;
case "/kr": koreanWantedPages.push(wantedPages[i]); break;
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 if (wantedPages[i].title.slice(0, 10) == "File talk:") {wantedFileTalk.push(wantedPages[i])} else {otherWantedPages.push(wantedPages[i])}; break;
}
}
getStubs();
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("kr", koreanWantedPages, "Korean");
createWantedPagesPage("file", wantedFiles, "Files");
createWantedPagesPage("file_talk", wantedFileTalk, "File talk");
createWantedPagesPage("template", wantedTemplates, "Templates");
createWantedPagesPage("other", otherWantedPages, "Other");
}
function createWantedPagesPage(location, wantedPages, language) {
var languageSuffixes = ["cs", "de", "es", "fr", "it", "ja", "nl", "pl", "pt-br", "ru", "sv", "uk", "zh", "tr", "kr"]
if (languageSuffixes.indexOf(location) > -1) {
var formattedWantedPages = "Number of wanted pages in " + language + ": " + wantedPages.length + "\n{|class=wikitable\n!#\n!Page\n!Links to this page\n!Length of the corresponding English page in bytes";
for (var i = 0; i < wantedPages.length; i++) {
//I don't dare to make this into a function because I don't want this to be async so lets put a whole api request in here lul
var enPageTitle = wantedPages[i].title.slice(0, - location.length - 1)
var length = 0;
if (enPageLength[enPageTitle]) {
length = enPageLength[enPageTitle]
} else {
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: 'json',
action: 'query',
titles: enPageTitle,
prop: 'info',
},
async: false,
dataType: 'json',
type: 'POST',
success: function( data ) {
var pages = data.query.pages;
var pageInfo = pages[Object.keys(pages)[0]];
length = pageInfo['length'];
if (!length) length = '---';
var redirect = pageInfo['redirect'];
if (redirect == "") {
length = length + " (Redirect)";
} else if (stubs[enPageTitle]) {
length = length + " (Stub)";
}
enPageLength[enPageTitle] = length
},
error: function( xhr ) {
alert("Failed to get page length: " + pageTitle);
}
});
}
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 + "]\n|[https://wiki.factorio.com/index.php?title=" + encodeURI(enPageTitle) + " " + length + "]");
}
} else {
var formattedWantedPages = "Number of wanted pages in " + language + ": " + wantedPages.length + "\n{|class=wikitable\n!#\n!Page\n!Links to this page";
for (var i = 0; i < wantedPages.length; i++) {
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 + "]");
}
}
formattedWantedPages = formattedWantedPages.concat("\n|}");
createPage(wantedPagesListsLocation + "/" + location, formattedWantedPages, "Updated the list of wanted pages for " + language + ".");
}
function performNullEdit(pageTitle, summary) {
$.ajax({
url: 'https://wiki.factorio.com/api.php',
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: 'https://wiki.factorio.com/api.php',
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: 'https://wiki.factorio.com/api.php',
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");
}
});
}
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: " + pageTitle);
},
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;
}
$("#create-redirect-list").click(function(){
getToken();
createRedirectList();
});
function createRedirectList() {
getUserGroup();
if (userGroup.some(isBot) == false) return;
getRedirects();
};
function getRedirects() {
var redirects = [];
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: 'json',
action: 'query',
list: 'allpages',
aplimit: '5000',
apfilterredir: 'redirects',
},
async: false,
dataType: 'json',
type: 'GET',
success: function( data ) {
redirects = data.query.allpages;
},
error: function( xhr ) {
alert( 'Error: Allpages request failed.' );
}
});
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: 'json',
action: 'query',
list: 'allpages',
aplimit: '5000',
apfilterredir: 'redirects',
apnamespace: '6'
},
async: false,
dataType: 'json',
type: 'GET',
success: function( data ) {
for (var i = 0; i < data.query.allpages.length; i++) {
redirects.push(data.query.allpages[i])
}
},
error: function( xhr ) {
alert( 'Error: Allpages request failed.' );
}
});
for (var i = 0; i < redirects.length; i++) {
$.ajax({
url: 'https://wiki.factorio.com/api.php',
data: {
format: "json",
action: 'query',
list: "backlinks",
bltitle: redirects[i].title,
bllimit: 500
},
async: false,
type: 'GET',
success: function( data ) {
redirects[i].value = data.query.backlinks.length;
},
error: function( xhr ) {
alert( 'Error: Backlinks request failed.' );
}
});
}
redirects = redirects.sort(compare);
createRedirectsPage("Factorio:Redirects", redirects);
};
function createRedirectsPage(location, redirects) {
var formattedRedirects = "{|class=wikitable\n!#\n!Redirect\n!Links to this redirect";
for (var i = 0; i < redirects.length; i++) {
formattedRedirects = formattedRedirects.concat("\n|-\n|" + (i + 1) + "\n|[https://wiki.factorio.com/index.php?title=" + encodeURI(redirects[i].title)&redirect=no " + redirects[i].title + "]\n|[https://wiki.factorio.com/index.php?title=Special:WhatLinksHere/" + encodeURI(redirects[i].title) + " " + redirects[i].value + "]");
}
formattedRedirects = formattedRedirects.concat("\n|}");
createPage(location, formattedRedirects, "Updated the list of redirects.");
}
/* 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 */