User:Habst/getNcs.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
pret = ``;
window.meets ??= await (await fetch(pret+`/api/competitions/all?&country=DEN&category=outdoor&champ=NC`, { headers: { Authorization: auth } })).json();
out = ``;
getAllMeets = true;
window.cache ??= {};
records = {};
isField=t=>['jump','vault','put','throw','thlon'].some(w=>t.toLowerCase().includes(w))
m2s = mk => {
  if (!mk.includes(':')) return +mk;
  const [m, s] = mk.split(':');
  return +m * 60 + +s;
}
fmtWind=s=>{
  let w = s.toLowerCase().split(' ').at(-1);
  if (w === 'w') return '<small>(wind assisted)</small>';
  if (!w.startsWith('+') && !w.startsWith('-')) w = '+' + w;
  return `<small>(${w} m/s)</small>`;
}
for (const yrDiv of meets.divs.toReversed()) {
  const yr = yrDiv.id.split('-').at(-1);
  const comps = yrDiv.tables.flatMap(month => month.body.map(c => ({...c,month: month.title})));
  let ncs = comps;
  if (!getAllMeets) ncs = ncs.filter(c => c.endDate)
  ncs = ncs.map(c =>({...c, cids: [c.competitionId], endDate: c.endDate ?? c.startDate})).reduce((acc, c) => {
    const last = acc.at(-1);
    if (!last) acc.push(c);
    else {
      if ([last.startDate, last.endDate].some(d => [c.startDate, c.endDate].includes(d))) {
        if (c.startDate < last.startDate) last.startDate = c.startDate;
        if (c.endDate > last.endDate) last.endDate = c.endDate;
        last.cids.push(...c.cids);
      } else acc.push(c);
    }
    return acc;
  }, []);
  if (!getAllMeets && ncs.length > 1) {
    const multis = comps.filter(c => c.type === 'Multievents');
    const skipIds = [];
    for (const m of multis) {
      for (const c of ncs) {
        if ([m.startDate, m.endDate].includes(c.startDate) || [m.startDate, m.endDate].includes(c.endDate)) {
          skipIds.push(...c.cids);
        }
      }
    }
    ncs = ncs.filter(c => !skipIds.some(sid => c.cids.includes(sid)));
  }
  if (!getAllMeets && ncs.length > 1) {
    const dms = ncs.filter(c => c.competitionLong?.includes('DM Senior'));
    if (dms.length) ncs = dms;
  }
  if (!getAllMeets && ncs.length > 1) {
    ncs = ncs.filter(c => c.competitionLong === 'National Championships');
  }
  const c = ncs[0];
  const startDay = +c.startDate.split('-').at(-1);
  const endDay = +c.endDate.split('-').at(-1);
  if (getAllMeets) c.cids.push(...ncs.slice(1).flatMap(nc => nc.cids));
  for (const cid of c.cids) {
    window.cache[cid] ??= await (await fetch(pret+`/api/results/${cid}`, { headers: { Authorization: auth } })).json();
    for (const gen of window.cache[cid].genders ?? []) {
      const ag = gen.agegroups[0];
      for (const ev of ag.events) {
        let title = `${gen.title}'s ${ev.title}`;
        const field = isField(ev.title);
        for (const rnd of ev.rounds) for (const ht of rnd.heats) {
          const res = ht.results[0];
          const wind = ht.wind ?? res.wind;
          const mark = m2s(res.result);
          const ttl = res.windAssisted ? title+` (wind assisted)` : title;
          if (!records[ttl]) records[ttl] = { mark: field ? 0 : Infinity };
          if (field ? (mark >= records[ttl].mark) : (mark <= records[ttl].mark)) {
            const rec = { mark, name: res.name, year: yr, cid, wind, result: res.result };
            if (mark === records[ttl].mark) {
              records[ttl].ties ??= [];
              records[ttl].ties.push(rec);
            } else records[ttl] = rec;
          }
        }
      }
    }
  }
  out += `| [[${yr} Danish Athletics Championships|${yr}]] || ${startDay}-${endDay} ${c.month} || [[${c.venue}]] ||${c.cids.map(id => `<ref name=c${id}>{{Tilastopaja results|${id}|${yr} Danish Athletics Championships #${id}}}</ref>`).join('')}\n|-\n`;
}
recordsOut = '{{col-start}}\n';
curGen = '';
for (const evt of Object.keys(records).toSorted((a, b) => {
    if (a.startsWith("Men's") || a.startsWith("Women's")) {
      if (a.startsWith("Men's") && b.startsWith("Women's")) return -1;
      if (b.startsWith("Men's") && a.startsWith("Women's")) return 1;
      a = a.split(' ').slice(1).join(' ');
      b = b.split(' ').slice(1).join(' ');
    }
    const evtOrder = ['100m', '200m', '400m', '800m', '1500m', '5000m', '10,000m', 'Marathon', '110m Hurdles', '100m Hurdles', '400m Hurdles', '3000m Steeplechase', '5000m Race Walk'].reverse();
    const bScore = evtOrder.findIndex(evt => b.includes(evt) && !b.includes('x ' + evt));
    const aScore = evtOrder.findIndex(evt => a.includes(evt) && !a.includes('x ' + evt));
    if (bScore === -1 && aScore === -1) return a.localeCompare(b);
    return bScore - aScore;
  })) {
  const gen = evt.split(' ')[0];
  const dispEvt = evt.split(' ').slice(1).join(' ');
  if (curGen !== gen) {
    if (recordsOut !== '{{col-start}}\n') recordsOut += `|}\n`;
    recordsOut += `{{col-2}}
{| class=wikitable
|+${gen.replace("'s", "")}
|-
! Event !! Record !! Athlete !! Year !! Ref
|-\n`;
    curGen = gen;
  }
  if (evt.endsWith(' (wind assisted)')) {
    const normalEvt = evt.replace(' (wind assisted)', '');
    const field = isField(normalEvt);
    if (records[normalEvt] && (field ? (records[normalEvt].mark >= records[evt].mark) : (records[normalEvt].mark <= records[evt].mark))) continue;
  }
  const r = records[evt];
  const field = isField(evt);
  recordsOut += `| ${dispEvt} || ${r.result}${field ? evt.includes('thlon') ? ' pts' : ' m' : ''}${r.wind ? ` ${fmtWind(r.wind)}` : ''} || [[${r.name}]] || ${r.year} ||<ref name=c${r.cid} />\n|-\n`;
}
if (recordsOut.endsWith('|-\n')) recordsOut += '|}\n{{col-end}}';
console.log(recordsOut);