// ts/cache.ts
var fetchCache = new Map;
async function cachedFetchJSON(url, options) {
if (fetchCache.has(url))
return fetchCache.get(url);
const response = await fetch(url, options).then((r) => r.json());
fetchCache.set(url, response);
return response;
}
// ts/popover.ts
function setupPopover() {
const main = document.querySelector("main");
const popover = document.querySelector("#popover");
main.addEventListener("mouseover", (event) => {
const target = event.target;
if (target.dataset.tooltip) {
popover.textContent = target.dataset.tooltip;
const rect = target.getBoundingClientRect();
popover.style.left = `${rect.left}px`;
popover.style.top = `${rect.bottom}px`;
popover.showPopover();
}
});
main.addEventListener("mouseout", (event) => {
const target = event.target;
if (target.dataset.tooltip)
popover.hidePopover();
});
}
// ts/buy.ts
var warehouseNames = {
AI1: "ANT",
CI1: "BEN",
IC1: "HRT",
NC1: "MOR"
};
var username = document.querySelector("#username");
var apiKey = document.querySelector("#api-key");
{
const storedUsername = localStorage.getItem("fio-username");
if (storedUsername)
username.value = storedUsername;
const storedApiKey = localStorage.getItem("fio-api-key");
if (storedApiKey)
apiKey.value = storedApiKey;
}
document.querySelector("#fetch").addEventListener("click", async () => {
const supplyForDays = parseInt(document.querySelector("#days").value, 10);
const loader = document.querySelector("#loader");
loader.innerHTML = "";
loader.style.display = "block";
try {
await calculate(username.value, apiKey.value, supplyForDays);
localStorage.setItem("fio-username", username.value);
localStorage.setItem("fio-api-key", apiKey.value);
} catch (e) {
console.error(e);
}
loader.style.display = "none";
});
document.querySelector("#buys").addEventListener("click", (event) => {
if (!event.target)
return;
const target = event.target;
if (target.tagName !== "INPUT" || target.type !== "button")
return;
const xitSection = target.parentElement;
if (!xitSection || !xitSection.classList.contains("xit-act"))
return;
navigator.clipboard.writeText(xitSection.querySelector("textarea").value);
});
setupPopover();
async function calculate(username2, apiKey2, supplyForDays) {
const buys = document.querySelector("#buys");
buys.innerHTML = "";
const closest = await cachedFetchJSON("/closest.json");
const planetsByCX = new Map;
for (const planet of await getPlanets(username2, apiKey2)) {
const wh = closest[planet.id];
const existing = planetsByCX.get(wh);
if (existing)
existing.push(planet);
else
planetsByCX.set(wh, [planet]);
}
for (const [cx, planets] of planetsByCX)
buys.append(...await calcForCX(username2, apiKey2, supplyForDays, planets, cx));
}
async function calcForCX(username2, apiKey2, supplyForDays, planets, cx) {
const prices = await getPrices(cx);
const avail = await warehouseInventory(username2, apiKey2, warehouseNames[cx]);
const { bids, orders } = await getBids(username2, apiKey2, cx);
const totalConsumption = new Map;
for (const planet of planets) {
for (const [ticker, consumption] of planet.netConsumption)
totalConsumption.set(ticker, (totalConsumption.get(ticker) ?? 0) + consumption);
for (const mat of planet.exporting) {
const planetExport = planet.inventory.get(mat);
if (planetExport)
avail.set(mat, (avail.get(mat) ?? 0) + planetExport);
}
}
const buy = new Map;
for (const [mat, amount] of totalConsumption)
if (amount > 0)
buy.set(mat, (buy.get(mat) ?? 0) + amount * supplyForDays);
const materials = [];
for (const [mat, amount] of buy) {
const remaining = Math.max(amount - (bids.get(mat) ?? 0) - (avail.get(mat) ?? 0), 0);
const price = prices.get(mat);
if (!price || price.Bid === null || price.Ask === null) {
console.log(mat, "has no bid/ask");
continue;
}
const spread = price.Ask - price.Bid;
materials.push({
ticker: mat,
amount,
bids: bids.get(mat) ?? 0,
have: avail.get(mat) ?? 0,
spread,
savings: spread * remaining
});
}
materials.sort((a, b) => b.savings - a.savings);
const h2 = document.createElement("h2");
h2.textContent = `${cx}/${warehouseNames[cx]}`;
const span = document.createElement("span");
span.textContent = planets.map((p) => p.name).join(", ");
const table = document.createElement("table");
table.innerHTML = `
mat
want
bids
have
buy
spread
savings