/** * Generate app/lib/fifa-2026-third-place-allocation.ts from the published FIFA * 2026 World Cup Annex C third-place allocation table. * * Source: Wikipedia "Template:2026 FIFA World Cup third-place table". * Run with: node scripts/gen-fifa-third-place.mjs */ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; const SOURCE_URL = "https://en.wikipedia.org/w/index.php?title=Template:2026_FIFA_World_Cup_third-place_table&action=raw"; const text = await (await fetch(SOURCE_URL)).text(); // Split into row blocks at each `! scope="row" | N`. const parts = text.split(/!\s*scope="row"\s*\|/).slice(1); if (parts.length !== 495) throw new Error(`expected 495 rows, got ${parts.length}`); const out = {}; for (const part of parts) { // Cut the block at the next row separator / table end. const block = part.split(/\n\|\}|\n\|-/)[0]; const tokens = block.replace(/'''/g, "").split(/\|\||\||\n/).map((t) => t.trim()); const qualifying = tokens.filter((t) => /^[A-L]$/.test(t)); const assignments = tokens.filter((t) => /^3[A-L]$/.test(t)).map((t) => t[1]); if (qualifying.length !== 8) throw new Error(`row qualifying != 8: ${qualifying}`); if (assignments.length !== 8) throw new Error(`row assignments != 8: ${assignments}`); const set = new Set(assignments); if (set.size !== 8) throw new Error(`duplicate thirds: ${assignments}`); for (const g of assignments) { if (!qualifying.includes(g)) throw new Error(`third ${g} not qualifying`); } const key = [...qualifying].sort().join(""); if (out[key]) throw new Error(`duplicate key ${key}`); out[key] = assignments.join(""); // thirds in winner-column order [A,B,D,E,G,I,K,L] } const keys = Object.keys(out).sort(); if (keys.length !== 495) throw new Error(`expected 495 keys, got ${keys.length}`); const lines = keys.map((k) => ` ${k}: "${out[k]}",`).join("\n"); const ts = `// AUTO-GENERATED from FIFA 2026 World Cup Annex C third-place allocation. // Source: Wikipedia "Template:2026 FIFA World Cup third-place table". // Do not edit by hand — regenerate with scripts/gen-fifa-third-place.mjs. // // Key: the eight qualifying third-place group letters, sorted (e.g. "EFGHIJKL"). // Value: the qualifying third-place group facing each group winner, in the // column order [1A, 1B, 1D, 1E, 1G, 1I, 1K, 1L]. export const THIRD_PLACE_WINNER_COLUMNS = ["A", "B", "D", "E", "G", "I", "K", "L"] as const; export const ANNEX_C_THIRD_PLACE_ALLOCATION: Record = { ${lines} }; `; const target = path.join( path.dirname(fileURLToPath(import.meta.url)), "..", "app", "lib", "fifa-2026-third-place-allocation.ts" ); fs.writeFileSync(target, ts); console.log(`Wrote ${keys.length} rows to ${target}`);