@wral/hsot-data 0.1.15 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,121 +1,85 @@
1
- import { LitElement as ae, html as n, css as y, nothing as p, svg as Z } from "lit";
2
- const pe = 50;
3
- function fe(a = {}) {
4
- const e = Object.entries(a).filter(([, s]) => s != null && s !== "");
5
- if (!e.length) return "";
6
- const t = new URLSearchParams();
7
- return e.forEach(([s, r]) => t.set(s, String(r))), `?${t.toString()}`;
8
- }
9
- function ue({ baseUrl: a, token: e = "", fetchFn: t } = {}) {
10
- if (!a) throw new Error("createClient requires a baseUrl");
11
- const s = a.replace(/\/+$/, ""), r = t || ((...i) => fetch(...i));
12
- async function o(i) {
13
- const h = { Accept: "application/json" };
14
- e && (h.Authorization = `Bearer ${e}`);
15
- const d = await r(`${s}${i}`, { headers: h });
16
- if (!d.ok) {
17
- const c = new Error(`api-hsot ${d.status} on ${i}`);
18
- throw c.status = d.status, c;
19
- }
20
- return d.json();
21
- }
22
- async function l(i, h = {}) {
23
- const d = [];
24
- let c = null;
25
- for (let m = 0; m < pe; m += 1) {
26
- const f = fe(c ? { ...h, cursor: c } : h), u = await o(`${i}${f}`);
27
- if (d.push(...u.items || []), c = u.nextCursor || null, !c) break;
28
- }
29
- return { items: d, total: d.length, nextCursor: null };
30
- }
31
- return {
32
- listSchools: (i) => l("/schools", i),
33
- getSchool: (i) => o(`/schools/${i}`),
34
- listTeams: (i) => l("/teams", i),
35
- getTeam: (i) => o(`/teams/${i}`),
36
- listConferences: (i) => l("/conferences", i),
37
- listPlayers: (i) => l("/players", i),
38
- listRosters: (i) => l("/rosters", i),
39
- listGames: (i) => l("/games", i),
40
- getGame: (i) => o(`/games/${i}`),
41
- listTournaments: (i) => l("/tournaments", i),
42
- listSeedings: (i, h) => l(`/tournaments/${i}/seedings`, h),
43
- listRankings: (i) => l("/rankings", i),
44
- listSports: () => o("/sports")
45
- };
46
- }
47
- const O = {
1
+ import { LitElement as ie, html as n, css as $, nothing as p, svg as J } from "lit";
2
+ import { createClient as $e } from "./client.mjs";
3
+ const A = {
48
4
  game: "/{sport}/game/{id}/",
49
5
  school: "/school/{id}/",
50
- section: "/{sport}/{view}/"
6
+ section: "/{sport}/{view}/",
7
+ // The "Report a Score" page; {id} is the game being reported on, and
8
+ // reportHref() drops the parameter when there is none.
9
+ report: "/report-a-score/?game={id}"
51
10
  };
52
11
  function g(a, e) {
53
12
  return String(a).replace(/\{(\w+)\}/g, (t, s) => e[s] !== void 0 && e[s] !== null ? String(e[s]) : t);
54
13
  }
55
- function F(a) {
14
+ function z(a) {
56
15
  return {
57
- game: a.getAttribute("game-href") || O.game,
58
- school: a.getAttribute("school-href") || O.school,
59
- section: a.getAttribute("section-href") || O.section
16
+ game: a.getAttribute("game-href") || A.game,
17
+ school: a.getAttribute("school-href") || A.school,
18
+ section: a.getAttribute("section-href") || A.section,
19
+ report: a.getAttribute("report-href") || A.report
60
20
  };
61
21
  }
62
- const I = (a) => a ? a.charAt(0).toUpperCase() + a.slice(1) : "";
63
- function $(a, e) {
22
+ function le(a, e = "") {
23
+ const t = g(a.report || A.report, { id: e || "" });
24
+ return e ? t : t.replace(/([?&])game=(?=&|$)/, "$1").replace(/[?&]$/, "").replace(/\?&/, "?");
25
+ }
26
+ const B = (a) => a ? a.charAt(0).toUpperCase() + a.slice(1) : "";
27
+ function w(a, e) {
64
28
  if (!a) return "TBD";
65
29
  const [t, s, r] = String(a).split("-").map(Number);
66
30
  return !t || !s || !r ? "TBD" : new Date(t, s - 1, r).toLocaleDateString("en-US", e || { weekday: "short", month: "short", day: "numeric" });
67
31
  }
68
- function U(a) {
32
+ function q(a) {
69
33
  if (!a) return "";
70
34
  const [e, t] = String(a).split(":").map(Number);
71
35
  if (Number.isNaN(e)) return "";
72
36
  const s = e >= 12 ? "PM" : "AM";
73
37
  return `${(e + 11) % 12 + 1}:${String(t || 0).padStart(2, "0")} ${s}`;
74
38
  }
75
- function ge(a) {
39
+ function we(a) {
76
40
  return a ? `${Math.floor(a / 12)}-${a % 12}` : "·";
77
41
  }
78
- function ve(a) {
42
+ function xe(a) {
79
43
  return (Array.isArray(a?.positions) ? a.positions : String(a?.position ?? "").split(/[/,]/)).map((t) => String(t ?? "").trim()).filter(Boolean).join("/");
80
44
  }
81
- function M(a = /* @__PURE__ */ new Date()) {
45
+ function _(a = /* @__PURE__ */ new Date()) {
82
46
  const e = a.getFullYear();
83
47
  return a.getMonth() >= 6 ? `${e}-${e + 1}` : `${e - 1}-${e}`;
84
48
  }
85
- function j(a = /* @__PURE__ */ new Date()) {
49
+ function W(a = /* @__PURE__ */ new Date()) {
86
50
  const e = (t) => String(t).padStart(2, "0");
87
51
  return `${a.getFullYear()}-${e(a.getMonth() + 1)}-${e(a.getDate())}`;
88
52
  }
89
- function be(a, e = j()) {
53
+ function ke(a, e = W()) {
90
54
  const t = [...new Set((a || []).filter(Boolean))].sort();
91
55
  if (!t.length || t.includes(e)) return e;
92
56
  const s = t.filter((r) => r < e);
93
57
  return s.length ? s[s.length - 1] : t[0];
94
58
  }
95
- function q(a) {
59
+ function V(a) {
96
60
  return a ? (a.abbr || a.name || "?").slice(0, 4).toUpperCase() : "?";
97
61
  }
98
- function _(a) {
62
+ function M(a) {
99
63
  if (!a || !/^#[0-9a-fA-F]{6}$/.test(a)) return "#FFFFFF";
100
64
  const e = parseInt(a.slice(1), 16), t = e >> 16 & 255, s = e >> 8 & 255, r = e & 255;
101
65
  return 0.299 * t + 0.587 * s + 0.114 * r > 150 ? "#0F1B33" : "#FFFFFF";
102
66
  }
103
- const ye = (a) => {
67
+ const Se = (a) => {
104
68
  const e = ["th", "st", "nd", "rd"], t = a % 100;
105
69
  return a + (e[(t - 20) % 10] || e[t] || e[0]);
106
70
  };
107
- function J(a, e) {
71
+ function ee(a, e) {
108
72
  const t = (o) => {
109
73
  const l = /^\d+/.exec(String(o ?? ""));
110
74
  return l ? Number(l[0]) : null;
111
75
  }, s = t(a), r = t(e);
112
76
  return s !== null && r !== null && s !== r ? r - s : s !== null && r === null ? -1 : s === null && r !== null ? 1 : String(a ?? "").localeCompare(String(e ?? ""), "en", { sensitivity: "base" });
113
77
  }
114
- function $e(a, e) {
78
+ function Ie(a, e) {
115
79
  const t = (s) => String(s?.name ?? s ?? "");
116
80
  return t(a).localeCompare(t(e), "en", { numeric: !0, sensitivity: "base" });
117
81
  }
118
- function re(a) {
82
+ function ce(a) {
119
83
  if (a.state === "live") {
120
84
  const e = [a.period, a.clock].filter(Boolean).join(" ");
121
85
  return { kind: "live", label: e ? `Live · ${e}` : "Live" };
@@ -124,9 +88,9 @@ function re(a) {
124
88
  const e = [];
125
89
  return a.finish === "overtime" && e.push("OT"), a.finish === "shootout" && e.push("PK-SO"), a.forfeit && a.forfeit !== "none" && e.push("Forfeit"), { kind: "final", label: `Final${e.length ? ` · ${e.join(" · ")}` : ""}` };
126
90
  }
127
- return a.state === "postponed" ? { kind: "warn", label: "Postponed" } : a.state === "canceled" ? { kind: "warn", label: "Canceled" } : { kind: "sched", label: `${$(a.date, { month: "short", day: "numeric" })} · ${U(a.time)}`.replace(/ · $/, "") };
91
+ return a.state === "postponed" ? { kind: "warn", label: "Postponed" } : a.state === "canceled" ? { kind: "warn", label: "Canceled" } : { kind: "sched", label: `${w(a.date, { month: "short", day: "numeric" })} · ${q(a.time)}`.replace(/ · $/, "") };
128
92
  }
129
- const we = /* @__PURE__ */ new Set(["game", "story", "page", "forum", "video", "gallery"]);
93
+ const Te = /* @__PURE__ */ new Set(["game", "story", "page", "forum", "video", "gallery"]);
130
94
  function S(a) {
131
95
  let e = String(a || "").replace(/^[a-z][a-z0-9+.-]*:\/\/[^/#?]*/i, "");
132
96
  const t = e.indexOf("#");
@@ -135,13 +99,13 @@ function S(a) {
135
99
  let r = e.split("?")[0] + s;
136
100
  return r = r.replace(/([^:])\/{2,}/g, "$1/").replace(/^\/{2,}/, "/"), r = r.replace(/^\/(?=#)/, ""), r.length > 1 && (r = r.replace(/\/+$/, "")), r.toLowerCase();
137
101
  }
138
- function oe() {
102
+ function de() {
139
103
  const a = globalThis.location;
140
104
  if (!a) return "";
141
105
  const e = (a.hash || "").startsWith("#/") ? a.hash : "";
142
106
  return S((a.pathname || "") + e);
143
107
  }
144
- function xe(a, e, t) {
108
+ function Ce(a, e, t) {
145
109
  if (!t) return null;
146
110
  const s = S(a);
147
111
  if (!s) return null;
@@ -150,28 +114,28 @@ function xe(a, e, t) {
150
114
  const l = S(g(e.section, { sport: t, view: "" }));
151
115
  if (s === l) return "";
152
116
  if (!s.startsWith(`${l}/`)) return null;
153
- const i = s.slice(l.length + 1), h = i.split("/");
154
- return h.length > 2 || h.some((d) => !/^[a-z][a-z-]*$/.test(d)) || we.has(h[0]) ? null : i;
117
+ const h = s.slice(l.length + 1), d = h.split("/");
118
+ return d.length > 2 || d.some((i) => !/^[a-z][a-z-]*$/.test(i)) || Te.has(d[0]) ? null : h;
155
119
  }
156
- function ke(a, e, t) {
120
+ function De(a, e, t) {
157
121
  const s = (l) => g(t.section, { sport: a, view: l }).replace(/([^:])\/{2,}/g, "$1/"), o = new Set((e || []).map((l) => l && l.gender).filter((l) => l === "boys" || l === "girls")).size === 2 ? [
158
122
  { label: "Boys Standings", href: s("boys/standings") },
159
123
  { label: "Girls Standings", href: s("girls/standings") }
160
124
  ] : [{ label: "Standings", href: s("standings") }];
161
125
  return [
162
- { label: `${I(a)} Home`, href: s("") },
126
+ { label: `${B(a)} Home`, href: s("") },
163
127
  { label: "Scores/Schedule", href: s("scores") },
164
128
  { label: "Playoff Brackets", href: s("brackets") },
165
129
  ...o,
166
130
  { label: "Polls & Rankings", href: s("rankings") }
167
131
  ];
168
132
  }
169
- function Se(a, e = oe()) {
133
+ function Be(a, e = de()) {
170
134
  const t = S(e);
171
135
  for (const s of a.querySelectorAll(':scope > a[slot="nav"]'))
172
136
  t && S(s.getAttribute("href")) === t ? s.setAttribute("aria-current", "page") : s.removeAttribute("aria-current");
173
137
  }
174
- class w extends ae {
138
+ class y extends ie {
175
139
  static properties = {
176
140
  api: { type: String },
177
141
  refreshInterval: { type: Number, attribute: "refresh-interval" },
@@ -190,7 +154,7 @@ class w extends ae {
190
154
  this._client = e, this.isConnected && this.load();
191
155
  }
192
156
  get client() {
193
- return this._client ? this._client : this.api ? ue({ baseUrl: this.api }) : null;
157
+ return this._client ? this._client : this.api ? $e({ baseUrl: this.api }) : null;
194
158
  }
195
159
  connectedCallback() {
196
160
  super.connectedCallback(), this._setupInterval();
@@ -202,7 +166,7 @@ class w extends ae {
202
166
  this.load();
203
167
  }
204
168
  updated(e) {
205
- e.has("api") && e.get("api") !== void 0 && e.get("api") !== this.api && this.load(), e.has("refreshInterval") && this._setupInterval(), Se(this);
169
+ e.has("api") && e.get("api") !== void 0 && e.get("api") !== this.api && this.load(), e.has("refreshInterval") && this._setupInterval(), Be(this);
206
170
  }
207
171
  async load() {
208
172
  const e = this.client;
@@ -237,7 +201,7 @@ class w extends ae {
237
201
  return n``;
238
202
  }
239
203
  }
240
- const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), Te = y`
204
+ const b = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), Fe = $`
241
205
  :host {
242
206
  --hsot-red: var(--color-red, #D1232A);
243
207
  --hsot-red-deep: var(--color-red-dark, #951C21);
@@ -275,7 +239,7 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), Te = y`
275
239
  outline-offset: 1px;
276
240
  }
277
241
  .mut { color: var(--hsot-gray-5); }
278
- `, Ie = y`
242
+ `, ze = $`
279
243
  .band { background: var(--hsot-white); color: var(--hsot-black); }
280
244
  .band .inner { max-width: 1366px; margin: 0 auto; padding: 1.1rem 1.25rem 0; }
281
245
  .band h1, .band h2.bandtitle {
@@ -324,7 +288,7 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), Te = y`
324
288
  @media (max-width: 720px) {
325
289
  .band h1, .band h2.bandtitle, .band.section h1, .band.section h2.bandtitle { font-size: 1.8rem; }
326
290
  }
327
- `, Ce = y`
291
+ `, Pe = $`
328
292
  .view { max-width: 1366px; margin: 0 auto; padding: 1.25rem; box-sizing: border-box; }
329
293
  /* Optional right rail (slot="rail" light-DOM children): a divided 300px
330
294
  column on desktop, stacked under the view content on smaller screens. */
@@ -388,7 +352,7 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), Te = y`
388
352
  .error { padding: 1.2rem 1rem; color: var(--hsot-red-deep); font-size: 0.9rem; }
389
353
  .note { font-size: 0.8125rem; color: var(--hsot-gray-5); margin: 0.6rem 0 0; }
390
354
  .loading { padding: 1.2rem; color: var(--hsot-gray-5); font-family: var(--hsot-heading-font); }
391
- `, De = y`
355
+ `, Ae = $`
392
356
  .pill {
393
357
  display: inline-block; font-family: var(--hsot-heading-font); font-weight: 700;
394
358
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em;
@@ -403,7 +367,7 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), Te = y`
403
367
  .pill.champ { background: var(--hsot-straw); color: #6b5900; }
404
368
  @keyframes hsot-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
405
369
  @media (prefers-reduced-motion: reduce) { .pill.live { animation: none; } }
406
- `, Fe = y`
370
+ `, Ee = $`
407
371
  .tablewrap { overflow-x: auto; }
408
372
  table.data { font-family: var(--hsot-heading-font); font-size: 14px; border-collapse: collapse; width: 100%; }
409
373
  table.data th {
@@ -421,7 +385,7 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), Te = y`
421
385
  table.data tbody tr.rowlink:hover { background: var(--hsot-gray-1); }
422
386
  table.data td.teamcell a { color: inherit; text-decoration: none; font-weight: 500; }
423
387
  table.data td.teamcell a:hover { text-decoration: underline; }
424
- `, ze = y`
388
+ `, _e = $`
425
389
  .swatch {
426
390
  display: inline-flex; align-items: center; justify-content: center;
427
391
  width: 26px; height: 26px; border-radius: 50%;
@@ -445,7 +409,7 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), Te = y`
445
409
  .dot.W { background: var(--hsot-win); }
446
410
  .dot.L { background: var(--hsot-loss); }
447
411
  .dot.T { background: var(--hsot-tie); }
448
- `, Pe = y`
412
+ `, Ne = $`
449
413
  ul.gamelist { list-style: none; margin: 0; padding: 0; }
450
414
  .gamelist li {
451
415
  display: flex; align-items: center; gap: 0.7rem; padding: 0.55rem 1rem;
@@ -495,80 +459,80 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), Te = y`
495
459
  .gamelist .ff { color: var(--hsot-gray-5); font-size: 0.78rem; font-style: italic; }
496
460
  .gamelist .where { color: var(--hsot-gray-5); font-size: 0.78rem; }
497
461
  .gamelist a.box { font-size: 0.78rem; }
498
- `, z = [Te, Ie, Ce, De, Fe, ze, Pe];
499
- function G(a) {
462
+ `, P = [Fe, ze, Pe, Ae, Ee, _e, Ne];
463
+ function H(a) {
500
464
  return a.state !== "final" ? null : a.forfeit === "home" ? "away" : a.forfeit === "away" || a.homeScore > a.awayScore ? "home" : a.awayScore > a.homeScore ? "away" : a.tiebreakWinner && a.tiebreakWinner !== "none" ? a.tiebreakWinner : "tie";
501
465
  }
502
- function Be(a) {
466
+ function Re(a) {
503
467
  return a && (a.forfeit === "home" || a.forfeit === "away") ? a.forfeit : null;
504
468
  }
505
- function P(a, e) {
469
+ function N(a, e) {
506
470
  const t = {}, s = (o) => (t[o] = t[o] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] }, t[o]), r = a.filter((o) => o.state === "final" && o.gameType !== "scrimmage" && (!e || o.date <= e)).sort((o, l) => String(o.date).localeCompare(String(l.date)));
507
471
  for (const o of r) {
508
- const l = G(o), i = o.gameType === "conference";
509
- for (const h of ["home", "away"]) {
510
- const d = h === "home" ? o.homeTeamId : o.awayTeamId;
511
- if (!d) continue;
512
- const c = s(d), m = h === "home" ? o.homeScore : o.awayScore, f = h === "home" ? o.awayScore : o.homeScore;
472
+ const l = H(o), h = o.gameType === "conference";
473
+ for (const d of ["home", "away"]) {
474
+ const i = d === "home" ? o.homeTeamId : o.awayTeamId;
475
+ if (!i) continue;
476
+ const c = s(i), m = d === "home" ? o.homeScore : o.awayScore, f = d === "home" ? o.awayScore : o.homeScore;
513
477
  c.pf += m, c.pa += f;
514
478
  let u = "T";
515
- l === "tie" ? (c.t += 1, i && (c.ct += 1)) : l === h ? (c.w += 1, i && (c.cw += 1), u = "W") : (c.l += 1, i && (c.cl += 1), u = "L"), c.results.push({ gameId: o.id, date: o.date, mark: u, my: m, their: f, opp: h === "home" ? o.awayTeamId : o.homeTeamId, conf: i });
479
+ l === "tie" ? (c.t += 1, h && (c.ct += 1)) : l === d ? (c.w += 1, h && (c.cw += 1), u = "W") : (c.l += 1, h && (c.cl += 1), u = "L"), c.results.push({ gameId: o.id, date: o.date, mark: u, my: m, their: f, opp: d === "home" ? o.awayTeamId : o.homeTeamId, conf: h });
516
480
  }
517
481
  }
518
482
  return t;
519
483
  }
520
- function H(a) {
484
+ function U(a) {
521
485
  if (!a || !a.length) return "";
522
486
  const e = a[a.length - 1].mark;
523
487
  let t = 0;
524
488
  for (let s = a.length - 1; s >= 0 && a[s].mark === e; s -= 1) t += 1;
525
489
  return e + t;
526
490
  }
527
- const ee = (a, e, t) => {
491
+ const te = (a, e, t) => {
528
492
  const s = a + e + t;
529
493
  return s ? (a + t / 2) / s : 0;
530
- }, te = (a) => a.toFixed(3).replace("0.", ".");
494
+ }, se = (a) => a.toFixed(3).replace("0.", ".");
531
495
  function k(a, e = !1) {
532
496
  if (!a) return "0-0";
533
497
  const t = e ? a.cw : a.w, s = e ? a.cl : a.l, r = e ? a.ct : a.t;
534
498
  return `${t}-${s}${r ? `-${r}` : ""}`;
535
499
  }
536
- function ne(a, e) {
500
+ function he(a, e) {
537
501
  return a.map((t) => {
538
502
  const s = e[t.id] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] };
539
- return { team: t, rec: s, confPct: ee(s.cw, s.cl, s.ct), overallPct: ee(s.w, s.l, s.t) };
503
+ return { team: t, rec: s, confPct: te(s.cw, s.cl, s.ct), overallPct: te(s.w, s.l, s.t) };
540
504
  }).sort((t, s) => s.confPct - t.confPct || s.overallPct - t.overallPct || s.rec.pf - s.rec.pa - (t.rec.pf - t.rec.pa));
541
505
  }
542
- function W(a, e) {
506
+ function Y(a, e) {
543
507
  return a.filter((t) => (t.homeTeamId === e || t.awayTeamId === e) && (t.state === "scheduled" || t.state === "live") && t.gameType !== "scrimmage").sort((t, s) => String(t.date).localeCompare(String(s.date)))[0] || null;
544
508
  }
545
- function se(a, e) {
509
+ function ae(a, e) {
546
510
  const t = a[e];
547
511
  return t && t.results.length ? t.results[t.results.length - 1] : null;
548
512
  }
549
- function st(a, e, t, s = "") {
513
+ function $t(a, e, t, s = "") {
550
514
  let r = null;
551
515
  for (const o of a || [])
552
516
  o.sport === e && (t && o.effectiveDate > t || s && o.gender && o.gender !== s || (!r || o.effectiveDate > r.effectiveDate) && (r = o));
553
517
  return r;
554
518
  }
555
- function V(a, e, t, s, r) {
519
+ function K(a, e, t, s, r) {
556
520
  const o = e[t];
557
521
  if (!o) return null;
558
522
  const l = /* @__PURE__ */ new Map();
559
- for (const h of a || []) {
560
- if (h.sport !== s || r && h.effectiveDate > r || h.gender && o.gender !== h.gender && o.gender !== "coed") continue;
561
- const d = h.gender || "", c = l.get(d);
562
- (!c || h.effectiveDate > c.effectiveDate) && l.set(d, h);
523
+ for (const d of a || []) {
524
+ if (d.sport !== s || r && d.effectiveDate > r || d.gender && o.gender !== d.gender && o.gender !== "coed") continue;
525
+ const i = d.gender || "", c = l.get(i);
526
+ (!c || d.effectiveDate > c.effectiveDate) && l.set(i, d);
563
527
  }
564
- let i = null;
565
- for (const h of l.values()) {
566
- const d = (h.teamIds || []).indexOf(t);
567
- d !== -1 && (!i || h.effectiveDate > i.effectiveDate) && (i = { poll: h, rank: d + 1 });
528
+ let h = null;
529
+ for (const d of l.values()) {
530
+ const i = (d.teamIds || []).indexOf(t);
531
+ i !== -1 && (!h || d.effectiveDate > h.effectiveDate) && (h = { poll: d, rank: i + 1 });
568
532
  }
569
- return i ? i.rank : null;
533
+ return h ? h.rank : null;
570
534
  }
571
- function Ae(a, e, t) {
535
+ function Me(a, e, t) {
572
536
  if (!a) return { kind: "none", delta: 0 };
573
537
  const s = (a.teamIds || []).indexOf(t) + 1;
574
538
  if (!s) return { kind: "none", delta: 0 };
@@ -578,100 +542,100 @@ function Ae(a, e, t) {
578
542
  const o = r - s;
579
543
  return o > 0 ? { kind: "up", delta: o } : o < 0 ? { kind: "down", delta: -o } : { kind: "same", delta: 0 };
580
544
  }
581
- function Ee(a) {
545
+ function Le(a) {
582
546
  return /^https?:\/\//i.test(String(a || ""));
583
547
  }
584
- function ie(a, { w: e, h: t } = {}) {
585
- if (!Ee(a)) return "";
548
+ function me(a, { w: e, h: t } = {}) {
549
+ if (!Le(a)) return "";
586
550
  const s = [];
587
551
  e && s.push(`w=${Math.max(1, Math.round(e))}`), t && s.push(`h=${Math.max(1, Math.round(t))}`), s.push("f=webp");
588
552
  const r = a.includes("?") ? "&" : "?";
589
553
  return `${a}${r}${s.join("&")}`;
590
554
  }
591
- function R(a, e) {
555
+ function L(a, e) {
592
556
  const t = e * 2;
593
- return ie(a?.logoAssetId, { w: t, h: t });
557
+ return me(a?.logoAssetId, { w: t, h: t });
594
558
  }
595
- function _e(a, e) {
596
- return ie(a?.photoAssetId, { w: e * 2 });
559
+ function Ge(a, e) {
560
+ return me(a?.photoAssetId, { w: e * 2 });
597
561
  }
598
- function Y(a, e, { title: t, sub: s, teams: r }) {
599
- const o = oe(), i = !!a.querySelector(':scope > a[slot="nav"]') || xe(o, e.hrefs, e.sport) !== null;
562
+ function j(a, e, { title: t, sub: s, teams: r }) {
563
+ const o = de(), h = !!a.querySelector(':scope > a[slot="nav"]') || Ce(o, e.hrefs, e.sport) !== null;
600
564
  return n`
601
565
  <div class="band section">
602
566
  <div class="inner">
603
567
  <h1>${t}</h1>
604
568
  ${s ? n`<p class="sub">${s}</p>` : p}
605
569
  </div>
606
- ${i ? n`
607
- <nav class="sectionnav" aria-label="${I(e.sport)} section">
570
+ ${h ? n`
571
+ <nav class="sectionnav" aria-label="${B(e.sport)} section">
608
572
  <div class="navrow">
609
573
  <slot name="nav">
610
- ${ke(e.sport, r, e.hrefs).map((h) => n`<a href=${h.href}
611
- aria-current=${o && S(h.href) === o ? "page" : p}>${h.label}</a>`)}
574
+ ${De(e.sport, r, e.hrefs).map((d) => n`<a href=${d.href}
575
+ aria-current=${o && S(d.href) === o ? "page" : p}>${d.label}</a>`)}
612
576
  </slot>
613
577
  </div>
614
578
  </nav>` : p}
615
579
  </div>
616
580
  `;
617
581
  }
618
- const C = (a, e) => {
582
+ const I = (a, e) => {
619
583
  const t = a.teamsById[e];
620
584
  return t ? a.schoolsById[t.schoolId] : null;
621
- }, T = (a, e) => C(a, e)?.name || "TBD", N = (a, e) => C(a, e)?.abbr || "TBD";
622
- function D(a, e = 26) {
585
+ }, F = (a, e) => I(a, e)?.name || "TBD", G = (a, e) => I(a, e)?.abbr || "TBD";
586
+ function T(a, e = 26) {
623
587
  if (!a) return p;
624
- const t = R(a, e);
588
+ const t = L(a, e);
625
589
  if (t)
626
590
  return n`<img class="swatch logo" aria-hidden="true" alt="" loading="lazy"
627
591
  src=${t} style="width:${e}px;height:${e}px" />`;
628
- const s = a.colorPrimary || "#030711", r = _(s);
592
+ const s = a.colorPrimary || "#030711", r = M(s);
629
593
  return n`<span class="swatch" aria-hidden="true"
630
594
  style="width:${e}px;height:${e}px;background:${s};color:${r};font-size:${Math.max(8, e * 0.28)}px"
631
- >${q(a)}</span>`;
595
+ >${V(a)}</span>`;
632
596
  }
633
597
  function Q(a, e, t) {
634
- const s = V(a.rankings, a.teamsById, e, a.sport, t);
598
+ const s = K(a.rankings, a.teamsById, e, a.sport, t);
635
599
  return s ? n`<span class="rankbadge">#${s}</span>` : p;
636
600
  }
637
- function le(a, e, t) {
638
- const s = C(a, e);
601
+ function O(a, e, t) {
602
+ const s = I(a, e);
639
603
  return s ? n`${Q(a, e, t)}<a href=${g(a.hrefs.school, { id: s.id })}>${s.name}</a>` : n`<span class="mut">TBD</span>`;
640
604
  }
641
- function K(a, e, t = 5) {
605
+ function X(a, e, t = 5) {
642
606
  const s = a.records[e];
643
607
  if (!s || !s.results.length) return n`<span class="mut">·</span>`;
644
608
  const r = s.results.slice(-1 * t);
645
609
  return n`<span class="dots" role="img" aria-label="last ${r.length} results">
646
610
  ${r.map((o) => n`<a class="dot ${o.mark}"
647
- title="${o.mark} ${o.my}-${o.their} vs ${T(a, o.opp)}"
611
+ title="${o.mark} ${o.my}-${o.their} vs ${F(a, o.opp)}"
648
612
  href=${g(a.hrefs.game, { sport: a.sport, id: o.gameId })}>${o.mark}</a>`)}
649
613
  </span>`;
650
614
  }
651
- function B(a, e) {
615
+ function C(a, e) {
652
616
  return a.querySelector(':scope > [slot="rail"]') ? n`<div class="view withrail">
653
617
  <div class="viewmain">${e}</div>
654
618
  <aside class="viewrail"><slot name="rail"></slot></aside>
655
619
  </div>` : n`<div class="view">${e}</div>`;
656
620
  }
657
- function A(a) {
621
+ function D(a) {
658
622
  if (!a.promoImage) return p;
659
623
  const e = n`<img src=${a.promoImage} alt=${a.promoAlt || "Sponsor"}>`;
660
624
  return n`<div class="promo">${a.promoHref ? n`<a href=${a.promoHref} target="_blank" rel="sponsored noopener">${e}</a>` : e}</div>`;
661
625
  }
662
- function L(a) {
663
- const e = re(a);
626
+ function E(a) {
627
+ const e = ce(a);
664
628
  return n`<span class="pill ${e.kind}">${e.label}</span>`;
665
629
  }
666
- function ce(a, e, t) {
630
+ function pe(a, e, t) {
667
631
  if (!e) return n`<span class="mut">·</span>`;
668
632
  const s = e.homeTeamId === t ? e.awayTeamId : e.homeTeamId, r = e.homeTeamId === t ? "vs" : "at";
669
- return n`${e.state === "live" ? n`<span class="pill live">Live</span> ` : n`${$(e.date, { month: "numeric", day: "numeric" })} `}${r} ${N(a, s)}`;
633
+ return n`${e.state === "live" ? n`<span class="pill live">Live</span> ` : n`${w(e.date, { month: "numeric", day: "numeric" })} `}${r} ${G(a, s)}`;
670
634
  }
671
- class Re extends w {
672
- static styles = z;
635
+ class Oe extends y {
636
+ static styles = P;
673
637
  static properties = {
674
- ...w.properties,
638
+ ...y.properties,
675
639
  sport: { type: String },
676
640
  season: { type: String },
677
641
  date: { type: String }
@@ -687,57 +651,57 @@ class Re extends w {
687
651
  this._datePinned = !!this.date;
688
652
  }
689
653
  async fetchData(e) {
690
- const t = this.season || M(), [s, r, o, l, i] = await Promise.all([
654
+ const t = this.season || _(), [s, r, o, l, h] = await Promise.all([
691
655
  e.listSchools(),
692
656
  e.listTeams({ sport: this.sport }),
693
657
  e.listConferences(),
694
658
  e.listGames({ sport: this.sport, season: t }),
695
659
  e.listRankings({ sport: this.sport })
696
660
  ]);
697
- return this._datePinned || (this.date = be(l.items.map((h) => h.date)), this._datePinned = !0), {
661
+ return this._datePinned || (this.date = ke(l.items.map((d) => d.date)), this._datePinned = !0), {
698
662
  season: t,
699
663
  schools: s.items,
700
664
  teams: r.items,
701
665
  conferences: o.items,
702
666
  games: l.items,
703
- rankings: i.items
667
+ rankings: h.items
704
668
  };
705
669
  }
706
670
  get ctx() {
707
671
  return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
708
- teamsById: v(this.data.teams),
709
- schoolsById: v(this.data.schools),
710
- records: P(this.data.games),
672
+ teamsById: b(this.data.teams),
673
+ schoolsById: b(this.data.schools),
674
+ records: N(this.data.games),
711
675
  rankings: this.data.rankings,
712
- hrefs: F(this),
676
+ hrefs: z(this),
713
677
  sport: this.sport
714
678
  }, this._ctxData = this.data), this._ctx;
715
679
  }
716
680
  renderView() {
717
- const e = this.ctx, t = v(this.data.conferences), s = [...new Set(this.data.games.map((d) => d.date).filter(Boolean))].sort(), r = Number.MAX_SAFE_INTEGER, o = (d) => {
718
- const c = [d.awayTeamId, d.homeTeamId].map((m) => V(e.rankings, e.teamsById, m, this.sport, d.date)).filter(Boolean);
681
+ const e = this.ctx, t = b(this.data.conferences), s = [...new Set(this.data.games.map((i) => i.date).filter(Boolean))].sort(), r = Number.MAX_SAFE_INTEGER, o = (i) => {
682
+ const c = [i.awayTeamId, i.homeTeamId].map((m) => K(e.rankings, e.teamsById, m, this.sport, i.date)).filter(Boolean);
719
683
  return c.length ? Math.min(...c) : r;
720
- }, l = this.data.games.filter((d) => d.date === this.date), i = new Map(l.map((d) => [d, o(d)]));
721
- l.sort((d, c) => (d.state === "live" ? 0 : 1) - (c.state === "live" ? 0 : 1) || i.get(d) - i.get(c));
722
- const h = /* @__PURE__ */ new Map();
723
- return l.forEach((d) => {
724
- const c = d.gameType === "conference" && d.conferenceId ? t[d.conferenceId]?.name || "Conference" : d.gameType === "playoff" ? "Playoffs" : d.gameType === "scrimmage" ? "Scrimmages" : "Nonconference";
725
- h.has(c) || h.set(c, []), h.get(c).push(d);
684
+ }, l = this.data.games.filter((i) => i.date === this.date), h = new Map(l.map((i) => [i, o(i)]));
685
+ l.sort((i, c) => (i.state === "live" ? 0 : 1) - (c.state === "live" ? 0 : 1) || h.get(i) - h.get(c));
686
+ const d = /* @__PURE__ */ new Map();
687
+ return l.forEach((i) => {
688
+ const c = i.gameType === "conference" && i.conferenceId ? t[i.conferenceId]?.name || "Conference" : i.gameType === "playoff" ? "Playoffs" : i.gameType === "scrimmage" ? "Scrimmages" : "Nonconference";
689
+ d.has(c) || d.set(c, []), d.get(c).push(i);
726
690
  }), n`
727
- ${Y(this, e, {
728
- title: n`${I(this.sport)} scores &amp; schedules`,
729
- sub: n`${$(this.date, { weekday: "long", month: "long", day: "numeric", year: "numeric" })} · ${l.length} games`,
691
+ ${j(this, e, {
692
+ title: n`${B(this.sport)} scores &amp; schedules`,
693
+ sub: n`${w(this.date, { weekday: "long", month: "long", day: "numeric", year: "numeric" })} · ${l.length} games`,
730
694
  teams: this.data.teams
731
695
  })}
732
- ${B(this, n`
733
- ${A(this)}
696
+ ${C(this, n`
697
+ ${D(this)}
734
698
  <div class="toolbar">
735
699
  <label class="asof" for="datesel">Date</label>
736
- <select id="datesel" @change=${(d) => {
737
- this.date = d.target.value;
700
+ <select id="datesel" @change=${(i) => {
701
+ this.date = i.target.value;
738
702
  }}>
739
- ${(s.includes(this.date) ? s : [...s, this.date].sort()).map((d) => n`<option value=${d} ?selected=${d === this.date}>
740
- ${$(d, { weekday: "short", month: "short", day: "numeric" })}${d === j() ? " · today" : ""}
703
+ ${(s.includes(this.date) ? s : [...s, this.date].sort()).map((i) => n`<option value=${i} ?selected=${i === this.date}>
704
+ ${w(i, { weekday: "short", month: "short", day: "numeric" })}${i === W() ? " · today" : ""}
741
705
  </option>`)}
742
706
  </select>
743
707
  <button class="chip" ?disabled=${s.indexOf(this.date) <= 0}
@@ -749,11 +713,11 @@ class Re extends w {
749
713
  this.date = s[s.indexOf(this.date) + 1];
750
714
  }}>Next →</button>
751
715
  <span class="spacer"></span>
752
- <span class="asof">Live games first · report a score to see it update here</span>
716
+ <span class="asof">Live games first · <a href=${le(e.hrefs)}>report a score</a> to see it update here</span>
753
717
  </div>
754
718
  ${l.length ? p : n`<p class="empty">No ${this.sport} games on this date.</p>`}
755
- ${[...h.entries()].map(([d, c]) => n`
756
- <div class="section-title">${d}</div>
719
+ ${[...d.entries()].map(([i, c]) => n`
720
+ <div class="section-title">${i}</div>
757
721
  <div class="card"><ul class="gamelist">
758
722
  ${c.map((m) => this.renderGame(e, m))}
759
723
  </ul></div>
@@ -765,12 +729,12 @@ class Re extends w {
765
729
  // a lone score column on the far right read as detached from the teams).
766
730
  // Scheduled games carry their start time on the status pill alone.
767
731
  renderGame(e, t) {
768
- const s = t.state === "final" || t.state === "live", r = (l, i, h = p) => n`<span class="side">${le(e, l, t.date)}${s ? n`<span class="score">${i}</span>` : p}${h}</span>`, o = Be(t);
732
+ const s = t.state === "final" || t.state === "live", r = (l, h, d = p) => n`<span class="side">${O(e, l, t.date)}${s ? n`<span class="score">${h}</span>` : p}${d}</span>`, o = Re(t);
769
733
  return n`
770
734
  <li>
771
- ${L(t)}
735
+ ${E(t)}
772
736
  <span class="opp matchup">${r(t.awayTeamId, t.awayScore, n`<span class="at">at</span>`)}${r(t.homeTeamId, t.homeScore)}</span>
773
- ${o ? n`<span class="ff">${T(e, o === "home" ? t.homeTeamId : t.awayTeamId)} forfeited</span>` : p}
737
+ ${o ? n`<span class="ff">${F(e, o === "home" ? t.homeTeamId : t.awayTeamId)} forfeited</span>` : p}
774
738
  <span class="where">${t.venue || ""}</span>
775
739
  ${t.broadcast ? n`<span class="pill class">${t.broadcast}</span>` : p}
776
740
  <a class="box" href=${g(e.hrefs.game, { sport: this.sport, id: t.id })}>Box score →</a>
@@ -778,11 +742,11 @@ class Re extends w {
778
742
  `;
779
743
  }
780
744
  }
781
- globalThis?.customElements && !globalThis.customElements.get("hsot-scores") && globalThis.customElements.define("hsot-scores", Re);
782
- class Ne extends w {
783
- static styles = z;
745
+ globalThis?.customElements && !globalThis.customElements.get("hsot-scores") && globalThis.customElements.define("hsot-scores", Oe);
746
+ class He extends y {
747
+ static styles = P;
784
748
  static properties = {
785
- ...w.properties,
749
+ ...y.properties,
786
750
  sport: { type: String },
787
751
  season: { type: String },
788
752
  classFilter: { state: !0 },
@@ -792,7 +756,7 @@ class Ne extends w {
792
756
  super(), this.sport = "football", this.season = "", this.classFilter = "All", this.query = "";
793
757
  }
794
758
  async fetchData(e) {
795
- const t = this.season || M(), [s, r, o, l, i] = await Promise.all([
759
+ const t = this.season || _(), [s, r, o, l, h] = await Promise.all([
796
760
  e.listConferences({ active: !0 }),
797
761
  e.listSchools(),
798
762
  e.listTeams({ sport: this.sport }),
@@ -805,29 +769,29 @@ class Ne extends w {
805
769
  schools: r.items,
806
770
  teams: o.items,
807
771
  games: l.items,
808
- rankings: i.items
772
+ rankings: h.items
809
773
  };
810
774
  }
811
775
  get ctx() {
812
776
  return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
813
- teamsById: v(this.data.teams),
814
- schoolsById: v(this.data.schools),
815
- records: P(this.data.games),
777
+ teamsById: b(this.data.teams),
778
+ schoolsById: b(this.data.schools),
779
+ records: N(this.data.games),
816
780
  rankings: this.data.rankings,
817
- hrefs: F(this),
781
+ hrefs: z(this),
818
782
  sport: this.sport
819
783
  }, this._ctxData = this.data), this._ctx;
820
784
  }
821
785
  renderView() {
822
- const e = this.ctx, t = ["All", ...[...new Set(this.data.conferences.flatMap((r) => r.classifications || []))].sort(J)].slice(0, 9), s = this.data.conferences.filter((r) => r.active !== !1).filter((r) => this.classFilter === "All" || (r.classifications || []).includes(this.classFilter)).sort($e);
786
+ const e = this.ctx, t = ["All", ...[...new Set(this.data.conferences.flatMap((r) => r.classifications || []))].sort(ee)].slice(0, 9), s = this.data.conferences.filter((r) => r.active !== !1).filter((r) => this.classFilter === "All" || (r.classifications || []).includes(this.classFilter)).sort(Ie);
823
787
  return n`
824
- ${Y(this, e, {
825
- title: n`${I(this.sport)} standings`,
788
+ ${j(this, e, {
789
+ title: n`${B(this.sport)} standings`,
826
790
  sub: n`${this.data.season} season · every conference, computed live from reported results`,
827
791
  teams: this.data.teams
828
792
  })}
829
- ${B(this, n`
830
- ${A(this)}
793
+ ${C(this, n`
794
+ ${D(this)}
831
795
  <div class="toolbar">
832
796
  <div role="group" aria-label="Classification filter">
833
797
  ${t.map((r) => n`<button class="chip ${this.classFilter === r ? "on" : ""}"
@@ -840,7 +804,7 @@ class Ne extends w {
840
804
  this.query = r.target.value;
841
805
  }}>
842
806
  <span class="spacer"></span>
843
- <span class="asof">Records through ${$(j(), { month: "long", day: "numeric" })} · conference games count toward both records · scrimmages toward neither</span>
807
+ <span class="asof">Records through ${w(W(), { month: "long", day: "numeric" })} · conference games count toward both records · scrimmages toward neither</span>
844
808
  </div>
845
809
  ${s.map((r) => this.renderConference(e, r))}
846
810
  `)}
@@ -849,12 +813,12 @@ class Ne extends w {
849
813
  renderConference(e, t) {
850
814
  const s = this.data.teams.filter((l) => l.conferenceId === t.id);
851
815
  if (!s.length) return p;
852
- const r = this.query.trim().toLowerCase(), o = ne(s, e.records);
816
+ const r = this.query.trim().toLowerCase(), o = he(s, e.records);
853
817
  return n`
854
818
  <div class="card">
855
819
  <div class="card-head">
856
820
  <h2>${t.name}</h2>
857
- ${[...t.classifications || []].sort(J).map((l) => n`<span class="pill class">${l}</span>`)}
821
+ ${[...t.classifications || []].sort(ee).map((l) => n`<span class="pill class">${l}</span>`)}
858
822
  <span class="meta">${o.length} teams · membership derives from teams</span>
859
823
  </div>
860
824
  <div class="tablewrap"><table class="data">
@@ -864,7 +828,7 @@ class Ne extends w {
864
828
  <th>Streak</th><th>Last 5</th><th>Next</th>
865
829
  </tr></thead>
866
830
  <tbody>
867
- ${o.map((l, i) => this.renderRow(e, l, i, r))}
831
+ ${o.map((l, h) => this.renderRow(e, l, h, r))}
868
832
  </tbody>
869
833
  </table></div>
870
834
  </div>
@@ -873,34 +837,34 @@ class Ne extends w {
873
837
  renderRow(e, t, s, r) {
874
838
  const o = e.schoolsById[t.team.schoolId], l = o?.name || t.team.name || "TBD";
875
839
  if (r && !l.toLowerCase().includes(r)) return p;
876
- const i = t.rec.pf - t.rec.pa, h = W(this.data.games, t.team.id), d = () => {
840
+ const h = t.rec.pf - t.rec.pa, d = Y(this.data.games, t.team.id), i = () => {
877
841
  location.href = g(e.hrefs.school, { id: t.team.schoolId });
878
842
  };
879
843
  return n`
880
844
  <tr class="rowlink" @click=${(c) => {
881
- c.target.closest("a") || d();
845
+ c.target.closest("a") || i();
882
846
  }}>
883
847
  <td class="mut">${s + 1}</td>
884
848
  <td class="teamcell">
885
- ${D(o)}${Q(e, t.team.id, null)}
849
+ ${T(o)}${Q(e, t.team.id, null)}
886
850
  <a href=${g(e.hrefs.school, { id: t.team.schoolId })}>${l}</a>
887
851
  </td>
888
852
  <td class="num">${k(t.rec, !0)}</td>
889
- <td class="num">${te(t.confPct)}</td>
853
+ <td class="num">${se(t.confPct)}</td>
890
854
  <td class="num">${k(t.rec)}</td>
891
- <td class="num">${te(t.overallPct)}</td>
855
+ <td class="num">${se(t.overallPct)}</td>
892
856
  <td class="num">${t.rec.pf}</td>
893
857
  <td class="num">${t.rec.pa}</td>
894
- <td class="num" style="color:${i >= 0 ? "var(--hsot-win)" : "var(--hsot-loss)"}">${i > 0 ? "+" : ""}${i}</td>
895
- <td>${H(t.rec.results) || "·"}</td>
896
- <td>${K(e, t.team.id)}</td>
897
- <td>${ce(e, h, t.team.id)}</td>
858
+ <td class="num" style="color:${h >= 0 ? "var(--hsot-win)" : "var(--hsot-loss)"}">${h > 0 ? "+" : ""}${h}</td>
859
+ <td>${U(t.rec.results) || "·"}</td>
860
+ <td>${X(e, t.team.id)}</td>
861
+ <td>${pe(e, d, t.team.id)}</td>
898
862
  </tr>
899
863
  `;
900
864
  }
901
865
  }
902
- globalThis?.customElements && !globalThis.customElements.get("hsot-standings") && globalThis.customElements.define("hsot-standings", Ne);
903
- const Le = y`
866
+ globalThis?.customElements && !globalThis.customElements.get("hsot-standings") && globalThis.customElements.define("hsot-standings", He);
867
+ const Ue = $`
904
868
  .hero1 {
905
869
  border-radius: var(--hsot-radius-md); color: var(--hsot-white);
906
870
  padding: 1.3rem 1.4rem; display: flex; align-items: center; gap: 1.2rem;
@@ -917,10 +881,10 @@ const Le = y`
917
881
  .delta.new { background: var(--hsot-straw); color: #6b5900; border-radius: var(--hsot-radius-xs); padding: 0.1rem 0.3rem; font-size: 0.7rem; }
918
882
  .sparkline { vertical-align: middle; }
919
883
  `;
920
- class Me extends w {
921
- static styles = [...z, Le];
884
+ class je extends y {
885
+ static styles = [...P, Ue];
922
886
  static properties = {
923
- ...w.properties,
887
+ ...y.properties,
924
888
  sport: { type: String },
925
889
  gender: { type: String },
926
890
  season: { type: String },
@@ -935,73 +899,73 @@ class Me extends w {
935
899
  e && (this.pollDate = e);
936
900
  }
937
901
  async fetchData(e) {
938
- const t = this.season || M(), [s, r, o, l, i] = await Promise.all([
902
+ const t = this.season || _(), [s, r, o, l, h] = await Promise.all([
939
903
  e.listRankings({ sport: this.sport, ...this.gender ? { gender: this.gender } : {} }),
940
904
  e.listSchools(),
941
905
  e.listTeams({ sport: this.sport }),
942
906
  e.listConferences(),
943
907
  e.listGames({ sport: this.sport, season: t })
944
- ]), h = s.items.filter((d) => !this.gender || !d.gender || d.gender === this.gender).sort((d, c) => c.effectiveDate.localeCompare(d.effectiveDate));
908
+ ]), d = s.items.filter((i) => !this.gender || !i.gender || i.gender === this.gender).sort((i, c) => c.effectiveDate.localeCompare(i.effectiveDate));
945
909
  return {
946
910
  season: t,
947
- polls: h,
911
+ polls: d,
948
912
  schools: r.items,
949
913
  teams: o.items,
950
914
  conferences: l.items,
951
- games: i.items
915
+ games: h.items
952
916
  };
953
917
  }
954
918
  get ctx() {
955
919
  return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
956
- teamsById: v(this.data.teams),
957
- schoolsById: v(this.data.schools),
958
- records: P(this.data.games),
920
+ teamsById: b(this.data.teams),
921
+ schoolsById: b(this.data.schools),
922
+ records: N(this.data.games),
959
923
  rankings: this.data.polls,
960
- hrefs: F(this),
924
+ hrefs: z(this),
961
925
  sport: this.sport
962
926
  }, this._ctxData = this.data), this._ctx;
963
927
  }
964
928
  sparkline(e, t, s) {
965
- const i = t.map((m, f) => {
929
+ const h = t.map((m, f) => {
966
930
  const u = (m.teamIds || []).indexOf(e);
967
931
  if (u === -1) return null;
968
- const b = t.length === 1 ? 96 / 2 : f / (t.length - 1) * 90 + 3, x = 3 + u / 24 * 20;
969
- return { x: b, y: x };
970
- }), h = [];
971
- let d = [];
972
- if (i.forEach((m) => {
973
- m ? d.push(m) : d.length && (h.push(d), d = []);
974
- }), d.length && h.push(d), !h.length) return p;
975
- const c = i[s];
932
+ const v = t.length === 1 ? 96 / 2 : f / (t.length - 1) * 90 + 3, x = 3 + u / 24 * 20;
933
+ return { x: v, y: x };
934
+ }), d = [];
935
+ let i = [];
936
+ if (h.forEach((m) => {
937
+ m ? i.push(m) : i.length && (d.push(i), i = []);
938
+ }), i.length && d.push(i), !d.length) return p;
939
+ const c = h[s];
976
940
  return n`<svg class="sparkline" width=${96} height=${26} viewBox="0 0 ${96} ${26}" role="img" aria-label="rank history">
977
- ${h.map((m) => Z`<polyline fill="none" stroke="var(--hsot-red)" stroke-width="2"
941
+ ${d.map((m) => J`<polyline fill="none" stroke="var(--hsot-red)" stroke-width="2"
978
942
  points=${m.map((f) => `${f.x.toFixed(1)},${f.y.toFixed(1)}`).join(" ")}></polyline>`)}
979
- ${c ? Z`<circle cx=${c.x.toFixed(1)} cy=${c.y.toFixed(1)} r="3" fill="var(--hsot-black)"></circle>` : p}
943
+ ${c ? J`<circle cx=${c.x.toFixed(1)} cy=${c.y.toFixed(1)} r="3" fill="var(--hsot-black)"></circle>` : p}
980
944
  </svg>`;
981
945
  }
982
946
  movement(e, t, s) {
983
- const r = Ae(e, t, s);
947
+ const r = Me(e, t, s);
984
948
  return r.kind === "up" ? n`<span class="delta up">▲ ${r.delta}</span>` : r.kind === "down" ? n`<span class="delta down">▼ ${r.delta}</span>` : r.kind === "new" ? n`<span class="delta new">NEW</span>` : r.kind === "same" ? n`<span class="delta same">—</span>` : n`<span class="delta same">·</span>`;
985
949
  }
986
950
  renderView() {
987
951
  const e = this.ctx, t = this.data.polls;
988
952
  if (!t.length) return n`<div class="view"><p class="empty">No ${this.sport} polls published yet this season.</p></div>`;
989
- const s = Math.max(0, t.findIndex((m) => m.effectiveDate === this.pollDate)), r = t[s] || t[0], o = t[s + 1] || null, l = t.slice().reverse(), i = l.indexOf(r), h = v(this.data.conferences), d = (r.teamIds || [])[0], c = d ? C(e, d) : null;
953
+ const s = Math.max(0, t.findIndex((m) => m.effectiveDate === this.pollDate)), r = t[s] || t[0], o = t[s + 1] || null, l = t.slice().reverse(), h = l.indexOf(r), d = b(this.data.conferences), i = (r.teamIds || [])[0], c = i ? I(e, i) : null;
990
954
  return n`
991
- ${Y(this, e, {
992
- title: n`${I(this.sport)} Top 25`,
955
+ ${j(this, e, {
956
+ title: n`${B(this.sport)} Top 25`,
993
957
  sub: n`The HighSchoolOT poll · updated weekly · ${t.length} polls this season`,
994
958
  teams: this.data.teams
995
959
  })}
996
- ${B(this, n`
997
- ${A(this)}
960
+ ${C(this, n`
961
+ ${D(this)}
998
962
  <div class="toolbar">
999
963
  <label class="asof" for="pollsel">Poll of</label>
1000
964
  <select id="pollsel" @change=${(m) => {
1001
965
  this.pollDate = m.target.value;
1002
966
  }}>
1003
967
  ${t.map((m, f) => n`<option value=${m.effectiveDate} ?selected=${m === r}>
1004
- ${$(m.effectiveDate, { month: "long", day: "numeric", year: "numeric" })}${f === 0 ? " · current" : ""}
968
+ ${w(m.effectiveDate, { month: "long", day: "numeric", year: "numeric" })}${f === 0 ? " · current" : ""}
1005
969
  </option>`)}
1006
970
  </select>
1007
971
  <button class="chip" ?disabled=${s >= t.length - 1}
@@ -1015,14 +979,14 @@ class Me extends w {
1015
979
  <span class="spacer"></span>
1016
980
  <span class="asof">Movement vs. the previous poll · sparkline = season rank history</span>
1017
981
  </div>
1018
- ${c ? this.renderHero(e, r, o, d, c, h) : p}
982
+ ${c ? this.renderHero(e, r, o, i, c, d) : p}
1019
983
  <div class="card"><div class="tablewrap"><table class="data">
1020
984
  <thead><tr>
1021
985
  <th class="num">Rk</th><th>Mvmt</th><th>Team</th><th class="num">Record</th>
1022
986
  <th>Conference</th><th>Last result</th><th>Next</th><th>Season</th>
1023
987
  </tr></thead>
1024
988
  <tbody>
1025
- ${(r.teamIds || []).map((m, f) => f === 0 || !m ? p : this.renderRow(e, r, o, l, i, h, m, f + 1))}
989
+ ${(r.teamIds || []).map((m, f) => f === 0 || !m ? p : this.renderRow(e, r, o, l, h, d, m, f + 1))}
1026
990
  </tbody>
1027
991
  </table></div></div>
1028
992
  <p class="note">Ranks elsewhere on the site resolve the poll in effect on the game date, so past box scores keep the ranks they were played under.</p>
@@ -1030,50 +994,50 @@ class Me extends w {
1030
994
  `;
1031
995
  }
1032
996
  renderHero(e, t, s, r, o, l) {
1033
- const i = e.records[r], h = se(e.records, r), d = l[e.teamsById[r]?.conferenceId], c = `linear-gradient(120deg, ${o.colorPrimary || "#030711"} 0%, var(--hsot-black) 85%)`;
997
+ const h = e.records[r], d = ae(e.records, r), i = l[e.teamsById[r]?.conferenceId], c = `linear-gradient(120deg, ${o.colorPrimary || "#030711"} 0%, var(--hsot-black) 85%)`;
1034
998
  return n`
1035
999
  <div class="hero1" style="background:${c}">
1036
1000
  <div class="bigrank">#1</div>
1037
- ${D(o, 64)}
1001
+ ${T(o, 64)}
1038
1002
  <div>
1039
1003
  <h2><a href=${g(e.hrefs.school, { id: o.id })}>${o.name} ${o.mascot || ""}</a></h2>
1040
1004
  <div class="facts">
1041
- ${k(i)} overall${d ? n` · ${k(i, !0)} ${d.name}` : p}
1042
- · streak ${H(i?.results) || "·"}
1043
- ${h ? n` · last: ${h.mark} ${h.my}-${h.their} vs ${N(e, h.opp)}` : p}
1005
+ ${k(h)} overall${i ? n` · ${k(h, !0)} ${i.name}` : p}
1006
+ · streak ${U(h?.results) || "·"}
1007
+ ${d ? n` · last: ${d.mark} ${d.my}-${d.their} vs ${G(e, d.opp)}` : p}
1044
1008
  &nbsp;${this.movement(t, s, r)}
1045
1009
  </div>
1046
1010
  </div>
1047
1011
  </div>
1048
1012
  `;
1049
1013
  }
1050
- renderRow(e, t, s, r, o, l, i, h) {
1051
- const d = C(e, i);
1052
- if (!d) return p;
1053
- const c = e.records[i], m = se(e.records, i), f = W(this.data.games, i), u = l[e.teamsById[i]?.conferenceId], b = () => {
1054
- location.href = g(e.hrefs.school, { id: d.id });
1014
+ renderRow(e, t, s, r, o, l, h, d) {
1015
+ const i = I(e, h);
1016
+ if (!i) return p;
1017
+ const c = e.records[h], m = ae(e.records, h), f = Y(this.data.games, h), u = l[e.teamsById[h]?.conferenceId], v = () => {
1018
+ location.href = g(e.hrefs.school, { id: i.id });
1055
1019
  };
1056
1020
  return n`
1057
1021
  <tr class="rowlink" @click=${(x) => {
1058
- x.target.closest("a") || b();
1022
+ x.target.closest("a") || v();
1059
1023
  }}>
1060
- <td class="num" style="font-weight:700">${h}</td>
1061
- <td>${this.movement(t, s, i)}</td>
1062
- <td class="teamcell">${D(d)}<a href=${g(e.hrefs.school, { id: d.id })}>${d.name}</a>
1063
- <span class="mut" style="font-size:0.78rem">${d.mascot || ""}</span></td>
1024
+ <td class="num" style="font-weight:700">${d}</td>
1025
+ <td>${this.movement(t, s, h)}</td>
1026
+ <td class="teamcell">${T(i)}<a href=${g(e.hrefs.school, { id: i.id })}>${i.name}</a>
1027
+ <span class="mut" style="font-size:0.78rem">${i.mascot || ""}</span></td>
1064
1028
  <td class="num">${k(c)}</td>
1065
1029
  <td class="mut">${u?.name || "Independent"}</td>
1066
1030
  <td>${m ? n`<a class="box" style="text-decoration:none" href=${g(e.hrefs.game, { sport: this.sport, id: m.gameId })}>
1067
1031
  <b style="color:${m.mark === "W" ? "var(--hsot-win)" : m.mark === "L" ? "var(--hsot-loss)" : "var(--hsot-tie)"}">${m.mark}</b>
1068
- ${m.my}-${m.their} vs ${N(e, m.opp)}</a>` : n`<span class="mut">·</span>`}</td>
1069
- <td>${ce(e, f, i)}</td>
1070
- <td>${this.sparkline(i, r, o)}</td>
1032
+ ${m.my}-${m.their} vs ${G(e, m.opp)}</a>` : n`<span class="mut">·</span>`}</td>
1033
+ <td>${pe(e, f, h)}</td>
1034
+ <td>${this.sparkline(h, r, o)}</td>
1071
1035
  </tr>
1072
1036
  `;
1073
1037
  }
1074
1038
  }
1075
- globalThis?.customElements && !globalThis.customElements.get("hsot-rankings") && globalThis.customElements.define("hsot-rankings", Me);
1076
- const He = y`
1039
+ globalThis?.customElements && !globalThis.customElements.get("hsot-rankings") && globalThis.customElements.define("hsot-rankings", je);
1040
+ const qe = $`
1077
1041
  .schoolhero { color: var(--hsot-white); padding: 1.6rem 1.25rem 1.3rem; }
1078
1042
  .schoolhero .inner { max-width: 1366px; margin: 0 auto; display: flex; gap: 1.2rem; align-items: center; flex-wrap: wrap; }
1079
1043
  .schoolhero .crest {
@@ -1127,10 +1091,10 @@ const He = y`
1127
1091
  table.data.roster .sub { display: block; font-weight: 400; font-size: 0.78rem; color: var(--hsot-gray-5); }
1128
1092
  }
1129
1093
  `;
1130
- class Oe extends w {
1131
- static styles = [...z, He];
1094
+ class We extends y {
1095
+ static styles = [...P, qe];
1132
1096
  static properties = {
1133
- ...w.properties,
1097
+ ...y.properties,
1134
1098
  schoolId: { type: String, attribute: "school-id" },
1135
1099
  sport: { type: String },
1136
1100
  season: { type: String },
@@ -1145,7 +1109,7 @@ class Oe extends w {
1145
1109
  e && !this.sport && (this.sport = e);
1146
1110
  }
1147
1111
  async fetchData(e) {
1148
- const t = this.season || M(), s = await e.getSchool(this.schoolId), o = (await e.listTeams({ schoolId: this.schoolId })).items, l = o.find((b) => b.sport === (this.sport || "football")) || o[0] || null, [i, h, d, c, m, f, u] = await Promise.all([
1112
+ const t = this.season || _(), s = await e.getSchool(this.schoolId), o = (await e.listTeams({ schoolId: this.schoolId })).items, l = o.find((v) => v.sport === (this.sport || "football")) || o[0] || null, [h, d, i, c, m, f, u] = await Promise.all([
1149
1113
  l ? e.listGames({ sport: l.sport, season: t }) : Promise.resolve({ items: [] }),
1150
1114
  l ? e.listTeams({ sport: l.sport }) : Promise.resolve({ items: [] }),
1151
1115
  e.listSchools(),
@@ -1161,22 +1125,22 @@ class Oe extends w {
1161
1125
  school: s,
1162
1126
  teams: o,
1163
1127
  active: l,
1164
- games: i.items,
1165
- allTeams: h.items,
1166
- schools: d.items,
1128
+ games: h.items,
1129
+ allTeams: d.items,
1130
+ schools: i.items,
1167
1131
  conferences: c.items,
1168
1132
  rankings: m.items,
1169
- roster: f.items.find((b) => b.season === t) || null,
1133
+ roster: f.items.find((v) => v.season === t) || null,
1170
1134
  players: u.items
1171
1135
  };
1172
1136
  }
1173
1137
  get ctx() {
1174
1138
  return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
1175
- teamsById: v(this.data.allTeams.length ? this.data.allTeams : this.data.teams),
1176
- schoolsById: v(this.data.schools),
1177
- records: P(this.data.games),
1139
+ teamsById: b(this.data.allTeams.length ? this.data.allTeams : this.data.teams),
1140
+ schoolsById: b(this.data.schools),
1141
+ records: N(this.data.games),
1178
1142
  rankings: this.data.rankings,
1179
- hrefs: F(this),
1143
+ hrefs: z(this),
1180
1144
  sport: this.data.active?.sport || "football"
1181
1145
  }, this._ctxData = this.data), this._ctx;
1182
1146
  }
@@ -1186,18 +1150,18 @@ class Oe extends w {
1186
1150
  renderView() {
1187
1151
  const { school: e, teams: t, active: s, season: r } = this.data;
1188
1152
  if (!e) return n`<div class="view"><p class="empty">School not found.</p></div>`;
1189
- const o = this.ctx, l = _(e.colorPrimary || "#030711"), i = (e.adm || [])[0], h = v(this.data.conferences), d = s ? h[s.conferenceId] : null;
1153
+ const o = this.ctx, l = M(e.colorPrimary || "#030711"), h = (e.adm || [])[0], d = b(this.data.conferences), i = s ? d[s.conferenceId] : null;
1190
1154
  return n`
1191
1155
  <div class="schoolhero" style="background:linear-gradient(115deg, ${e.colorPrimary || "#030711"} 0%, ${e.colorPrimary || "#030711"} 55%, var(--hsot-black) 100%);color:${l}">
1192
1156
  <div class="inner">
1193
- ${R(e, 84) ? n`<img class="crest logo" alt="" loading="lazy" src=${R(e, 84)} />` : n`<div class="crest" style="background:${e.colorSecondary || "#7C7C7C"};color:${_(e.colorSecondary || "#7C7C7C")}">${q(e)}</div>`}
1157
+ ${L(e, 84) ? n`<img class="crest logo" alt="" loading="lazy" src=${L(e, 84)} />` : n`<div class="crest" style="background:${e.colorSecondary || "#7C7C7C"};color:${M(e.colorSecondary || "#7C7C7C")}">${V(e)}</div>`}
1194
1158
  <div style="min-width:260px">
1195
1159
  <h1>${e.name} <span class="mascot">${e.mascot || ""}</span></h1>
1196
1160
  <div class="facts">
1197
1161
  ${e.location ? n`<span><b>Location</b>${e.location}${e.county ? n` · ${e.county} County` : p}</span>` : p}
1198
1162
  ${e.association ? n`<span><b>League</b>${e.association}${e.classification ? n` · ${e.classification}` : p}</span>` : p}
1199
- ${d ? n`<span><b>Conference</b>${d.name}</span>` : p}
1200
- ${i ? n`<span><b>Enrollment</b>${i.value.toLocaleString()} (${i.season} ADM)</span>` : p}
1163
+ ${i ? n`<span><b>Conference</b>${i.name}</span>` : p}
1164
+ ${h ? n`<span><b>Enrollment</b>${h.value.toLocaleString()} (${h.season} ADM)</span>` : p}
1201
1165
  ${e.openingYear ? n`<span><b>Opened</b>${e.openingYear}</span>` : p}
1202
1166
  ${e.areaCode ? n`<span><b>Area</b>${e.areaCode}</span>` : p}
1203
1167
  </div>
@@ -1211,24 +1175,24 @@ class Oe extends w {
1211
1175
  }}>${c.name}</a>`)}
1212
1176
  </nav>
1213
1177
  </div>
1214
- ${B(this, n`
1215
- ${A(this)}
1216
- ${s ? this.renderTeam(o, s, d, r) : n`<p class="empty">No teams recorded for this school yet.</p>`}
1178
+ ${C(this, n`
1179
+ ${D(this)}
1180
+ ${s ? this.renderTeam(o, s, i, r) : n`<p class="empty">No teams recorded for this school yet.</p>`}
1217
1181
  `)}
1218
1182
  `;
1219
1183
  }
1220
1184
  renderTeam(e, t, s, r) {
1221
- const o = e.records[t.id] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] }, l = o.w + o.l + o.t, i = s ? this.data.allTeams.filter((m) => m.conferenceId === s.id) : [], h = s ? ne(i, e.records).findIndex((m) => m.team.id === t.id) + 1 : 0, d = V(e.rankings, e.teamsById, t.id, t.sport, null), c = this.data.games.filter((m) => m.homeTeamId === t.id || m.awayTeamId === t.id).sort((m, f) => String(m.date).localeCompare(String(f.date)));
1185
+ const o = e.records[t.id] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] }, l = o.w + o.l + o.t, h = s ? this.data.allTeams.filter((m) => m.conferenceId === s.id) : [], d = s ? he(h, e.records).findIndex((m) => m.team.id === t.id) + 1 : 0, i = K(e.rankings, e.teamsById, t.id, t.sport, null), c = this.data.games.filter((m) => m.homeTeamId === t.id || m.awayTeamId === t.id).sort((m, f) => String(m.date).localeCompare(String(f.date)));
1222
1186
  return n`
1223
1187
  <div class="tiles">
1224
1188
  <div class="tile"><div class="k">Overall</div><div class="v">${k(o)}</div><div class="s">${l} games played</div></div>
1225
1189
  <div class="tile"><div class="k">${s?.name || "Conference"}</div><div class="v">${k(o, !0)}</div>
1226
- <div class="s">${h ? `${ye(h)} of ${i.length}` : "·"}</div></div>
1190
+ <div class="s">${d ? `${Se(d)} of ${h.length}` : "·"}</div></div>
1227
1191
  <div class="tile"><div class="k">Points</div><div class="v">${l ? (o.pf / l).toFixed(1) : "0.0"}</div>
1228
1192
  <div class="s">scored per game · ${l ? (o.pa / l).toFixed(1) : "0.0"} allowed</div></div>
1229
- <div class="tile"><div class="k">Streak</div><div class="v">${H(o.results) || "·"}</div>
1230
- <div class="s">last 5: ${K(e, t.id)}</div></div>
1231
- <div class="tile"><div class="k">HSOT Top 25</div><div class="v">${d ? `#${d}` : "NR"}</div>
1193
+ <div class="tile"><div class="k">Streak</div><div class="v">${U(o.results) || "·"}</div>
1194
+ <div class="s">last 5: ${X(e, t.id)}</div></div>
1195
+ <div class="tile"><div class="k">HSOT Top 25</div><div class="v">${i ? `#${i}` : "NR"}</div>
1232
1196
  <div class="s"><a href=${g(e.hrefs.section, { sport: t.sport, view: "rankings" })}>full poll</a></div></div>
1233
1197
  </div>
1234
1198
  ${(t.championships || []).length ? n`
@@ -1250,20 +1214,20 @@ class Oe extends w {
1250
1214
  `;
1251
1215
  }
1252
1216
  renderGameRow(e, t, s) {
1253
- const r = s.homeTeamId === t.id, o = r ? s.awayTeamId : s.homeTeamId, l = r ? s.homeScore : s.awayScore, i = r ? s.awayScore : s.homeScore;
1254
- let h = n`<span class="mut">${U(s.time)}</span>`;
1217
+ const r = s.homeTeamId === t.id, o = r ? s.awayTeamId : s.homeTeamId, l = r ? s.homeScore : s.awayScore, h = r ? s.awayScore : s.homeScore;
1218
+ let d = n`<span class="mut">${q(s.time)}</span>`;
1255
1219
  if (s.state === "final") {
1256
- const c = G(s), m = c === "tie" ? "T" : c === (r ? "home" : "away") ? "W" : "L";
1257
- h = n`<span class=${m}>${m}</span> ${l}-${i}${s.finish === "overtime" ? n` <span class="mut">OT</span>` : p}${s.forfeit && s.forfeit !== "none" ? n` <span class="mut">FF</span>` : p}`;
1258
- } else s.state === "live" && (h = n`<span style="color:var(--hsot-red)">${l}-${i}</span>`);
1259
- const d = s.gameType === "conference" ? "Conf" : s.gameType === "nonconference" ? "Non-conf" : s.gameType === "playoff" ? `Playoff${s.label ? ` · ${s.label}` : ""}` : "Scrimmage";
1220
+ const c = H(s), m = c === "tie" ? "T" : c === (r ? "home" : "away") ? "W" : "L";
1221
+ d = n`<span class=${m}>${m}</span> ${l}-${h}${s.finish === "overtime" ? n` <span class="mut">OT</span>` : p}${s.forfeit && s.forfeit !== "none" ? n` <span class="mut">FF</span>` : p}`;
1222
+ } else s.state === "live" && (d = n`<span style="color:var(--hsot-red)">${l}-${h}</span>`);
1223
+ const i = s.gameType === "conference" ? "Conf" : s.gameType === "nonconference" ? "Non-conf" : s.gameType === "playoff" ? `Playoff${s.label ? ` · ${s.label}` : ""}` : "Scrimmage";
1260
1224
  return n`
1261
1225
  <li>
1262
- <span class="d">${$(s.date)}</span>
1263
- ${re(s).kind === "sched" ? p : L(s)}
1264
- <span class="res">${h}</span>
1265
- <span class="opp">${r ? "vs" : "at"} ${le(e, o, s.date)}
1266
- <span class="pill type">${d}</span>
1226
+ <span class="d">${w(s.date)}</span>
1227
+ ${ce(s).kind === "sched" ? p : E(s)}
1228
+ <span class="res">${d}</span>
1229
+ <span class="opp">${r ? "vs" : "at"} ${O(e, o, s.date)}
1230
+ <span class="pill type">${i}</span>
1267
1231
  ${s.broadcast ? n`<span class="pill class">${s.broadcast}</span>` : p}
1268
1232
  </span>
1269
1233
  <span class="where">${s.venue || ""}</span>
@@ -1275,25 +1239,25 @@ class Oe extends w {
1275
1239
  const s = this.data.roster;
1276
1240
  if (!s)
1277
1241
  return n`<p class="empty">Roster not published for ${t}.</p>`;
1278
- const r = _e(s, 560), o = this.data.school?.name || "", l = v(this.data.players), i = s.entries.slice().sort((d, c) => (d.number || 0) - (c.number || 0)), h = i.some((d) => l[d.playerId]?.college);
1242
+ const r = Ge(s, 560), o = this.data.school?.name || "", l = b(this.data.players), h = s.entries.slice().sort((i, c) => (i.number || 0) - (c.number || 0)), d = h.some((i) => l[i.playerId]?.college);
1279
1243
  return n`
1280
1244
  ${r ? n`<img class="rosterphoto" src=${r} loading="lazy" decoding="async"
1281
1245
  alt="${o} ${e.name} ${t} team photo" />` : p}
1282
1246
  <div class="tablewrap"><table class="data roster">
1283
- <thead><tr><th class="num">No.</th><th>Player</th><th class="pos">Pos</th><th class="cls">Class</th><th class="num">Ht</th><th class="num">Wt</th>${h ? n`<th>College</th>` : p}</tr></thead>
1247
+ <thead><tr><th class="num">No.</th><th>Player</th><th class="pos">Pos</th><th class="cls">Class</th><th class="num">Ht</th><th class="num">Wt</th>${d ? n`<th>College</th>` : p}</tr></thead>
1284
1248
  <tbody>
1285
- ${i.map((d) => {
1286
- const c = l[d.playerId];
1249
+ ${h.map((i) => {
1250
+ const c = l[i.playerId];
1287
1251
  if (!c) return p;
1288
- const m = ve(d), f = [m, c.classOf].filter(Boolean).join(" · ") || "·";
1252
+ const m = xe(i), f = [m, c.classOf].filter(Boolean).join(" · ") || "·";
1289
1253
  return n`<tr>
1290
- <td class="num mut">${d.number ?? "·"}</td>
1254
+ <td class="num mut">${i.number ?? "·"}</td>
1291
1255
  <td class="player" style="font-weight:500">${c.firstName} ${c.lastName}<span class="sub">${f}</span></td>
1292
1256
  <td class="pos">${m || "·"}</td>
1293
1257
  <td class="cls mut">${c.classOf || "·"}</td>
1294
- <td class="num">${ge(c.heightIn)}</td>
1258
+ <td class="num">${we(c.heightIn)}</td>
1295
1259
  <td class="num">${c.weightLb || "·"}</td>
1296
- ${h ? n`<td class="college">${c.college || "·"}</td>` : p}
1260
+ ${d ? n`<td class="college">${c.college || "·"}</td>` : p}
1297
1261
  </tr>`;
1298
1262
  })}
1299
1263
  </tbody>
@@ -1301,8 +1265,8 @@ class Oe extends w {
1301
1265
  `;
1302
1266
  }
1303
1267
  }
1304
- globalThis?.customElements && !globalThis.customElements.get("hsot-school") && globalThis.customElements.define("hsot-school", Oe);
1305
- const de = {
1268
+ globalThis?.customElements && !globalThis.customElements.get("hsot-school") && globalThis.customElements.define("hsot-school", We);
1269
+ const fe = {
1306
1270
  football: ["quarters", 4],
1307
1271
  flag_football: ["quarters", 4],
1308
1272
  basketball: ["quarters", 4],
@@ -1313,57 +1277,57 @@ const de = {
1313
1277
  softball: ["innings", 7],
1314
1278
  volleyball: ["sets", 3]
1315
1279
  };
1316
- function he(a) {
1317
- return (de[a] || ["quarters", 4])[0];
1280
+ function ue(a) {
1281
+ return (fe[a] || ["quarters", 4])[0];
1318
1282
  }
1319
- function X(a) {
1320
- return (de[a] || ["quarters", 4])[1];
1283
+ function Z(a) {
1284
+ return (fe[a] || ["quarters", 4])[1];
1321
1285
  }
1322
- function Ue(a, e) {
1323
- const t = he(a), s = X(a);
1286
+ function Ve(a, e) {
1287
+ const t = ue(a), s = Z(a);
1324
1288
  if (e <= s || t === "innings" || t === "sets") return String(e);
1325
1289
  const r = e - s;
1326
1290
  return `OT${r > 1 ? r : ""}`;
1327
1291
  }
1328
- function je(a, e) {
1292
+ function Ye(a, e) {
1329
1293
  const t = String(a ?? "").trim();
1330
1294
  let s;
1331
- return (s = /^(\d+)Q$/i.exec(t)) || (s = /^(\d+)H$/i.exec(t)) ? Number(s[1]) : /^half$/i.test(t) ? he(e) === "halves" ? 1 : 2 : (s = /^(\d*)OT(\d*)$/i.exec(t)) ? X(e) + Number(s[1] || s[2] || 1) : (s = /^[TB](\d+)$/i.exec(t)) || (s = /^(\d+)(?:st|nd|rd|th)\s*set$/i.exec(t)) || (s = /^set\s*(\d+)$/i.exec(t)) ? Number(s[1]) : null;
1295
+ return (s = /^(\d+)Q$/i.exec(t)) || (s = /^(\d+)H$/i.exec(t)) ? Number(s[1]) : /^half$/i.test(t) ? ue(e) === "halves" ? 1 : 2 : (s = /^(\d*)OT(\d*)$/i.exec(t)) ? Z(e) + Number(s[1] || s[2] || 1) : (s = /^[TB](\d+)$/i.exec(t)) || (s = /^(\d+)(?:st|nd|rd|th)\s*set$/i.exec(t)) || (s = /^set\s*(\d+)$/i.exec(t)) ? Number(s[1]) : null;
1332
1296
  }
1333
- const E = (a) => Number.isInteger(a) && a >= 0 ? a : null;
1334
- function qe(a) {
1297
+ const R = (a) => Number.isInteger(a) && a >= 0 ? a : null;
1298
+ function Ke(a) {
1335
1299
  const e = Array.isArray(a?.scoringPlays) ? a.scoringPlays : [];
1336
1300
  if (!e.length) return null;
1337
1301
  const t = a.sport, s = /* @__PURE__ */ new Map();
1338
1302
  for (const m of e) {
1339
- const f = je(m?.period, t), u = E(m?.homeScore), b = E(m?.awayScore);
1340
- if (!f || u === null || b === null) return null;
1303
+ const f = Ye(m?.period, t), u = R(m?.homeScore), v = R(m?.awayScore);
1304
+ if (!f || u === null || v === null) return null;
1341
1305
  const x = s.get(f) || { home: 0, away: 0 };
1342
- x.home = Math.max(x.home, u), x.away = Math.max(x.away, b), s.set(f, x);
1306
+ x.home = Math.max(x.home, u), x.away = Math.max(x.away, v), s.set(f, x);
1343
1307
  }
1344
1308
  const r = Math.max(...s.keys()), o = [];
1345
- let l = !0, i = { home: 0, away: 0 };
1309
+ let l = !0, h = { home: 0, away: 0 };
1346
1310
  for (let m = 1; m <= r; m += 1) {
1347
- const f = s.get(m) || i, u = f.home - i.home, b = f.away - i.away;
1348
- (u < 0 || b < 0) && (l = !1), o.push({ period: m, home: Math.max(u, 0), away: Math.max(b, 0) }), i = { home: Math.max(f.home, i.home), away: Math.max(f.away, i.away) };
1311
+ const f = s.get(m) || h, u = f.home - h.home, v = f.away - h.away;
1312
+ (u < 0 || v < 0) && (l = !1), o.push({ period: m, home: Math.max(u, 0), away: Math.max(v, 0) }), h = { home: Math.max(f.home, h.home), away: Math.max(f.away, h.away) };
1349
1313
  }
1350
- const h = E(a.homeScore) ?? 0, d = E(a.awayScore) ?? 0, c = l && i.home === h && i.away === d;
1351
- return l = l && i.home <= h && i.away <= d, { periods: o, reconciled: c, consistent: l };
1314
+ const d = R(a.homeScore) ?? 0, i = R(a.awayScore) ?? 0, c = l && h.home === d && h.away === i;
1315
+ return l = l && h.home <= d && h.away <= i, { periods: o, reconciled: c, consistent: l };
1352
1316
  }
1353
- function Ge(a) {
1317
+ function Qe(a) {
1354
1318
  if (Array.isArray(a?.periodScores) && a.periodScores.length) return a.periodScores;
1355
- const e = qe(a);
1319
+ const e = Ke(a);
1356
1320
  return e ? a.state === "final" ? e.reconciled ? e.periods : null : e.consistent ? e.periods : null : null;
1357
1321
  }
1358
- const We = "https://api.wral.com/search";
1359
- function Ve(a) {
1322
+ const Xe = "https://api.wral.com/search";
1323
+ function Ze(a) {
1360
1324
  return a.map((e) => `uri:"${e}"`).join(" OR ");
1361
1325
  }
1362
- function Ye(a, e) {
1363
- const t = String(a || We).replace(/\/+$/, ""), s = new URLSearchParams({ query: Ve(e), sort: "score", lang: "en" });
1326
+ function Je(a, e) {
1327
+ const t = String(a || Xe).replace(/\/+$/, ""), s = new URLSearchParams({ query: Ze(e), sort: "score", lang: "en" });
1364
1328
  return `${t}/v1/query?${s}`;
1365
1329
  }
1366
- function me(a) {
1330
+ function ge(a) {
1367
1331
  try {
1368
1332
  const e = new URL(a);
1369
1333
  if (/(^|\.)smugmug\.com$/i.test(e.hostname)) {
@@ -1378,13 +1342,13 @@ function me(a) {
1378
1342
  }
1379
1343
  return { uri: a, title: a };
1380
1344
  }
1381
- async function Qe(a, e, t) {
1382
- const r = await ((...i) => fetch(...i))(Ye(a, e));
1345
+ async function et(a, e, t) {
1346
+ const r = await ((...h) => fetch(...h))(Je(a, e));
1383
1347
  if (!r.ok) throw new Error(`search answered ${r.status}`);
1384
- const o = await r.json(), l = new Map((o.items || []).map((i) => [i.uri, i]));
1385
- return e.map((i) => l.get(i) || me(i));
1348
+ const o = await r.json(), l = new Map((o.items || []).map((h) => [h.uri, h]));
1349
+ return e.map((h) => l.get(h) || ge(h));
1386
1350
  }
1387
- const Ke = y`
1351
+ const tt = $`
1388
1352
  .breadcrumbs { font-size: 0.8125rem; margin: 0.9rem 0 0; color: var(--hsot-gray-5); }
1389
1353
  .breadcrumbs a { text-decoration: none; }
1390
1354
  .scorehead { display: grid; grid-template-columns: 1fr auto 1fr; gap: 1rem; align-items: center; padding: 1.4rem 1rem; }
@@ -1427,6 +1391,9 @@ const Ke = y`
1427
1391
  table.plays-table td.play { white-space: normal; min-width: 12rem; }
1428
1392
  /* Game notes are typed with line breaks the desk means to keep. */
1429
1393
  .gamenote { padding: 0 1rem 0.9rem; text-align: center; white-space: pre-line; }
1394
+ /* The embed's way out to everything it drops (Coverage, season context,
1395
+ head to head) — the data page still renders all of it. */
1396
+ .fullbox { margin: 0.9rem 0 0; text-align: center; font-size: 0.875rem; }
1430
1397
  .cols { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
1431
1398
  .ctxcard { padding: 0.85rem 1rem; }
1432
1399
  .ctxcard .who { font-family: var(--hsot-heading-font); font-weight: 700; margin-bottom: 0.4rem; }
@@ -1437,22 +1404,28 @@ const Ke = y`
1437
1404
  .cols { grid-template-columns: 1fr; }
1438
1405
  }
1439
1406
  `;
1440
- class Xe extends w {
1441
- static styles = [...z, Ke];
1407
+ class st extends y {
1408
+ static styles = [...P, tt];
1442
1409
  static properties = {
1443
- ...w.properties,
1410
+ ...y.properties,
1444
1411
  gameId: { type: String, attribute: "game-id" },
1445
1412
  // The public site search that resolves Game.coverageUrls into cards
1446
1413
  // (DEV-1236). Shared cross-stage by design — see the studio host's
1447
1414
  // registry — so the prod default is right everywhere; the attribute
1448
1415
  // exists for the same reason the href templates do.
1449
- searchApi: { type: String, attribute: "search-api" }
1416
+ searchApi: { type: String, attribute: "search-api" },
1417
+ // Story pages embed the box score in the article column, where the page
1418
+ // chrome (breadcrumbs, the report-a-score line) and the cross-links
1419
+ // (Coverage, Season context, head-to-head) belong to the data page, not
1420
+ // the recap. `embed` keeps the score head, line score and scoring plays,
1421
+ // and links out to the full box score for the rest.
1422
+ embed: { type: Boolean }
1450
1423
  };
1451
1424
  constructor() {
1452
- super(), this.gameId = "", this.searchApi = "";
1425
+ super(), this.gameId = "", this.searchApi = "", this.embed = !1;
1453
1426
  }
1454
1427
  async fetchData(e) {
1455
- const t = await e.getGame(this.gameId), s = Array.isArray(t.coverageUrls) ? t.coverageUrls : [], [r, o, l, i, h, d] = await Promise.all([
1428
+ const t = await e.getGame(this.gameId), s = Array.isArray(t.coverageUrls) ? t.coverageUrls : [], [r, o, l, h, d, i] = await Promise.all([
1456
1429
  e.listSchools(),
1457
1430
  e.listTeams({ sport: t.sport }),
1458
1431
  e.listConferences(),
@@ -1460,57 +1433,64 @@ class Xe extends w {
1460
1433
  e.listGames({ sport: t.sport, season: t.season }),
1461
1434
  // A search outage must not blank the box score — degrade to bare
1462
1435
  // links (fetchCoverage already degrades per-URL index misses).
1463
- s.length ? Qe(this.searchApi, s).catch(() => s.map(me)) : Promise.resolve([])
1436
+ // The embed drops the Coverage grid, so it skips the search
1437
+ // round-trip entirely rather than fetching cards it will not render.
1438
+ s.length && !this.embed ? et(this.searchApi, s).catch(() => s.map(ge)) : Promise.resolve([])
1464
1439
  ]);
1465
1440
  return {
1466
1441
  game: t,
1467
1442
  schools: r.items,
1468
1443
  teams: o.items,
1469
1444
  conferences: l.items,
1470
- rankings: i.items,
1471
- games: h.items,
1472
- coverage: d
1445
+ rankings: h.items,
1446
+ games: d.items,
1447
+ coverage: i
1473
1448
  };
1474
1449
  }
1475
1450
  get ctx() {
1476
1451
  return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
1477
- teamsById: v(this.data.teams),
1478
- schoolsById: v(this.data.schools),
1479
- records: P(this.data.games),
1452
+ teamsById: b(this.data.teams),
1453
+ schoolsById: b(this.data.schools),
1454
+ records: N(this.data.games),
1480
1455
  rankings: this.data.rankings,
1481
- hrefs: F(this),
1456
+ hrefs: z(this),
1482
1457
  sport: this.data.game.sport
1483
1458
  }, this._ctxData = this.data), this._ctx;
1484
1459
  }
1485
1460
  renderView() {
1486
1461
  const e = this.data.game;
1487
1462
  if (!e) return n`<div class="view"><p class="empty">Game not found.</p></div>`;
1488
- const t = this.ctx, s = v(this.data.conferences), r = t.teamsById[e.awayTeamId] ? t.schoolsById[t.teamsById[e.awayTeamId].schoolId] : null, o = t.teamsById[e.homeTeamId] ? t.schoolsById[t.teamsById[e.homeTeamId].schoolId] : null, l = G(e), i = (c) => e.state === "final" && l !== c && l !== "tie" ? "opacity:0.45" : "", h = e.conferenceId ? s[e.conferenceId] : null, d = this.data.games.filter((c) => c.id !== e.id && c.state === "final" && c.gameType !== "scrimmage" && (c.homeTeamId === e.homeTeamId && c.awayTeamId === e.awayTeamId || c.homeTeamId === e.awayTeamId && c.awayTeamId === e.homeTeamId));
1463
+ const t = this.ctx, s = b(this.data.conferences), r = t.teamsById[e.awayTeamId] ? t.schoolsById[t.teamsById[e.awayTeamId].schoolId] : null, o = t.teamsById[e.homeTeamId] ? t.schoolsById[t.teamsById[e.homeTeamId].schoolId] : null, l = H(e), h = (c) => e.state === "final" && l !== c && l !== "tie" ? "opacity:0.45" : "", d = e.conferenceId ? s[e.conferenceId] : null, i = this.data.games.filter((c) => c.id !== e.id && c.state === "final" && c.gameType !== "scrimmage" && (c.homeTeamId === e.homeTeamId && c.awayTeamId === e.awayTeamId || c.homeTeamId === e.awayTeamId && c.awayTeamId === e.homeTeamId));
1489
1464
  return n`
1490
- ${B(this, n`
1491
- ${A(this)}
1492
- <p class="breadcrumbs">
1493
- <a href=${g(t.hrefs.section, { sport: e.sport, view: "scores" })}>${I(e.sport)}</a> /
1494
- <a href=${g(t.hrefs.section, { sport: e.sport, view: "scores" })}>Scores/Schedules</a> /
1495
- ${T(t, e.awayTeamId)} at ${T(t, e.homeTeamId)}
1496
- </p>
1465
+ ${C(this, n`
1466
+ ${D(this)}
1467
+ ${this.embed ? p : n`
1468
+ <p class="breadcrumbs">
1469
+ <a href=${g(t.hrefs.section, { sport: e.sport, view: "scores" })}>${B(e.sport)}</a> /
1470
+ <a href=${g(t.hrefs.section, { sport: e.sport, view: "scores" })}>Scores/Schedules</a> /
1471
+ ${F(t, e.awayTeamId)} at ${F(t, e.homeTeamId)}
1472
+ </p>`}
1497
1473
  <div class="card">
1498
1474
  <div class="scorehead">
1499
1475
  ${this.teamBlock(t, e, e.awayTeamId, r, !1)}
1500
1476
  <div class="mid">
1501
1477
  <div class="bigscore">
1502
- <span style=${i("away")}>${e.awayScore}</span>
1478
+ <span style=${h("away")}>${e.awayScore}</span>
1503
1479
  <span class="mut" style="font-size:1.6rem">–</span>
1504
- <span style=${i("home")}>${e.homeScore}</span>
1480
+ <span style=${h("home")}>${e.homeScore}</span>
1505
1481
  </div>
1506
- <div class="status">${L(e)}</div>
1507
- <div class="status">${$(e.date, { weekday: "short", month: "short", day: "numeric", year: "numeric" })}${e.state === "scheduled" && e.time ? n` · ${U(e.time)}` : p} · ${e.venue || "Venue TBD"}
1482
+ <div class="status">${E(e)}</div>
1483
+ <div class="status">${w(e.date, { weekday: "short", month: "short", day: "numeric", year: "numeric" })}${e.state === "scheduled" && e.time ? n` · ${q(e.time)}` : p} · ${e.venue || "Venue TBD"}
1508
1484
  ${e.broadcast ? n` · <span class="pill class">${e.broadcast}</span>` : p}</div>
1509
1485
  <div class="status">
1510
- <span class="pill type">${e.gameType === "conference" ? `${h?.name || "Conference"} game` : e.gameType}</span>
1486
+ <span class="pill type">${e.gameType === "conference" ? `${d?.name || "Conference"} game` : e.gameType}</span>
1511
1487
  ${e.label ? n`<span class="pill type">Bracket ${e.label}</span>` : p}
1512
1488
  ${(e.tags || []).map((c) => n`<span class="pill type">${c}</span>`)}
1513
1489
  </div>
1490
+ ${this.embed ? p : n`
1491
+ <div class="status">
1492
+ <a href=${le(t.hrefs, e.id)}>Report a score for this game</a>
1493
+ </div>`}
1514
1494
  </div>
1515
1495
  ${this.teamBlock(t, e, e.homeTeamId, o, !0)}
1516
1496
  </div>
@@ -1518,6 +1498,10 @@ class Xe extends w {
1518
1498
  ${this.renderScoringPlays(e, r, o)}
1519
1499
  ${e.notes ? n`<p class="note gamenote">${e.notes}</p>` : p}
1520
1500
  </div>
1501
+ ${this.embed ? n`
1502
+ <p class="fullbox">
1503
+ <a href=${g(t.hrefs.game, { sport: e.sport, id: e.id })}>Full box score &rarr;</a>
1504
+ </p>` : n`
1521
1505
  ${(this.data.coverage || []).length ? n`
1522
1506
  <div class="section-title">Coverage</div>
1523
1507
  <div class="covgrid">
@@ -1538,51 +1522,51 @@ class Xe extends w {
1538
1522
  <div class="cols">
1539
1523
  ${[[e.awayTeamId, r], [e.homeTeamId, o]].map(([c, m]) => this.renderContext(t, c, m))}
1540
1524
  </div>
1541
- ${d.length ? n`
1525
+ ${i.length ? n`
1542
1526
  <div class="section-title">Head to head this season</div>
1543
1527
  <div class="card"><ul class="gamelist">
1544
- ${d.map((c) => n`<li>
1545
- <span class="d">${$(c.date)}</span>${L(c)}
1546
- <span class="opp">${T(t, c.awayTeamId)} ${c.awayScore}, ${T(t, c.homeTeamId)} ${c.homeScore}</span>
1528
+ ${i.map((c) => n`<li>
1529
+ <span class="d">${w(c.date)}</span>${E(c)}
1530
+ <span class="opp">${F(t, c.awayTeamId)} ${c.awayScore}, ${F(t, c.homeTeamId)} ${c.homeScore}</span>
1547
1531
  <a class="box" href=${g(t.hrefs.game, { sport: e.sport, id: c.id })}>Box score →</a>
1548
1532
  </li>`)}
1549
- </ul></div>` : p}
1533
+ </ul></div>` : p}`}
1550
1534
  `)}
1551
1535
  `;
1552
1536
  }
1553
1537
  teamBlock(e, t, s, r, o) {
1554
1538
  if (!r) return n`<div class="teamblock ${o ? "right" : ""}"><div class="tname">TBD</div></div>`;
1555
- const l = e.teamsById[s], i = e.records[s], h = R(r, 58);
1539
+ const l = e.teamsById[s], h = e.records[s], d = L(r, 58);
1556
1540
  return n`
1557
1541
  <div class="teamblock ${o ? "right" : ""}">
1558
- ${h ? n`<img class="crest logo" alt="" loading="lazy" src=${h} />` : n`<span class="crest" style="background:${r.colorPrimary || "#030711"};color:${_(r.colorPrimary || "#030711")}">${q(r)}</span>`}
1542
+ ${d ? n`<img class="crest logo" alt="" loading="lazy" src=${d} />` : n`<span class="crest" style="background:${r.colorPrimary || "#030711"};color:${M(r.colorPrimary || "#030711")}">${V(r)}</span>`}
1559
1543
  <div>
1560
1544
  <div class="tname">${Q(e, s, t.date)}<a href=${g(e.hrefs.school, { id: r.id })}>${r.name}</a></div>
1561
- <div class="trec">${r.mascot || ""} · ${k(i)}${l?.conferenceId ? n` · ${k(i, !0)} conf` : p}</div>
1545
+ <div class="trec">${r.mascot || ""} · ${k(h)}${l?.conferenceId ? n` · ${k(h, !0)} conf` : p}</div>
1562
1546
  </div>
1563
1547
  </div>
1564
1548
  `;
1565
1549
  }
1566
1550
  renderLineScore(e, t, s) {
1567
- const r = Ge(e);
1551
+ const r = Qe(e);
1568
1552
  if (!r)
1569
1553
  return e.state === "scheduled" ? n`<p class="empty" style="text-align:center">Period scoring will appear once the game starts.</p>` : p;
1570
- const o = Math.max(X(e.sport), ...r.map((d) => d.period)), l = (d) => Ue(e.sport, d), i = (d, c) => {
1554
+ const o = Math.max(Z(e.sport), ...r.map((i) => i.period)), l = (i) => Ve(e.sport, i), h = (i, c) => {
1571
1555
  const m = r.find((f) => f.period === c);
1572
- return m ? m[d] : e.state === "final" ? 0 : "·";
1573
- }, h = (d, c, m) => n`
1556
+ return m ? m[i] : e.state === "final" ? 0 : "·";
1557
+ }, d = (i, c, m) => n`
1574
1558
  <tr>
1575
- <td class="teamcell">${D(d, 20)}${d?.abbr || "TBD"}</td>
1576
- ${Array.from({ length: o }, (f, u) => n`<td class="num">${i(c, u + 1)}</td>`)}
1559
+ <td class="teamcell">${T(i, 20)}${i?.abbr || "TBD"}</td>
1560
+ ${Array.from({ length: o }, (f, u) => n`<td class="num">${h(c, u + 1)}</td>`)}
1577
1561
  <td class="num" style="font-weight:700">${m}</td>
1578
1562
  </tr>`;
1579
1563
  return n`
1580
1564
  <div class="tablewrap" style="border-top:1px solid var(--hsot-gray-2)">
1581
1565
  <table class="data" style="max-width:560px;margin:0.6rem auto 0.9rem">
1582
- <thead><tr><th>Team</th>${Array.from({ length: o }, (d, c) => n`<th class="num">${l(c + 1)}</th>`)}<th class="num">T</th></tr></thead>
1566
+ <thead><tr><th>Team</th>${Array.from({ length: o }, (i, c) => n`<th class="num">${l(c + 1)}</th>`)}<th class="num">T</th></tr></thead>
1583
1567
  <tbody>
1584
- ${h(t, "away", e.awayScore)}
1585
- ${h(s, "home", e.homeScore)}
1568
+ ${d(t, "away", e.awayScore)}
1569
+ ${d(s, "home", e.homeScore)}
1586
1570
  </tbody>
1587
1571
  </table>
1588
1572
  </div>
@@ -1616,24 +1600,24 @@ class Xe extends w {
1616
1600
  }
1617
1601
  renderContext(e, t, s) {
1618
1602
  if (!s) return p;
1619
- const r = e.records[t], o = W(this.data.games, t);
1603
+ const r = e.records[t], o = Y(this.data.games, t);
1620
1604
  return n`
1621
1605
  <div class="card ctxcard">
1622
- <div class="who">${D(s)}${s.name}</div>
1606
+ <div class="who">${T(s)}${s.name}</div>
1623
1607
  <div class="row">
1624
- <span>Last 5: ${K(e, t)}</span>
1625
- <span>Streak: <b>${r ? H(r.results) : "·"}</b></span>
1608
+ <span>Last 5: ${X(e, t)}</span>
1609
+ <span>Streak: <b>${r ? U(r.results) : "·"}</b></span>
1626
1610
  <span>PF/PA: <b>${r ? `${r.pf} / ${r.pa}` : "·"}</b></span>
1627
- <span>Next: ${o ? n`${$(o.date, { month: "numeric", day: "numeric" })}
1628
- ${o.homeTeamId === t ? "vs" : "at"} ${N(e, o.homeTeamId === t ? o.awayTeamId : o.homeTeamId)}` : "·"}</span>
1611
+ <span>Next: ${o ? n`${w(o.date, { month: "numeric", day: "numeric" })}
1612
+ ${o.homeTeamId === t ? "vs" : "at"} ${G(e, o.homeTeamId === t ? o.awayTeamId : o.homeTeamId)}` : "·"}</span>
1629
1613
  </div>
1630
1614
  </div>
1631
1615
  `;
1632
1616
  }
1633
1617
  }
1634
- globalThis?.customElements && !globalThis.customElements.get("hsot-boxscore") && globalThis.customElements.define("hsot-boxscore", Xe);
1635
- const Ze = 250, Je = 2;
1636
- class et extends ae {
1618
+ globalThis?.customElements && !globalThis.customElements.get("hsot-boxscore") && globalThis.customElements.define("hsot-boxscore", st);
1619
+ const at = 250, rt = 2;
1620
+ class ot extends ie {
1637
1621
  static properties = {
1638
1622
  api: { type: String },
1639
1623
  schoolHref: { type: String, attribute: "school-href" },
@@ -1644,7 +1628,7 @@ class et extends ae {
1644
1628
  activeIndex: { state: !0 },
1645
1629
  searched: { state: !0 }
1646
1630
  };
1647
- static styles = y`
1631
+ static styles = $`
1648
1632
  :host {
1649
1633
  display: block;
1650
1634
  position: relative;
@@ -1713,11 +1697,11 @@ class et extends ae {
1713
1697
  }
1714
1698
  onInput(e) {
1715
1699
  const t = e.target.value.trim();
1716
- if (clearTimeout(this.debounceTimer), t.length < Je) {
1700
+ if (clearTimeout(this.debounceTimer), t.length < rt) {
1717
1701
  this.abortController?.abort(), this.results = [], this.open = !1, this.searched = !1;
1718
1702
  return;
1719
1703
  }
1720
- this.debounceTimer = setTimeout(() => this.search(t), Ze);
1704
+ this.debounceTimer = setTimeout(() => this.search(t), at);
1721
1705
  }
1722
1706
  async search(e) {
1723
1707
  this.abortController?.abort(), this.abortController = new AbortController();
@@ -1810,23 +1794,309 @@ class et extends ae {
1810
1794
  `;
1811
1795
  }
1812
1796
  }
1813
- globalThis?.customElements && !globalThis.customElements.get("hsot-school-search") && globalThis.customElements.define("hsot-school-search", et);
1797
+ globalThis?.customElements && !globalThis.customElements.get("hsot-school-search") && globalThis.customElements.define("hsot-school-search", ot);
1798
+ function ve(a, e) {
1799
+ const t = new Map(a.map((d) => [d.id, d])), s = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
1800
+ for (const d of e || [])
1801
+ d.outcome === "winner" && (s.has(d.targetGameId) || s.set(d.targetGameId, []), s.get(d.targetGameId).push(d), r.has(d.sourceGameId) || r.set(d.sourceGameId, []), r.get(d.sourceGameId).push(d));
1802
+ const o = a.filter((d) => !r.has(d.id)), l = (d) => d.targetSlot === "home" ? 0 : 1;
1803
+ function h(d) {
1804
+ const i = t.get(d);
1805
+ if (!i) return null;
1806
+ const m = [...s.get(d) || []].sort((f, u) => l(f) - l(u)).map((f) => h(f.sourceGameId)).filter(Boolean);
1807
+ return { game: i, children: m, bracketGroup: i.bracketGroup };
1808
+ }
1809
+ return o.length === 1 ? h(o[0].id) : o.map((d) => h(d.id));
1810
+ }
1811
+ function be(a, e = [], t = 0) {
1812
+ if (!a) return e;
1813
+ e[t] || (e[t] = []), e[t].push(a.game);
1814
+ for (const s of a.children || []) be(s, e, t + 1);
1815
+ return e;
1816
+ }
1817
+ const nt = (a) => Math.max(1, Math.round(Math.log2(a || 2)));
1818
+ function it({ round: a, perGroup: e, groupCount: t = 1 }) {
1819
+ const s = nt(e), o = (t === 4 ? s + 2 : t === 2 ? s + 1 : s) - a;
1820
+ return o === 0 ? t > 1 ? "Championship" : "Final" : o === 1 ? "Semifinal" : `Round ${a}`;
1821
+ }
1822
+ function lt(a) {
1823
+ if (!a || !a.length) return "setup";
1824
+ const e = Math.max(...a.map((s) => s.round ?? 0)), t = a.filter((s) => (s.round ?? 0) === e);
1825
+ return t.length && t.every((s) => s.state === "final") ? "complete" : a.some((s) => s.state !== "scheduled" || s.homeScore || s.awayScore || s.round === 1 && (s.homeTeamId || s.awayTeamId)) ? "active" : "setup";
1826
+ }
1827
+ function ct(a, e) {
1828
+ const t = a?.groupNames || [];
1829
+ if (t.length >= 2) {
1830
+ const r = t.map((o) => ({ key: o, name: o }));
1831
+ return (e || []).some((o) => o.bracketGroup === "Championship") && r.push({ key: "Championship", name: "Championship" }), r;
1832
+ }
1833
+ const s = [...new Set((e || []).map((r) => r.bracketGroup).filter(Boolean))];
1834
+ return [{ key: null, name: s.length === 1 ? s[0] : "Bracket" }];
1835
+ }
1836
+ const dt = (a, e) => e?.key == null ? [...a || []] : (a || []).filter((t) => t.bracketGroup === e.key), re = (a) => {
1837
+ const e = /(\d+)\s*$/.exec(a.label || "");
1838
+ return e ? Number(e[1]) : 1 / 0;
1839
+ }, oe = (a, e) => re(a) - re(e) || String(a.id).localeCompare(String(e.id));
1840
+ function ht(a, e) {
1841
+ if (a.every((r) => Number.isInteger(r.round))) return (r) => r.round;
1842
+ const t = ve(a, e), s = /* @__PURE__ */ new Map();
1843
+ for (const r of Array.isArray(t) ? t : [t]) {
1844
+ const o = be(r), l = o.length - 1;
1845
+ o.forEach((h, d) => h.forEach((i) => s.set(i.id, l - d + 1)));
1846
+ }
1847
+ return (r) => Number.isInteger(r.round) ? r.round : s.get(r.id) || 1;
1848
+ }
1849
+ function mt(a, e, t) {
1850
+ const s = dt(a, t);
1851
+ if (!s.length) return [];
1852
+ const r = ht(a || [], e || []), o = /* @__PURE__ */ new Map();
1853
+ for (const i of s) {
1854
+ const c = r(i);
1855
+ o.has(c) || o.set(c, []), o.get(c).push(i);
1856
+ }
1857
+ const l = /* @__PURE__ */ new Map();
1858
+ for (const i of e || [])
1859
+ i.outcome === "winner" && (l.has(i.targetGameId) || l.set(i.targetGameId, []), l.get(i.targetGameId).push(i.sourceGameId));
1860
+ const h = [];
1861
+ let d = null;
1862
+ for (const i of [...o.keys()].sort((c, m) => c - m)) {
1863
+ let c = [...o.get(i)];
1864
+ if (d) {
1865
+ const m = (f) => {
1866
+ const u = (l.get(f.id) || []).map((v) => d.get(v)).filter((v) => v !== void 0);
1867
+ return u.length ? Math.min(...u) : 1 / 0;
1868
+ };
1869
+ c.sort((f, u) => m(f) - m(u) || oe(f, u));
1870
+ } else
1871
+ c.sort(oe);
1872
+ d = new Map(c.map((m, f) => [m.id, f])), h.push({ round: i, games: c });
1873
+ }
1874
+ return h;
1875
+ }
1876
+ function pt(a, e, t) {
1877
+ const s = a[`${e}TeamId`] || null, r = (t || []).find((l) => l.gameId === a.id && l.slot === e), o = a[`${e}Seed`] ?? r?.seed ?? null;
1878
+ return { teamId: s, seed: o, bye: !s && !!r?.isBye };
1879
+ }
1880
+ function ye(a) {
1881
+ const e = H(a);
1882
+ return e === "home" || e === "away" ? e : null;
1883
+ }
1884
+ function ft(a, e) {
1885
+ const t = ve(a || [], e || []);
1886
+ if (!t || Array.isArray(t)) return null;
1887
+ const s = ye(t.game);
1888
+ return s && t.game[`${s}TeamId`] || null;
1889
+ }
1890
+ const ne = { active: 0, setup: 1, complete: 2 };
1891
+ function ut(a, { id: e, param: t } = {}) {
1892
+ const s = a || [];
1893
+ if (!s.length) return null;
1894
+ for (const r of [e, t]) {
1895
+ if (!r) continue;
1896
+ const o = s.find((l) => l.id === r);
1897
+ if (o) return o;
1898
+ }
1899
+ return [...s].sort((r, o) => (ne[r.status] ?? 3) - (ne[o.status] ?? 3) || String(r.name || "").localeCompare(String(o.name || "")))[0];
1900
+ }
1901
+ const gt = $`
1902
+ .bracket { display: flex; gap: 1rem; align-items: stretch; overflow-x: auto; padding-bottom: 0.5rem; }
1903
+ .round { flex: 0 0 250px; display: flex; flex-direction: column; min-width: 0; }
1904
+ .roundhead {
1905
+ margin: 0 0 0.6rem; padding-bottom: 0.35rem; border-bottom: 3px solid var(--hsot-gray-2);
1906
+ font-family: var(--hsot-heading-font); font-weight: 700; font-size: 0.8rem;
1907
+ text-transform: uppercase; letter-spacing: 0.04em; color: var(--hsot-gray-6);
1908
+ }
1909
+ /* Equal-flex bands center each matchup between the two that feed it. */
1910
+ .games { flex: 1; display: flex; flex-direction: column; justify-content: space-around; gap: 0.6rem; }
1911
+ .matchup {
1912
+ background: var(--hsot-white); border: 1px solid var(--hsot-gray-2);
1913
+ border-radius: var(--hsot-radius-md); overflow: hidden;
1914
+ }
1915
+ .matchup.live { border-color: var(--hsot-red); }
1916
+ .slot { display: flex; align-items: center; gap: 0.45rem; padding: 0.45rem 0.6rem; font-size: 0.9rem; min-height: 2.1rem; box-sizing: border-box; }
1917
+ .slot + .slot { border-top: 1px solid var(--hsot-gray-2); }
1918
+ .slot .seed {
1919
+ flex: none; width: 1.3rem; text-align: right; font-family: var(--hsot-heading-font);
1920
+ font-size: 0.75rem; color: var(--hsot-gray-5); font-variant-numeric: tabular-nums;
1921
+ }
1922
+ .slot .swatch { margin-right: 0; }
1923
+ .slot .tname { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1924
+ .slot .tname a { color: inherit; text-decoration: none; font-weight: 500; }
1925
+ .slot .tname a:hover { text-decoration: underline; }
1926
+ .slot .tname.bye { font-style: italic; color: var(--hsot-gray-5); }
1927
+ .slot .score {
1928
+ flex: none; min-width: 1.6rem; text-align: right; font-family: var(--hsot-heading-font);
1929
+ font-weight: 700; font-variant-numeric: tabular-nums;
1930
+ }
1931
+ .slot.winner .tname a, .slot.winner .tname { font-weight: 700; }
1932
+ .slot.winner .score { color: var(--hsot-red-deep); }
1933
+ .slot.loser { color: var(--hsot-gray-5); }
1934
+ .mfoot {
1935
+ display: flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0.6rem;
1936
+ background: var(--hsot-gray-1); border-top: 1px solid var(--hsot-gray-2); font-size: 0.75rem;
1937
+ }
1938
+ .mfoot .spacer { flex: 1; }
1939
+ .mfoot .label { color: var(--hsot-gray-5); font-family: var(--hsot-heading-font); }
1940
+ .champ {
1941
+ display: flex; align-items: center; gap: 0.5rem; margin: 0 0 1rem;
1942
+ font-family: var(--hsot-heading-font); font-size: 1.05rem;
1943
+ }
1944
+ .champ .tname a { color: inherit; text-decoration: none; font-weight: 700; }
1945
+ @media (max-width: 720px) { .round { flex-basis: 215px; } }
1946
+ `;
1947
+ class vt extends y {
1948
+ static styles = [P, gt];
1949
+ static properties = {
1950
+ ...y.properties,
1951
+ sport: { type: String },
1952
+ season: { type: String },
1953
+ tournamentId: { type: String, attribute: "tournament-id" },
1954
+ picked: { state: !0 },
1955
+ group: { state: !0 }
1956
+ };
1957
+ constructor() {
1958
+ super(), this.sport = "football", this.season = "", this.tournamentId = "", this.picked = "", this.group = null;
1959
+ }
1960
+ async fetchData(e) {
1961
+ const t = this.season || _(), s = (await e.listTournaments({ sport: this.sport, season: t })).items, r = new URLSearchParams(globalThis.location?.search || "").get("tournament"), o = ut(s, { id: this.picked || this.tournamentId, param: r });
1962
+ if (!o) return { season: t, tournaments: s, tournament: null };
1963
+ const [l, h, d, i, c] = await Promise.all([
1964
+ e.listSeedings(o.id),
1965
+ e.listEdges(o.id),
1966
+ e.listGames({ tournamentId: o.id }),
1967
+ e.listSchools(),
1968
+ e.listTeams({ sport: this.sport })
1969
+ ]);
1970
+ return {
1971
+ season: t,
1972
+ tournaments: s,
1973
+ tournament: o,
1974
+ seedings: l.items,
1975
+ edges: h.items,
1976
+ games: d.items,
1977
+ schools: i.items,
1978
+ teams: c.items
1979
+ };
1980
+ }
1981
+ get ctx() {
1982
+ return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
1983
+ teamsById: b(this.data.teams),
1984
+ schoolsById: b(this.data.schools),
1985
+ records: {},
1986
+ rankings: [],
1987
+ hrefs: z(this),
1988
+ sport: this.sport
1989
+ }, this._ctxData = this.data), this._ctx;
1990
+ }
1991
+ /** Switch tournaments: remember the pick, deep-link it, reload the scoped data. */
1992
+ pick(e) {
1993
+ if (e !== this.data?.tournament?.id) {
1994
+ this.picked = e, this.group = null;
1995
+ try {
1996
+ const t = new URL(globalThis.location.href);
1997
+ t.searchParams.set("tournament", e), globalThis.history?.replaceState(null, "", t);
1998
+ } catch {
1999
+ }
2000
+ this.load();
2001
+ }
2002
+ }
2003
+ renderView() {
2004
+ const e = this.data, t = this.ctx, s = j(this, t, {
2005
+ title: n`${B(this.sport)} playoff brackets`,
2006
+ sub: e.tournament ? n`${e.tournament.name} · ${e.season} season` : n`${e.season} season`,
2007
+ teams: e.teams
2008
+ });
2009
+ if (!e.tournament)
2010
+ return n`${s}${C(this, n`
2011
+ ${D(this)}
2012
+ <div class="card"><div class="empty">No ${this.sport} brackets have been published for the ${e.season} season yet.</div></div>
2013
+ `)}`;
2014
+ const r = ct(e.tournament, e.games), o = r.find((m) => m.key === this.group) || r[0], l = (e.tournament.groupNames || []).length >= 2 ? e.tournament.groupNames.length : 1, h = (Number(e.tournament.size) || 0) / l, d = mt(e.games, e.edges, o), i = lt(e.games), c = ft(e.games, e.edges);
2015
+ return n`
2016
+ ${s}
2017
+ ${C(this, n`
2018
+ ${D(this)}
2019
+ <div class="toolbar">
2020
+ ${e.tournaments.length > 1 ? n`
2021
+ <div role="group" aria-label="Tournament">
2022
+ ${e.tournaments.map((m) => n`<button class="chip ${m.id === e.tournament.id ? "on" : ""}"
2023
+ @click=${() => this.pick(m.id)}>${m.name}</button>`)}
2024
+ </div>` : p}
2025
+ ${r.length > 1 ? n`
2026
+ <div role="tablist" aria-label="Bracket group">
2027
+ ${r.map((m) => n`<button class="chip ${m.key === o.key ? "on" : ""}" role="tab"
2028
+ aria-selected=${m.key === o.key ? "true" : "false"}
2029
+ @click=${() => {
2030
+ this.group = m.key;
2031
+ }}>${m.name}</button>`)}
2032
+ </div>` : p}
2033
+ <span class="spacer"></span>
2034
+ <span class="pill ${i === "complete" ? "final" : i === "active" ? "class" : "type"}">${i === "complete" ? "Complete" : i === "active" ? "In progress" : "Bracket set"}</span>
2035
+ <span class="asof">${e.tournament.size}-team ${String(e.tournament.format || "").replace(/_/g, " ")}</span>
2036
+ </div>
2037
+ ${c ? n`<div class="champ"><span class="pill champ">Champion</span>
2038
+ ${T(I(t, c), 26)}<span class="tname">${O(t, c)}</span></div>` : p}
2039
+ ${d.length ? n`
2040
+ <div class="bracket" role="region" aria-label="${o.name} bracket">
2041
+ ${d.map((m) => n`
2042
+ <section class="round">
2043
+ <h3 class="roundhead">${it({ round: m.round, perGroup: h, groupCount: l })}</h3>
2044
+ <div class="games">${m.games.map((f) => this.renderMatchup(t, f))}</div>
2045
+ </section>`)}
2046
+ </div>` : n`<div class="card"><div class="empty">This bracket has no games yet.</div></div>`}
2047
+ `)}
2048
+ `;
2049
+ }
2050
+ renderMatchup(e, t) {
2051
+ const s = t.homeTeamId && t.awayTeamId || t.state === "final" || t.state === "live";
2052
+ return n`
2053
+ <article class="matchup ${t.state}" aria-label="${t.label || "Matchup"}">
2054
+ ${this.renderSlot(e, t, "home")}
2055
+ ${this.renderSlot(e, t, "away")}
2056
+ <footer class="mfoot">
2057
+ ${E(t)}
2058
+ ${t.label ? n`<span class="label">${t.label}</span>` : p}
2059
+ <span class="spacer"></span>
2060
+ ${s ? n`<a class="box" href=${g(e.hrefs.game, { sport: this.sport, id: t.id })}>Box score</a>` : p}
2061
+ </footer>
2062
+ </article>
2063
+ `;
2064
+ }
2065
+ renderSlot(e, t, s) {
2066
+ const { teamId: r, seed: o, bye: l } = pt(t, s, this.data.seedings), h = ye(t), d = t.state === "live" || t.state === "final";
2067
+ return n`
2068
+ <div class="slot ${h ? h === s ? "winner" : "loser" : ""}">
2069
+ <span class="seed">${o ?? ""}</span>
2070
+ ${r ? n`${T(I(e, r), 22)}<span class="tname">${O(e, r, t.date)}</span>` : l ? n`<span class="tname bye">Bye</span>` : n`<span class="tname mut">TBD</span>`}
2071
+ ${d ? n`<span class="score">${t[`${s}Score`] ?? 0}</span>` : p}
2072
+ </div>
2073
+ `;
2074
+ }
2075
+ }
2076
+ globalThis?.customElements && !globalThis.customElements.get("hsot-brackets") && globalThis.customElements.define("hsot-brackets", vt);
1814
2077
  export {
1815
- O as D,
1816
- Xe as H,
1817
- Me as a,
1818
- Oe as b,
1819
- et as c,
1820
- Re as d,
1821
- Ne as e,
1822
- P as f,
1823
- ue as g,
1824
- g as h,
1825
- G as i,
1826
- st as j,
1827
- H as k,
1828
- Ae as p,
2078
+ A as D,
2079
+ st as H,
2080
+ vt as a,
2081
+ je as b,
2082
+ We as c,
2083
+ ot as d,
2084
+ Oe as e,
2085
+ He as f,
2086
+ ct as g,
2087
+ ve as h,
2088
+ ft as i,
2089
+ N as j,
2090
+ lt as k,
2091
+ g as l,
2092
+ H as m,
2093
+ $t as n,
2094
+ it as o,
2095
+ Me as p,
2096
+ mt as q,
1829
2097
  k as r,
1830
- ne as s,
1831
- V as t
2098
+ he as s,
2099
+ U as t,
2100
+ K as u,
2101
+ be as v
1832
2102
  };