// <nowiki>
window.meets ??= {};
window.redirs ??= {};
(async () => {
const getRedir = async pg => {
redirs[pg] ??= new DOMParser().parseFromString(await (await fetch(`/wiki/${pg}`)).text(), 'text/html').querySelector('title').innerText.slice(0, -12);
return redirs[pg];
}
const addPipe = name => `${name}${name.includes('(') ? '|' : ''}`;
const bullet = (yr) => winners[yr] ? `* [[${yr} USA Indoor Track and Field Championships|${yr}]]: ${winners[yr].map(w => w.ctry ? `{{fla|[[${addPipe(w.name)}]]|${w.ctry}}}` : `[[${addPipe(w.name)}]]${w.pl > 1 ? ` (${ord(w.pl)})` : ''}`).join(', ') ?? ''}` : '';
const range = (start, end) => [...Array(end - start + 1)].map((_, i) => i + start);
const getRed = href => new URLSearchParams(href.split('?').at(-1)).get('title').replaceAll('_', ' ');
const ord = n => n + ['st', 'nd', 'rd'][(((n < 0 ? -n : n) + 90) % 100 - 10) % 10 - 1] || 'th';
const removeRowspans = table => {
const rows = Array.from(table.rows);
for (let i = 0; i < rows.length; i++) {
const cells = Array.from(rows[i].cells);
for (let cell of cells) {
const rowspan = cell.getAttribute('rowspan');
if (rowspan && rowspan > 1) {
const rowSpanValue = parseInt(rowspan);
cell.removeAttribute('rowspan');
for (let j = 1; j < rowSpanValue; j++) {
const targetRow = rows[i + j];
if (targetRow) {
const newCell = cell.cloneNode(true);
targetRow.insertBefore(newCell, targetRow.cells[cell.cellIndex]);
}
}
}
}
}
}
const GEN = 'Men';
const START = 1906;
const END = new Date().getFullYear();
const matchEvts = {
'60m': ['60 metres', '40-yard dash', '40 yards', '50 m', '50 metres', '55 m', '55 metres', '50 yards', '50-yard dash', '60 yards', '60-yard dash'],
'75y': ['75 yards', '75-yard dash'],
'150y': ['150 yards'],
'200m': ['200 metres', '220 yards', '220-yard dash', '200 yards', '240 yards'],
'400m': ['400 metres', '440 yards', '440-yard dash', '300 metres', '300 m', '300 yards', '300-yard dash'],
'600m': ['600 metres', '600 m', '500 metres', '500 m', '600 yards', '600-yard run', 'Middle-distance running'],
'800m': ['800 metres', '880-yard dash', '880 yards', '880-yard run', '800 m', '1000 m', '1000 metres', '1000 yards', '1000-yard run'],
'Mile': ['Mile run', 'Mile', '1500 m', '1500 metres'],
'3000m': ['3000 metres', 'Two miles', '2 miles', '3 miles', '5000 metres', '5000 m'],
'5M': ['5 miles', 'Five miles', '5-mile run', 'Five-mile run'],
'60mH': ['60 metres hurdles', '60 yards hurdles', '60-yard hurdles', '55 metres hurdles', '50 metres hurdles', '50 yards hurdles', '50-yard hurdles', '80 metres hurdles', '70 yards hurdles', '70-yard hurdles'],
'220yH': ['220 yards hurdles', 'Low hurdles'],
'440yH': ['440 yards hurdles', '300 yards hurdles', '400 metres hurdles'],
'3000mSC': ['3000 metres steeplechase', '3000 m steeplechase', '2 miles steeplechase', 'Steeplechase (athletics)'],
HJ: ['High jump'],
SHJ: ['Standing high jump'],
LJ: ['Long jump', 'Standing long jump'],
SP: ['Shot put'],
DT: ['Discus throw'],
TJ: ['Triple jump'],
STJ: ['Standing triple jump'],
PV: ['Pole vault'],
PVD: ['Pole vault for distance', 'Fierljeppen'],
WT: ['Weight throw', 'Weight throw for height'],
'MileW': ['Mile walk', '1500 m walk', '1500 metres walk', '1500 metres race walk', '1500 metres racewalk', '1500 m race walk', '1500 m racewalk'],
'3000mW': ['3000 metres race walk', '2 miles race walk', '2 miles walk'],
'5000mW': ['5000 metres race walk', '3 miles race walk', '3 miles walk'],
PEN: ['Women\'s Pentathlon'],
HEP: ['Heptathlon'],
}['HEP'];
const trackOrField = 'field';
const winners = {};
for (const y of range(START, END)) {
meets[y] ??= await (await fetch(`/wiki/${y}_USA_Indoor_Track_and_Field_Championships`)).text();
const doc = new DOMParser().parseFromString(meets[y], 'text/html');
const tables = [GEN, `${GEN}\\'s_${trackOrField}`].map(id => doc.querySelector(`#${id}`)?.parentElement.nextSibling.nextSibling).filter(x => x?.tagName === 'TABLE');
for (const table of tables) removeRowspans(table);
const trs = tables.flatMap(table => [...table?.querySelectorAll('tr') ?? []]);
const evtRows = [];
for (const tr of trs) {
const tds = tr.querySelectorAll('td');
const rowEvtA = tds[0]?.querySelector('a');
const rowEvt = rowEvtA?.href.split('/').at(-1).split('#')[0];
if (!rowEvt) continue;
const evt = rowEvtA.classList.contains('new') ? getRed(rowEvt) : await getRedir(rowEvt);
if (matchEvts.includes(evt)) evtRows.push(tds);
}
for (const tds of evtRows) {
const getWinner = async (idx) => {
const winnerA = tds[idx].querySelector('a');
const winnerHref = winnerA?.href.split('/').at(-1);
if (!winnerHref) return;
const name = winnerA.classList.contains('new') ? getRed(winnerHref) : await getRedir(winnerHref);
const ctry = tds[idx].querySelector('.flagicon') ? tds[idx].querySelector('abbr').innerText : undefined;
return { name, ctry, pl: (idx + 1) / 2 };
}
winners[y] ??= [];
for (let i = 1; i <= 5; i += 2) {
const winner = await getWinner(i);
if (!winner) continue;
if (!winners[y].find(w => w.name === winner.name && w.pl === winner.pl))
winners[y].push(winner);
//if (!winner.ctry) break;
}
}
if (!winners[y]) continue;
winners[y].sort((a, b) => a.pl - b.pl);
for (const winner of winners[y]) {
const idx = winners[y].findIndex(w => w.name === winner.name);
const getNextIdx = () => winners[y].slice(idx + 1).findIndex(w => w.name === winner.name);
while (getNextIdx() !== -1) winners[y].splice(getNextIdx(), 1);
}
const topNativeFinish = [...Array(3)].map((_, i) => i + 1).find(num => winners[y].find(ath => ath.pl === num && !ath.ctry));
if (!topNativeFinish) console.log('no native finish', y);
winners[y] = winners[y].filter(ath => {
if (ath.pl > topNativeFinish) return false;
if (ath.pl > 1 && ath.ctry) return false;
return true;
});
}
const abbrEvt = matchEvts[0].replace('metres', 'm').toLowerCase();
const out = `
{{Navbox
| name = USA Indoor Track and Field Championships winners in ${GEN.toLowerCase()}'s ${abbrEvt}
| title = [[USA Indoor Track and Field Championships]] winners in ${GEN.toLowerCase()}'s [[${abbrEvt}]]
| state = {{{state<includeonly>|collapsed</includeonly>}}}
| listclass = hlist
| nowrapitems = yes
| titlestyle = background: #F0DC82
| groupstyle = text-align: center; background: #F0DC82
| group1 = ${START}–1979<br />{{small|[[Amateur Athletic Union]]}}
| list1 =
${range(START, 1979).map(bullet).filter(x => x).join('\n')}
| group2 = 1980–1992<br />{{small|[[The Athletics Congress]]}}
| list2 =
${range(1980, 1992).map(bullet).filter(x => x).join('\n')}
| group3 = 1993–present<br />{{small|[[USA Track & Field]]}}
| list3 =
${range(1993, END).map(bullet).filter(x => x).join('\n')}
|group4 = Notes
|list4 =
{{allow wrap|* Distances have varied as follows: 440 yards (1959–1986), 400 meters (1987–date) alternating with 300 meters in odd numbered years starting 2015}}
}}<noinclude>
{{collapsible option}}
[[Category:United States indoor track and field champions navigational boxes|${abbrEvt[0].toUpperCase() + abbrEvt.slice(1)}, ${GEN.toLowerCase()}]]
</noinclude>`
console.log(out);
})();
// </nowiki>