// src/main.ts async function fetchData() { const [recipesResponse, exchangesResponse] = await Promise.all([ fetch("https://api.prunplanner.org/data/recipes"), fetch("https://api.prunplanner.org/data/exchanges") ]); const [recipes, prices] = await Promise.all([ recipesResponse.json(), exchangesResponse.json() ]); return { recipes, prices }; } function render({ recipes, prices }) { const priceMap = new Map; for (const price of prices) if (price.ExchangeCode == "PP7D_IC1") priceMap.set(price.MaterialTicker, price); const profits = []; for (const recipe of recipes) { const runsPerDay = 1000 * 60 * 60 * 24 / recipe.TimeMs; if (recipe.Outputs.length !== 1) { console.warn(`${recipe.RecipeName} doesn't have 1 output`); continue; } const output = recipe.Outputs[0]; const outputPrice = priceMap.get(output.Ticker); if (outputPrice === undefined) throw new Error(`missing price for ${output.Ticker}`); const revenuePerRun = output.Amount * outputPrice.PriceAverage; const costPerRun = recipe.Inputs.reduce((sum, input) => { const price = priceMap.get(input.Ticker); if (price === undefined) throw new Error(`missing price for ${input.Ticker}`); return sum + price.PriceAverage * input.Amount; }, 0); const dailyProfit = (revenuePerRun - costPerRun) * runsPerDay; profits.push({ recipeName: recipe.RecipeName, dailyProfit, traded: outputPrice.Traded }); } profits.sort((a, b) => b.dailyProfit - a.dailyProfit); const fmt = new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }); const tbody = document.querySelector("tbody"); tbody.innerHTML = ""; for (const profit of profits) { const row = document.createElement("tr"); row.innerHTML = `