@wral/hsot-data 0.1.7 → 0.1.9

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,47 +1,47 @@
1
- import { LitElement as te, html as i, css as b, nothing as p, svg as X } from "lit";
2
- const ne = 50;
3
- function le(a = {}) {
1
+ import { LitElement as ee, html as r, css as b, nothing as p, svg as Q } from "lit";
2
+ const le = 50;
3
+ function ce(a = {}) {
4
4
  const e = Object.entries(a).filter(([, s]) => s != null && s !== "");
5
5
  if (!e.length) return "";
6
6
  const t = new URLSearchParams();
7
- return e.forEach(([s, r]) => t.set(s, String(r))), `?${t.toString()}`;
7
+ return e.forEach(([s, o]) => t.set(s, String(o))), `?${t.toString()}`;
8
8
  }
9
- function ce({ baseUrl: a, token: e = "", fetchFn: t } = {}) {
9
+ function de({ baseUrl: a, token: e = "", fetchFn: t } = {}) {
10
10
  if (!a) throw new Error("createClient requires a baseUrl");
11
- const s = a.replace(/\/+$/, ""), r = t || ((...n) => fetch(...n));
12
- async function o(n) {
11
+ const s = a.replace(/\/+$/, ""), o = t || ((...n) => fetch(...n));
12
+ async function i(n) {
13
13
  const h = { Accept: "application/json" };
14
14
  e && (h.Authorization = `Bearer ${e}`);
15
- const l = await r(`${s}${n}`, { headers: h });
15
+ const l = await o(`${s}${n}`, { headers: h });
16
16
  if (!l.ok) {
17
- const d = new Error(`api-hsot ${l.status} on ${n}`);
18
- throw d.status = l.status, d;
17
+ const c = new Error(`api-hsot ${l.status} on ${n}`);
18
+ throw c.status = l.status, c;
19
19
  }
20
20
  return l.json();
21
21
  }
22
- async function c(n, h = {}) {
22
+ async function d(n, h = {}) {
23
23
  const l = [];
24
- let d = null;
25
- for (let m = 0; m < ne; m += 1) {
26
- const f = le(d ? { ...h, cursor: d } : h), g = await o(`${n}${f}`);
27
- if (l.push(...g.items || []), d = g.nextCursor || null, !d) break;
24
+ let c = null;
25
+ for (let m = 0; m < le; m += 1) {
26
+ const f = ce(c ? { ...h, cursor: c } : h), g = await i(`${n}${f}`);
27
+ if (l.push(...g.items || []), c = g.nextCursor || null, !c) break;
28
28
  }
29
29
  return { items: l, total: l.length, nextCursor: null };
30
30
  }
31
31
  return {
32
- listSchools: (n) => c("/schools", n),
33
- getSchool: (n) => o(`/schools/${n}`),
34
- listTeams: (n) => c("/teams", n),
35
- getTeam: (n) => o(`/teams/${n}`),
36
- listConferences: (n) => c("/conferences", n),
37
- listPlayers: (n) => c("/players", n),
38
- listRosters: (n) => c("/rosters", n),
39
- listGames: (n) => c("/games", n),
40
- getGame: (n) => o(`/games/${n}`),
41
- listTournaments: (n) => c("/tournaments", n),
42
- listSeedings: (n, h) => c(`/tournaments/${n}/seedings`, h),
43
- listRankings: (n) => c("/rankings", n),
44
- listSports: () => o("/sports")
32
+ listSchools: (n) => d("/schools", n),
33
+ getSchool: (n) => i(`/schools/${n}`),
34
+ listTeams: (n) => d("/teams", n),
35
+ getTeam: (n) => i(`/teams/${n}`),
36
+ listConferences: (n) => d("/conferences", n),
37
+ listPlayers: (n) => d("/players", n),
38
+ listRosters: (n) => d("/rosters", n),
39
+ listGames: (n) => d("/games", n),
40
+ getGame: (n) => i(`/games/${n}`),
41
+ listTournaments: (n) => d("/tournaments", n),
42
+ listSeedings: (n, h) => d(`/tournaments/${n}/seedings`, h),
43
+ listRankings: (n) => d("/rankings", n),
44
+ listSports: () => i("/sports")
45
45
  };
46
46
  }
47
47
  const H = {
@@ -59,102 +59,102 @@ function D(a) {
59
59
  section: a.getAttribute("section-href") || H.section
60
60
  };
61
61
  }
62
- const T = (a) => a ? a.charAt(0).toUpperCase() + a.slice(1) : "";
63
- function $(a, e) {
62
+ const I = (a) => a ? a.charAt(0).toUpperCase() + a.slice(1) : "";
63
+ function y(a, e) {
64
64
  if (!a) return "TBD";
65
- const [t, s, r] = String(a).split("-").map(Number);
66
- return !t || !s || !r ? "TBD" : new Date(t, s - 1, r).toLocaleDateString("en-US", e || { weekday: "short", month: "short", day: "numeric" });
65
+ const [t, s, o] = String(a).split("-").map(Number);
66
+ return !t || !s || !o ? "TBD" : new Date(t, s - 1, o).toLocaleDateString("en-US", e || { weekday: "short", month: "short", day: "numeric" });
67
67
  }
68
- function M(a) {
68
+ function U(a) {
69
69
  if (!a) return "";
70
70
  const [e, t] = String(a).split(":").map(Number);
71
71
  if (Number.isNaN(e)) return "";
72
72
  const s = e >= 12 ? "PM" : "AM";
73
73
  return `${(e + 11) % 12 + 1}:${String(t || 0).padStart(2, "0")} ${s}`;
74
74
  }
75
- function de(a) {
75
+ function he(a) {
76
76
  return a ? `${Math.floor(a / 12)}-${a % 12}` : "·";
77
77
  }
78
- function L(a = /* @__PURE__ */ new Date()) {
78
+ function N(a = /* @__PURE__ */ new Date()) {
79
79
  const e = a.getFullYear();
80
80
  return a.getMonth() >= 6 ? `${e}-${e + 1}` : `${e - 1}-${e}`;
81
81
  }
82
- function j(a = /* @__PURE__ */ new Date()) {
82
+ function M(a = /* @__PURE__ */ new Date()) {
83
83
  const e = (t) => String(t).padStart(2, "0");
84
84
  return `${a.getFullYear()}-${e(a.getMonth() + 1)}-${e(a.getDate())}`;
85
85
  }
86
- function he(a, e = j()) {
86
+ function me(a, e = M()) {
87
87
  const t = [...new Set((a || []).filter(Boolean))].sort();
88
88
  if (!t.length || t.includes(e)) return e;
89
- const s = t.filter((r) => r < e);
89
+ const s = t.filter((o) => o < e);
90
90
  return s.length ? s[s.length - 1] : t[0];
91
91
  }
92
- function G(a) {
92
+ function j(a) {
93
93
  return a ? (a.abbr || a.name || "?").slice(0, 4).toUpperCase() : "?";
94
94
  }
95
95
  function E(a) {
96
96
  if (!a || !/^#[0-9a-fA-F]{6}$/.test(a)) return "#FFFFFF";
97
- const e = parseInt(a.slice(1), 16), t = e >> 16 & 255, s = e >> 8 & 255, r = e & 255;
98
- return 0.299 * t + 0.587 * s + 0.114 * r > 150 ? "#0F1B33" : "#FFFFFF";
97
+ const e = parseInt(a.slice(1), 16), t = e >> 16 & 255, s = e >> 8 & 255, o = e & 255;
98
+ return 0.299 * t + 0.587 * s + 0.114 * o > 150 ? "#0F1B33" : "#FFFFFF";
99
99
  }
100
- const me = (a) => {
100
+ const pe = (a) => {
101
101
  const e = ["th", "st", "nd", "rd"], t = a % 100;
102
102
  return a + (e[(t - 20) % 10] || e[t] || e[0]);
103
103
  };
104
- function se(a) {
104
+ function te(a) {
105
105
  if (a.state === "live") return { kind: "live", label: `Live · ${a.period || ""}`.replace(/ · $/, "") };
106
106
  if (a.state === "final") {
107
107
  const e = [];
108
108
  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(" · ")}` : ""}` };
109
109
  }
110
- return a.state === "postponed" ? { kind: "warn", label: "Postponed" } : a.state === "canceled" ? { kind: "warn", label: "Canceled" } : { kind: "sched", label: `${$(a.date, { month: "short", day: "numeric" })} · ${M(a.time)}`.replace(/ · $/, "") };
110
+ return a.state === "postponed" ? { kind: "warn", label: "Postponed" } : a.state === "canceled" ? { kind: "warn", label: "Canceled" } : { kind: "sched", label: `${y(a.date, { month: "short", day: "numeric" })} · ${U(a.time)}`.replace(/ · $/, "") };
111
111
  }
112
- const pe = /* @__PURE__ */ new Set(["game", "story", "page", "forum", "video", "gallery"]);
112
+ const fe = /* @__PURE__ */ new Set(["game", "story", "page", "forum", "video", "gallery"]);
113
113
  function x(a) {
114
114
  let e = String(a || "").replace(/^[a-z][a-z0-9+.-]*:\/\/[^/#?]*/i, "");
115
115
  const t = e.indexOf("#");
116
116
  let s = "";
117
117
  t !== -1 && (s = e.slice(t).split("?")[0], e = e.slice(0, t));
118
- let r = e.split("?")[0] + s;
119
- return r = r.replace(/([^:])\/{2,}/g, "$1/").replace(/^\/{2,}/, "/"), r = r.replace(/^\/(?=#)/, ""), r.length > 1 && (r = r.replace(/\/+$/, "")), r.toLowerCase();
118
+ let o = e.split("?")[0] + s;
119
+ return o = o.replace(/([^:])\/{2,}/g, "$1/").replace(/^\/{2,}/, "/"), o = o.replace(/^\/(?=#)/, ""), o.length > 1 && (o = o.replace(/\/+$/, "")), o.toLowerCase();
120
120
  }
121
- function ae() {
121
+ function se() {
122
122
  const a = globalThis.location;
123
123
  if (!a) return "";
124
124
  const e = (a.hash || "").startsWith("#/") ? a.hash : "";
125
125
  return x((a.pathname || "") + e);
126
126
  }
127
- function fe(a, e, t) {
127
+ function ue(a, e, t) {
128
128
  if (!t) return null;
129
129
  const s = x(a);
130
130
  if (!s) return null;
131
- const r = x(u(e.game, { sport: t, id: "" })), o = x(u(e.school, { id: "" }));
132
- if (s === r || s.startsWith(`${r}/`) || s === o || s.startsWith(`${o}/`)) return null;
133
- const c = x(u(e.section, { sport: t, view: "" }));
134
- if (s === c) return "";
135
- if (!s.startsWith(`${c}/`)) return null;
136
- const n = s.slice(c.length + 1), h = n.split("/");
137
- return h.length > 2 || h.some((l) => !/^[a-z][a-z-]*$/.test(l)) || pe.has(h[0]) ? null : n;
131
+ const o = x(u(e.game, { sport: t, id: "" })), i = x(u(e.school, { id: "" }));
132
+ if (s === o || s.startsWith(`${o}/`) || s === i || s.startsWith(`${i}/`)) return null;
133
+ const d = x(u(e.section, { sport: t, view: "" }));
134
+ if (s === d) return "";
135
+ if (!s.startsWith(`${d}/`)) return null;
136
+ const n = s.slice(d.length + 1), h = n.split("/");
137
+ return h.length > 2 || h.some((l) => !/^[a-z][a-z-]*$/.test(l)) || fe.has(h[0]) ? null : n;
138
138
  }
139
- function ue(a, e, t) {
140
- const s = (c) => u(t.section, { sport: a, view: c }).replace(/([^:])\/{2,}/g, "$1/"), o = new Set((e || []).map((c) => c && c.gender).filter((c) => c === "boys" || c === "girls")).size === 2 ? [
139
+ function ge(a, e, t) {
140
+ const s = (d) => u(t.section, { sport: a, view: d }).replace(/([^:])\/{2,}/g, "$1/"), i = new Set((e || []).map((d) => d && d.gender).filter((d) => d === "boys" || d === "girls")).size === 2 ? [
141
141
  { label: "Boys Standings", href: s("boys/standings") },
142
142
  { label: "Girls Standings", href: s("girls/standings") }
143
143
  ] : [{ label: "Standings", href: s("standings") }];
144
144
  return [
145
- { label: `${T(a)} Home`, href: s("") },
145
+ { label: `${I(a)} Home`, href: s("") },
146
146
  { label: "Scores/Schedule", href: s("scores") },
147
147
  { label: "Playoff Brackets", href: s("brackets") },
148
- ...o,
148
+ ...i,
149
149
  { label: "Polls & Rankings", href: s("rankings") }
150
150
  ];
151
151
  }
152
- function ge(a, e = ae()) {
152
+ function ve(a, e = se()) {
153
153
  const t = x(e);
154
154
  for (const s of a.querySelectorAll(':scope > a[slot="nav"]'))
155
155
  t && x(s.getAttribute("href")) === t ? s.setAttribute("aria-current", "page") : s.removeAttribute("aria-current");
156
156
  }
157
- class y extends te {
157
+ class $ extends ee {
158
158
  static properties = {
159
159
  api: { type: String },
160
160
  refreshInterval: { type: Number, attribute: "refresh-interval" },
@@ -173,7 +173,7 @@ class y extends te {
173
173
  this._client = e, this.isConnected && this.load();
174
174
  }
175
175
  get client() {
176
- return this._client ? this._client : this.api ? ce({ baseUrl: this.api }) : null;
176
+ return this._client ? this._client : this.api ? de({ baseUrl: this.api }) : null;
177
177
  }
178
178
  connectedCallback() {
179
179
  super.connectedCallback(), this._setupInterval();
@@ -185,7 +185,7 @@ class y extends te {
185
185
  this.load();
186
186
  }
187
187
  updated(e) {
188
- e.has("api") && e.get("api") !== void 0 && e.get("api") !== this.api && this.load(), e.has("refreshInterval") && this._setupInterval(), ge(this);
188
+ e.has("api") && e.get("api") !== void 0 && e.get("api") !== this.api && this.load(), e.has("refreshInterval") && this._setupInterval(), ve(this);
189
189
  }
190
190
  async load() {
191
191
  const e = this.client;
@@ -214,13 +214,13 @@ class y extends te {
214
214
  this._refreshId && (clearInterval(this._refreshId), this._refreshId = null);
215
215
  }
216
216
  render() {
217
- return this.error === "not-configured" ? i`<div class="error">This component needs an <code>api</code> attribute (the api-hsot public read-surface base URL) or an injected client.</div>` : this.error ? i`<div class="error">Unable to load right now. <button class="chip" @click=${() => this.load()}>Retry</button></div>` : this.data ? this.renderView() : i`<div class="loading" role="status">Loading…</div>`;
217
+ return this.error === "not-configured" ? r`<div class="error">This component needs an <code>api</code> attribute (the api-hsot public read-surface base URL) or an injected client.</div>` : this.error ? r`<div class="error">Unable to load right now. <button class="chip" @click=${() => this.load()}>Retry</button></div>` : this.data ? this.renderView() : r`<div class="loading" role="status">Loading…</div>`;
218
218
  }
219
219
  renderView() {
220
- return i``;
220
+ return r``;
221
221
  }
222
222
  }
223
- const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), ve = b`
223
+ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), be = b`
224
224
  :host {
225
225
  --hsot-red: var(--color-red, #D1232A);
226
226
  --hsot-red-deep: var(--color-red-dark, #951C21);
@@ -258,7 +258,7 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), ve = b`
258
258
  outline-offset: 1px;
259
259
  }
260
260
  .mut { color: var(--hsot-gray-5); }
261
- `, be = b`
261
+ `, ye = b`
262
262
  .band { background: var(--hsot-white); color: var(--hsot-black); }
263
263
  .band .inner { max-width: 1366px; margin: 0 auto; padding: 1.1rem 1.25rem 0; }
264
264
  .band h1, .band h2.bandtitle {
@@ -371,7 +371,7 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), ve = b`
371
371
  .error { padding: 1.2rem 1rem; color: var(--hsot-red-deep); font-size: 0.9rem; }
372
372
  .note { font-size: 0.8125rem; color: var(--hsot-gray-5); margin: 0.6rem 0 0; }
373
373
  .loading { padding: 1.2rem; color: var(--hsot-gray-5); font-family: var(--hsot-heading-font); }
374
- `, ye = b`
374
+ `, we = b`
375
375
  .pill {
376
376
  display: inline-block; font-family: var(--hsot-heading-font); font-weight: 700;
377
377
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em;
@@ -386,7 +386,7 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), ve = b`
386
386
  .pill.champ { background: var(--hsot-straw); color: #6b5900; }
387
387
  @keyframes hsot-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
388
388
  @media (prefers-reduced-motion: reduce) { .pill.live { animation: none; } }
389
- `, we = b`
389
+ `, xe = b`
390
390
  .tablewrap { overflow-x: auto; }
391
391
  table.data { font-family: var(--hsot-heading-font); font-size: 14px; border-collapse: collapse; width: 100%; }
392
392
  table.data th {
@@ -404,7 +404,7 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), ve = b`
404
404
  table.data tbody tr.rowlink:hover { background: var(--hsot-gray-1); }
405
405
  table.data td.teamcell a { color: inherit; text-decoration: none; font-weight: 500; }
406
406
  table.data td.teamcell a:hover { text-decoration: underline; }
407
- `, xe = b`
407
+ `, ke = b`
408
408
  .swatch {
409
409
  display: inline-flex; align-items: center; justify-content: center;
410
410
  width: 26px; height: 26px; border-radius: 50%;
@@ -428,7 +428,7 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), ve = b`
428
428
  .dot.W { background: var(--hsot-win); }
429
429
  .dot.L { background: var(--hsot-loss); }
430
430
  .dot.T { background: var(--hsot-tie); }
431
- `, ke = b`
431
+ `, Te = b`
432
432
  ul.gamelist { list-style: none; margin: 0; padding: 0; }
433
433
  .gamelist li {
434
434
  display: flex; align-items: center; gap: 0.7rem; padding: 0.55rem 1rem;
@@ -451,111 +451,147 @@ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), ve = b`
451
451
  .gamelist .opp { flex: 1; min-width: 180px; }
452
452
  .gamelist .opp a { text-decoration: none; color: inherit; font-weight: 500; }
453
453
  .gamelist .opp a:hover { text-decoration: underline; }
454
+
455
+ /* Scoreboard matchup: "Away <score> at Home <score>".
456
+ Scoped to .matchup, not .opp, because hsot-school's schedule rows
457
+ reuse .opp for a single opponent plus pills and must keep the plain
458
+ inline flow.
459
+
460
+ Each team + score is one .side flex item, so a matchup wider than the
461
+ row breaks *between* the two teams instead of through a school's name
462
+ — the "at North / Moore" and "at Greene / Central" wraps the old
463
+ single-span markup produced. */
464
+ .gamelist .opp.matchup {
465
+ display: flex; flex-wrap: wrap; align-items: center; gap: 0 0.35rem;
466
+ }
467
+ .gamelist .opp.matchup .side { display: inline-flex; align-items: center; }
468
+ .gamelist .opp.matchup .at { margin-left: 0.45rem; }
469
+ @media (max-width: 720px) {
470
+ /* Always two lines on a phone, split after the "at", rather than
471
+ one line for short matchups and a break wherever the text runs
472
+ out for long ones. Consistent rows read better than tight ones. */
473
+ .gamelist .opp.matchup { flex-direction: column; align-items: flex-start; row-gap: 0.15rem; }
474
+ }
475
+
476
+ /* Names the side that forfeited — the pill only says "Final · Forfeit",
477
+ which leaves a 0-0 row ambiguous about who was awarded the win. */
478
+ .gamelist .ff { color: var(--hsot-gray-5); font-size: 0.78rem; font-style: italic; }
454
479
  .gamelist .where { color: var(--hsot-gray-5); font-size: 0.78rem; }
455
480
  .gamelist a.box { font-size: 0.78rem; }
456
- `, F = [ve, be, $e, ye, we, xe, ke];
457
- function q(a) {
481
+ `, F = [be, ye, $e, we, xe, ke, Te];
482
+ function G(a) {
458
483
  return a.state !== "final" ? null : a.forfeit && a.forfeit !== "none" ? a.forfeit : a.homeScore > a.awayScore ? "home" : a.awayScore > a.homeScore ? "away" : a.tiebreakWinner && a.tiebreakWinner !== "none" ? a.tiebreakWinner : "tie";
459
484
  }
485
+ function Ie(a) {
486
+ return !a || !a.forfeit || a.forfeit === "none" ? null : a.forfeit === "home" ? "away" : a.forfeit === "away" ? "home" : null;
487
+ }
460
488
  function z(a, e) {
461
- 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, c) => String(o.date).localeCompare(String(c.date)));
462
- for (const o of r) {
463
- const c = q(o), n = o.gameType === "conference";
489
+ const t = {}, s = (i) => (t[i] = t[i] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] }, t[i]), o = a.filter((i) => i.state === "final" && i.gameType !== "scrimmage" && (!e || i.date <= e)).sort((i, d) => String(i.date).localeCompare(String(d.date)));
490
+ for (const i of o) {
491
+ const d = G(i), n = i.gameType === "conference";
464
492
  for (const h of ["home", "away"]) {
465
- const l = h === "home" ? o.homeTeamId : o.awayTeamId;
493
+ const l = h === "home" ? i.homeTeamId : i.awayTeamId;
466
494
  if (!l) continue;
467
- const d = s(l), m = h === "home" ? o.homeScore : o.awayScore, f = h === "home" ? o.awayScore : o.homeScore;
468
- d.pf += m, d.pa += f;
495
+ const c = s(l), m = h === "home" ? i.homeScore : i.awayScore, f = h === "home" ? i.awayScore : i.homeScore;
496
+ c.pf += m, c.pa += f;
469
497
  let g = "T";
470
- c === "tie" ? (d.t += 1, n && (d.ct += 1)) : c === h ? (d.w += 1, n && (d.cw += 1), g = "W") : (d.l += 1, n && (d.cl += 1), g = "L"), d.results.push({ gameId: o.id, date: o.date, mark: g, my: m, their: f, opp: h === "home" ? o.awayTeamId : o.homeTeamId, conf: n });
498
+ d === "tie" ? (c.t += 1, n && (c.ct += 1)) : d === h ? (c.w += 1, n && (c.cw += 1), g = "W") : (c.l += 1, n && (c.cl += 1), g = "L"), c.results.push({ gameId: i.id, date: i.date, mark: g, my: m, their: f, opp: h === "home" ? i.awayTeamId : i.homeTeamId, conf: n });
471
499
  }
472
500
  }
473
501
  return t;
474
502
  }
475
- function N(a) {
503
+ function L(a) {
476
504
  if (!a || !a.length) return "";
477
505
  const e = a[a.length - 1].mark;
478
506
  let t = 0;
479
507
  for (let s = a.length - 1; s >= 0 && a[s].mark === e; s -= 1) t += 1;
480
508
  return e + t;
481
509
  }
482
- const Z = (a, e, t) => {
510
+ const X = (a, e, t) => {
483
511
  const s = a + e + t;
484
512
  return s ? (a + t / 2) / s : 0;
485
- }, J = (a) => a.toFixed(3).replace("0.", ".");
513
+ }, Z = (a) => a.toFixed(3).replace("0.", ".");
486
514
  function w(a, e = !1) {
487
515
  if (!a) return "0-0";
488
- const t = e ? a.cw : a.w, s = e ? a.cl : a.l, r = e ? a.ct : a.t;
489
- return `${t}-${s}${r ? `-${r}` : ""}`;
516
+ const t = e ? a.cw : a.w, s = e ? a.cl : a.l, o = e ? a.ct : a.t;
517
+ return `${t}-${s}${o ? `-${o}` : ""}`;
490
518
  }
491
- function re(a, e) {
519
+ function ae(a, e) {
492
520
  return a.map((t) => {
493
521
  const s = e[t.id] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] };
494
- return { team: t, rec: s, confPct: Z(s.cw, s.cl, s.ct), overallPct: Z(s.w, s.l, s.t) };
522
+ return { team: t, rec: s, confPct: X(s.cw, s.cl, s.ct), overallPct: X(s.w, s.l, s.t) };
495
523
  }).sort((t, s) => s.confPct - t.confPct || s.overallPct - t.overallPct || s.rec.pf - s.rec.pa - (t.rec.pf - t.rec.pa));
496
524
  }
497
- function W(a, e) {
525
+ function q(a, e) {
498
526
  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;
499
527
  }
500
- function ee(a, e) {
528
+ function J(a, e) {
501
529
  const t = a[e];
502
530
  return t && t.results.length ? t.results[t.results.length - 1] : null;
503
531
  }
504
- function Me(a, e, t, s = "") {
505
- let r = null;
506
- for (const o of a || [])
507
- o.sport === e && (t && o.effectiveDate > t || s && o.gender && o.gender !== s || (!r || o.effectiveDate > r.effectiveDate) && (r = o));
508
- return r;
532
+ function qe(a, e, t, s = "") {
533
+ let o = null;
534
+ for (const i of a || [])
535
+ i.sport === e && (t && i.effectiveDate > t || s && i.gender && i.gender !== s || (!o || i.effectiveDate > o.effectiveDate) && (o = i));
536
+ return o;
509
537
  }
510
- function V(a, e, t, s, r) {
511
- const o = e[t];
512
- if (!o) return null;
513
- const c = /* @__PURE__ */ new Map();
538
+ function W(a, e, t, s, o) {
539
+ const i = e[t];
540
+ if (!i) return null;
541
+ const d = /* @__PURE__ */ new Map();
514
542
  for (const h of a || []) {
515
- if (h.sport !== s || r && h.effectiveDate > r || h.gender && o.gender !== h.gender && o.gender !== "coed") continue;
516
- const l = h.gender || "", d = c.get(l);
517
- (!d || h.effectiveDate > d.effectiveDate) && c.set(l, h);
543
+ if (h.sport !== s || o && h.effectiveDate > o || h.gender && i.gender !== h.gender && i.gender !== "coed") continue;
544
+ const l = h.gender || "", c = d.get(l);
545
+ (!c || h.effectiveDate > c.effectiveDate) && d.set(l, h);
518
546
  }
519
547
  let n = null;
520
- for (const h of c.values()) {
548
+ for (const h of d.values()) {
521
549
  const l = (h.teamIds || []).indexOf(t);
522
550
  l !== -1 && (!n || h.effectiveDate > n.effectiveDate) && (n = { poll: h, rank: l + 1 });
523
551
  }
524
552
  return n ? n.rank : null;
525
553
  }
526
- function Te(a, e, t) {
554
+ function Se(a, e, t) {
527
555
  if (!a) return { kind: "none", delta: 0 };
528
556
  const s = (a.teamIds || []).indexOf(t) + 1;
529
557
  if (!s) return { kind: "none", delta: 0 };
530
558
  if (!e) return { kind: "same", delta: 0 };
531
- const r = (e.teamIds || []).indexOf(t) + 1;
532
- if (!r) return { kind: "new", delta: 0 };
533
- const o = r - s;
534
- return o > 0 ? { kind: "up", delta: o } : o < 0 ? { kind: "down", delta: -o } : { kind: "same", delta: 0 };
559
+ const o = (e.teamIds || []).indexOf(t) + 1;
560
+ if (!o) return { kind: "new", delta: 0 };
561
+ const i = o - s;
562
+ return i > 0 ? { kind: "up", delta: i } : i < 0 ? { kind: "down", delta: -i } : { kind: "same", delta: 0 };
535
563
  }
536
- function Ie(a) {
564
+ function Ce(a) {
537
565
  return /^https?:\/\//i.test(String(a || ""));
538
566
  }
539
- function _(a, e) {
540
- const t = a?.logoAssetId;
541
- if (!Ie(t)) return "";
542
- const s = Math.max(1, Math.round(e * 2)), r = t.includes("?") ? "&" : "?";
543
- return `${t}${r}w=${s}&h=${s}&f=webp`;
567
+ function oe(a, { w: e, h: t } = {}) {
568
+ if (!Ce(a)) return "";
569
+ const s = [];
570
+ e && s.push(`w=${Math.max(1, Math.round(e))}`), t && s.push(`h=${Math.max(1, Math.round(t))}`), s.push("f=webp");
571
+ const o = a.includes("?") ? "&" : "?";
572
+ return `${a}${o}${s.join("&")}`;
573
+ }
574
+ function A(a, e) {
575
+ const t = e * 2;
576
+ return oe(a?.logoAssetId, { w: t, h: t });
544
577
  }
545
- function Y(a, e, { title: t, sub: s, teams: r }) {
546
- const o = ae(), n = !!a.querySelector(':scope > a[slot="nav"]') || fe(o, e.hrefs, e.sport) !== null;
547
- return i`
578
+ function De(a, e) {
579
+ return oe(a?.photoAssetId, { w: e * 2 });
580
+ }
581
+ function V(a, e, { title: t, sub: s, teams: o }) {
582
+ const i = se(), n = !!a.querySelector(':scope > a[slot="nav"]') || ue(i, e.hrefs, e.sport) !== null;
583
+ return r`
548
584
  <div class="band section">
549
585
  <div class="inner">
550
586
  <h1>${t}</h1>
551
- ${s ? i`<p class="sub">${s}</p>` : p}
587
+ ${s ? r`<p class="sub">${s}</p>` : p}
552
588
  </div>
553
- ${n ? i`
554
- <nav class="sectionnav" aria-label="${T(e.sport)} section">
589
+ ${n ? r`
590
+ <nav class="sectionnav" aria-label="${I(e.sport)} section">
555
591
  <div class="navrow">
556
592
  <slot name="nav">
557
- ${ue(e.sport, r, e.hrefs).map((h) => i`<a href=${h.href}
558
- aria-current=${o && x(h.href) === o ? "page" : p}>${h.label}</a>`)}
593
+ ${ge(e.sport, o, e.hrefs).map((h) => r`<a href=${h.href}
594
+ aria-current=${i && x(h.href) === i ? "page" : p}>${h.label}</a>`)}
559
595
  </slot>
560
596
  </div>
561
597
  </nav>` : p}
@@ -565,60 +601,60 @@ function Y(a, e, { title: t, sub: s, teams: r }) {
565
601
  const S = (a, e) => {
566
602
  const t = a.teamsById[e];
567
603
  return t ? a.schoolsById[t.schoolId] : null;
568
- }, I = (a, e) => S(a, e)?.name || "TBD", A = (a, e) => S(a, e)?.abbr || "TBD";
604
+ }, T = (a, e) => S(a, e)?.name || "TBD", _ = (a, e) => S(a, e)?.abbr || "TBD";
569
605
  function C(a, e = 26) {
570
606
  if (!a) return p;
571
- const t = _(a, e);
607
+ const t = A(a, e);
572
608
  if (t)
573
- return i`<img class="swatch logo" aria-hidden="true" alt="" loading="lazy"
609
+ return r`<img class="swatch logo" aria-hidden="true" alt="" loading="lazy"
574
610
  src=${t} style="width:${e}px;height:${e}px" />`;
575
- const s = a.colorPrimary || "#030711", r = E(s);
576
- return i`<span class="swatch" aria-hidden="true"
577
- style="width:${e}px;height:${e}px;background:${s};color:${r};font-size:${Math.max(8, e * 0.28)}px"
578
- >${G(a)}</span>`;
611
+ const s = a.colorPrimary || "#030711", o = E(s);
612
+ return r`<span class="swatch" aria-hidden="true"
613
+ style="width:${e}px;height:${e}px;background:${s};color:${o};font-size:${Math.max(8, e * 0.28)}px"
614
+ >${j(a)}</span>`;
579
615
  }
580
- function K(a, e, t) {
581
- const s = V(a.rankings, a.teamsById, e, a.sport, t);
582
- return s ? i`<span class="rankbadge">#${s}</span>` : p;
616
+ function Y(a, e, t) {
617
+ const s = W(a.rankings, a.teamsById, e, a.sport, t);
618
+ return s ? r`<span class="rankbadge">#${s}</span>` : p;
583
619
  }
584
- function U(a, e, t) {
620
+ function re(a, e, t) {
585
621
  const s = S(a, e);
586
- return s ? i`${K(a, e, t)}<a href=${u(a.hrefs.school, { id: s.id })}>${s.name}</a>` : i`<span class="mut">TBD</span>`;
622
+ return s ? r`${Y(a, e, t)}<a href=${u(a.hrefs.school, { id: s.id })}>${s.name}</a>` : r`<span class="mut">TBD</span>`;
587
623
  }
588
- function Q(a, e, t = 5) {
624
+ function K(a, e, t = 5) {
589
625
  const s = a.records[e];
590
- if (!s || !s.results.length) return i`<span class="mut">·</span>`;
591
- const r = s.results.slice(-1 * t);
592
- return i`<span class="dots" role="img" aria-label="last ${r.length} results">
593
- ${r.map((o) => i`<a class="dot ${o.mark}"
594
- title="${o.mark} ${o.my}-${o.their} vs ${I(a, o.opp)}"
595
- href=${u(a.hrefs.game, { sport: a.sport, id: o.gameId })}>${o.mark}</a>`)}
626
+ if (!s || !s.results.length) return r`<span class="mut">·</span>`;
627
+ const o = s.results.slice(-1 * t);
628
+ return r`<span class="dots" role="img" aria-label="last ${o.length} results">
629
+ ${o.map((i) => r`<a class="dot ${i.mark}"
630
+ title="${i.mark} ${i.my}-${i.their} vs ${T(a, i.opp)}"
631
+ href=${u(a.hrefs.game, { sport: a.sport, id: i.gameId })}>${i.mark}</a>`)}
596
632
  </span>`;
597
633
  }
598
634
  function B(a, e) {
599
- return a.querySelector(':scope > [slot="rail"]') ? i`<div class="view withrail">
635
+ return a.querySelector(':scope > [slot="rail"]') ? r`<div class="view withrail">
600
636
  <div class="viewmain">${e}</div>
601
637
  <aside class="viewrail"><slot name="rail"></slot></aside>
602
- </div>` : i`<div class="view">${e}</div>`;
638
+ </div>` : r`<div class="view">${e}</div>`;
603
639
  }
604
640
  function P(a) {
605
641
  if (!a.promoImage) return p;
606
- const e = i`<img src=${a.promoImage} alt=${a.promoAlt || "Sponsor"}>`;
607
- return i`<div class="promo">${a.promoHref ? i`<a href=${a.promoHref} target="_blank" rel="sponsored noopener">${e}</a>` : e}</div>`;
642
+ const e = r`<img src=${a.promoImage} alt=${a.promoAlt || "Sponsor"}>`;
643
+ return r`<div class="promo">${a.promoHref ? r`<a href=${a.promoHref} target="_blank" rel="sponsored noopener">${e}</a>` : e}</div>`;
608
644
  }
609
645
  function R(a) {
610
- const e = se(a);
611
- return i`<span class="pill ${e.kind}">${e.label}</span>`;
646
+ const e = te(a);
647
+ return r`<span class="pill ${e.kind}">${e.label}</span>`;
612
648
  }
613
- function oe(a, e, t) {
614
- if (!e) return i`<span class="mut">·</span>`;
615
- const s = e.homeTeamId === t ? e.awayTeamId : e.homeTeamId, r = e.homeTeamId === t ? "vs" : "at";
616
- return i`${e.state === "live" ? i`<span class="pill live">Live</span> ` : i`${$(e.date, { month: "numeric", day: "numeric" })} `}${r} ${A(a, s)}`;
649
+ function ie(a, e, t) {
650
+ if (!e) return r`<span class="mut">·</span>`;
651
+ const s = e.homeTeamId === t ? e.awayTeamId : e.homeTeamId, o = e.homeTeamId === t ? "vs" : "at";
652
+ return r`${e.state === "live" ? r`<span class="pill live">Live</span> ` : r`${y(e.date, { month: "numeric", day: "numeric" })} `}${o} ${_(a, s)}`;
617
653
  }
618
- class Se extends y {
654
+ class Fe extends $ {
619
655
  static styles = F;
620
656
  static properties = {
621
- ...y.properties,
657
+ ...$.properties,
622
658
  sport: { type: String },
623
659
  season: { type: String },
624
660
  date: { type: String }
@@ -634,19 +670,19 @@ class Se extends y {
634
670
  this._datePinned = !!this.date;
635
671
  }
636
672
  async fetchData(e) {
637
- const t = this.season || L(), [s, r, o, c, n] = await Promise.all([
673
+ const t = this.season || N(), [s, o, i, d, n] = await Promise.all([
638
674
  e.listSchools(),
639
675
  e.listTeams({ sport: this.sport }),
640
676
  e.listConferences(),
641
677
  e.listGames({ sport: this.sport, season: t }),
642
678
  e.listRankings({ sport: this.sport })
643
679
  ]);
644
- return this._datePinned || (this.date = he(c.items.map((h) => h.date)), this._datePinned = !0), {
680
+ return this._datePinned || (this.date = me(d.items.map((h) => h.date)), this._datePinned = !0), {
645
681
  season: t,
646
682
  schools: s.items,
647
- teams: r.items,
648
- conferences: o.items,
649
- games: c.items,
683
+ teams: o.items,
684
+ conferences: i.items,
685
+ games: d.items,
650
686
  rankings: n.items
651
687
  };
652
688
  }
@@ -661,30 +697,30 @@ class Se extends y {
661
697
  }, this._ctxData = this.data), this._ctx;
662
698
  }
663
699
  renderView() {
664
- const e = this.ctx, t = v(this.data.conferences), s = [...new Set(this.data.games.map((l) => l.date).filter(Boolean))].sort(), r = Number.MAX_SAFE_INTEGER, o = (l) => {
665
- const d = [l.awayTeamId, l.homeTeamId].map((m) => V(e.rankings, e.teamsById, m, this.sport, l.date)).filter(Boolean);
666
- return d.length ? Math.min(...d) : r;
667
- }, c = this.data.games.filter((l) => l.date === this.date), n = new Map(c.map((l) => [l, o(l)]));
668
- c.sort((l, d) => (l.state === "live" ? 0 : 1) - (d.state === "live" ? 0 : 1) || n.get(l) - n.get(d));
700
+ const e = this.ctx, t = v(this.data.conferences), s = [...new Set(this.data.games.map((l) => l.date).filter(Boolean))].sort(), o = Number.MAX_SAFE_INTEGER, i = (l) => {
701
+ const c = [l.awayTeamId, l.homeTeamId].map((m) => W(e.rankings, e.teamsById, m, this.sport, l.date)).filter(Boolean);
702
+ return c.length ? Math.min(...c) : o;
703
+ }, d = this.data.games.filter((l) => l.date === this.date), n = new Map(d.map((l) => [l, i(l)]));
704
+ d.sort((l, c) => (l.state === "live" ? 0 : 1) - (c.state === "live" ? 0 : 1) || n.get(l) - n.get(c));
669
705
  const h = /* @__PURE__ */ new Map();
670
- return c.forEach((l) => {
671
- const d = l.gameType === "conference" && l.conferenceId ? t[l.conferenceId]?.name || "Conference" : l.gameType === "playoff" ? "Playoffs" : l.gameType === "scrimmage" ? "Scrimmages" : "Nonconference";
672
- h.has(d) || h.set(d, []), h.get(d).push(l);
673
- }), i`
674
- ${Y(this, e, {
675
- title: i`${T(this.sport)} scores &amp; schedules`,
676
- sub: i`${$(this.date, { weekday: "long", month: "long", day: "numeric", year: "numeric" })} · ${c.length} games`,
706
+ return d.forEach((l) => {
707
+ const c = l.gameType === "conference" && l.conferenceId ? t[l.conferenceId]?.name || "Conference" : l.gameType === "playoff" ? "Playoffs" : l.gameType === "scrimmage" ? "Scrimmages" : "Nonconference";
708
+ h.has(c) || h.set(c, []), h.get(c).push(l);
709
+ }), r`
710
+ ${V(this, e, {
711
+ title: r`${I(this.sport)} scores &amp; schedules`,
712
+ sub: r`${y(this.date, { weekday: "long", month: "long", day: "numeric", year: "numeric" })} · ${d.length} games`,
677
713
  teams: this.data.teams
678
714
  })}
679
- ${B(this, i`
715
+ ${B(this, r`
680
716
  ${P(this)}
681
717
  <div class="toolbar">
682
718
  <label class="asof" for="datesel">Date</label>
683
719
  <select id="datesel" @change=${(l) => {
684
720
  this.date = l.target.value;
685
721
  }}>
686
- ${(s.includes(this.date) ? s : [...s, this.date].sort()).map((l) => i`<option value=${l} ?selected=${l === this.date}>
687
- ${$(l, { weekday: "short", month: "short", day: "numeric" })}${l === j() ? " · today" : ""}
722
+ ${(s.includes(this.date) ? s : [...s, this.date].sort()).map((l) => r`<option value=${l} ?selected=${l === this.date}>
723
+ ${y(l, { weekday: "short", month: "short", day: "numeric" })}${l === M() ? " · today" : ""}
688
724
  </option>`)}
689
725
  </select>
690
726
  <button class="chip" ?disabled=${s.indexOf(this.date) <= 0}
@@ -698,11 +734,11 @@ class Se extends y {
698
734
  <span class="spacer"></span>
699
735
  <span class="asof">Live games first · report a score to see it update here</span>
700
736
  </div>
701
- ${c.length ? p : i`<p class="empty">No ${this.sport} games on this date.</p>`}
702
- ${[...h.entries()].map(([l, d]) => i`
737
+ ${d.length ? p : r`<p class="empty">No ${this.sport} games on this date.</p>`}
738
+ ${[...h.entries()].map(([l, c]) => r`
703
739
  <div class="section-title">${l}</div>
704
740
  <div class="card"><ul class="gamelist">
705
- ${d.map((m) => this.renderGame(e, m))}
741
+ ${c.map((m) => this.renderGame(e, m))}
706
742
  </ul></div>
707
743
  `)}
708
744
  `)}
@@ -712,24 +748,24 @@ class Se extends y {
712
748
  // a lone score column on the far right read as detached from the teams).
713
749
  // Scheduled games carry their start time on the status pill alone.
714
750
  renderGame(e, t) {
715
- const s = t.state === "final" || t.state === "live";
716
- return i`
751
+ const s = t.state === "final" || t.state === "live", o = (d, n, h = p) => r`<span class="side">${re(e, d, t.date)}${s ? r`<span class="score">${n}</span>` : p}${h}</span>`, i = Ie(t);
752
+ return r`
717
753
  <li>
718
754
  ${R(t)}
719
- <span class="opp">${U(e, t.awayTeamId, t.date)}${s ? i`<span class="score">${t.awayScore}</span>` : p}
720
- at ${U(e, t.homeTeamId, t.date)}${s ? i`<span class="score">${t.homeScore}</span>` : p}</span>
755
+ <span class="opp matchup">${o(t.awayTeamId, t.awayScore, r`<span class="at">at</span>`)}${o(t.homeTeamId, t.homeScore)}</span>
756
+ ${i ? r`<span class="ff">${T(e, i === "home" ? t.homeTeamId : t.awayTeamId)} forfeited</span>` : p}
721
757
  <span class="where">${t.venue || ""}</span>
722
- ${t.broadcast ? i`<span class="pill class">${t.broadcast}</span>` : p}
758
+ ${t.broadcast ? r`<span class="pill class">${t.broadcast}</span>` : p}
723
759
  <a class="box" href=${u(e.hrefs.game, { sport: this.sport, id: t.id })}>Box score →</a>
724
760
  </li>
725
761
  `;
726
762
  }
727
763
  }
728
- globalThis?.customElements && !globalThis.customElements.get("hsot-scores") && globalThis.customElements.define("hsot-scores", Se);
729
- class Ce extends y {
764
+ globalThis?.customElements && !globalThis.customElements.get("hsot-scores") && globalThis.customElements.define("hsot-scores", Fe);
765
+ class ze extends $ {
730
766
  static styles = F;
731
767
  static properties = {
732
- ...y.properties,
768
+ ...$.properties,
733
769
  sport: { type: String },
734
770
  season: { type: String },
735
771
  classFilter: { state: !0 },
@@ -739,7 +775,7 @@ class Ce extends y {
739
775
  super(), this.sport = "football", this.season = "", this.classFilter = "All", this.query = "";
740
776
  }
741
777
  async fetchData(e) {
742
- const t = this.season || L(), [s, r, o, c, n] = await Promise.all([
778
+ const t = this.season || N(), [s, o, i, d, n] = await Promise.all([
743
779
  e.listConferences({ active: !0 }),
744
780
  e.listSchools(),
745
781
  e.listTeams({ sport: this.sport }),
@@ -749,9 +785,9 @@ class Ce extends y {
749
785
  return {
750
786
  season: t,
751
787
  conferences: s.items,
752
- schools: r.items,
753
- teams: o.items,
754
- games: c.items,
788
+ schools: o.items,
789
+ teams: i.items,
790
+ games: d.items,
755
791
  rankings: n.items
756
792
  };
757
793
  }
@@ -766,43 +802,43 @@ class Ce extends y {
766
802
  }, this._ctxData = this.data), this._ctx;
767
803
  }
768
804
  renderView() {
769
- const e = this.ctx, t = ["All", ...new Set(this.data.conferences.flatMap((r) => r.classifications || []))].slice(0, 9), s = this.data.conferences.filter((r) => r.active !== !1).filter((r) => this.classFilter === "All" || (r.classifications || []).includes(this.classFilter));
770
- return i`
771
- ${Y(this, e, {
772
- title: i`${T(this.sport)} standings`,
773
- sub: i`${this.data.season} season · every conference, computed live from reported results`,
805
+ const e = this.ctx, t = ["All", ...new Set(this.data.conferences.flatMap((o) => o.classifications || []))].slice(0, 9), s = this.data.conferences.filter((o) => o.active !== !1).filter((o) => this.classFilter === "All" || (o.classifications || []).includes(this.classFilter));
806
+ return r`
807
+ ${V(this, e, {
808
+ title: r`${I(this.sport)} standings`,
809
+ sub: r`${this.data.season} season · every conference, computed live from reported results`,
774
810
  teams: this.data.teams
775
811
  })}
776
- ${B(this, i`
812
+ ${B(this, r`
777
813
  ${P(this)}
778
814
  <div class="toolbar">
779
815
  <div role="group" aria-label="Classification filter">
780
- ${t.map((r) => i`<button class="chip ${this.classFilter === r ? "on" : ""}"
816
+ ${t.map((o) => r`<button class="chip ${this.classFilter === o ? "on" : ""}"
781
817
  @click=${() => {
782
- this.classFilter = r;
783
- }}>${r}</button>`)}
818
+ this.classFilter = o;
819
+ }}>${o}</button>`)}
784
820
  </div>
785
821
  <input type="search" placeholder="Find a school…" aria-label="Find a school"
786
- .value=${this.query} @input=${(r) => {
787
- this.query = r.target.value;
822
+ .value=${this.query} @input=${(o) => {
823
+ this.query = o.target.value;
788
824
  }}>
789
825
  <span class="spacer"></span>
790
- <span class="asof">Records through ${$(j(), { month: "long", day: "numeric" })} · conference games count toward both records · scrimmages toward neither</span>
826
+ <span class="asof">Records through ${y(M(), { month: "long", day: "numeric" })} · conference games count toward both records · scrimmages toward neither</span>
791
827
  </div>
792
- ${s.map((r) => this.renderConference(e, r))}
828
+ ${s.map((o) => this.renderConference(e, o))}
793
829
  `)}
794
830
  `;
795
831
  }
796
832
  renderConference(e, t) {
797
- const s = this.data.teams.filter((c) => c.conferenceId === t.id);
833
+ const s = this.data.teams.filter((d) => d.conferenceId === t.id);
798
834
  if (!s.length) return p;
799
- const r = this.query.trim().toLowerCase(), o = re(s, e.records);
800
- return i`
835
+ const o = this.query.trim().toLowerCase(), i = ae(s, e.records);
836
+ return r`
801
837
  <div class="card">
802
838
  <div class="card-head">
803
839
  <h2>${t.name}</h2>
804
- ${(t.classifications || []).map((c) => i`<span class="pill class">${c}</span>`)}
805
- <span class="meta">${o.length} teams · membership derives from teams</span>
840
+ ${(t.classifications || []).map((d) => r`<span class="pill class">${d}</span>`)}
841
+ <span class="meta">${i.length} teams · membership derives from teams</span>
806
842
  </div>
807
843
  <div class="tablewrap"><table class="data">
808
844
  <thead><tr>
@@ -811,44 +847,44 @@ class Ce extends y {
811
847
  <th>Streak</th><th>Last 5</th><th>Next</th>
812
848
  </tr></thead>
813
849
  <tbody>
814
- ${o.map((c, n) => this.renderRow(e, c, n, r))}
850
+ ${i.map((d, n) => this.renderRow(e, d, n, o))}
815
851
  </tbody>
816
852
  </table></div>
817
853
  </div>
818
854
  `;
819
855
  }
820
- renderRow(e, t, s, r) {
821
- const o = e.schoolsById[t.team.schoolId], c = o?.name || t.team.name || "TBD";
822
- if (r && !c.toLowerCase().includes(r)) return p;
823
- const n = t.rec.pf - t.rec.pa, h = W(this.data.games, t.team.id), l = (t.team.championships || []).map((m) => i`
824
- <span class="pill champ" title="${m.season} ${m.title} champion">★ ${m.season} ${m.title}</span>`), d = () => {
856
+ renderRow(e, t, s, o) {
857
+ const i = e.schoolsById[t.team.schoolId], d = i?.name || t.team.name || "TBD";
858
+ if (o && !d.toLowerCase().includes(o)) return p;
859
+ const n = t.rec.pf - t.rec.pa, h = q(this.data.games, t.team.id), l = (t.team.championships || []).map((m) => r`
860
+ <span class="pill champ" title="${m.season} ${m.title} champion">★ ${m.season} ${m.title}</span>`), c = () => {
825
861
  location.href = u(e.hrefs.school, { id: t.team.schoolId });
826
862
  };
827
- return i`
863
+ return r`
828
864
  <tr class="rowlink" @click=${(m) => {
829
- m.target.closest("a") || d();
865
+ m.target.closest("a") || c();
830
866
  }}>
831
867
  <td class="mut">${s + 1}</td>
832
868
  <td class="teamcell">
833
- ${C(o)}${K(e, t.team.id, null)}
834
- <a href=${u(e.hrefs.school, { id: t.team.schoolId })}>${c}</a> ${l}
869
+ ${C(i)}${Y(e, t.team.id, null)}
870
+ <a href=${u(e.hrefs.school, { id: t.team.schoolId })}>${d}</a> ${l}
835
871
  </td>
836
872
  <td class="num">${w(t.rec, !0)}</td>
837
- <td class="num">${J(t.confPct)}</td>
873
+ <td class="num">${Z(t.confPct)}</td>
838
874
  <td class="num">${w(t.rec)}</td>
839
- <td class="num">${J(t.overallPct)}</td>
875
+ <td class="num">${Z(t.overallPct)}</td>
840
876
  <td class="num">${t.rec.pf}</td>
841
877
  <td class="num">${t.rec.pa}</td>
842
878
  <td class="num" style="color:${n >= 0 ? "var(--hsot-win)" : "var(--hsot-loss)"}">${n > 0 ? "+" : ""}${n}</td>
843
- <td>${N(t.rec.results) || "·"}</td>
844
- <td>${Q(e, t.team.id)}</td>
845
- <td>${oe(e, h, t.team.id)}</td>
879
+ <td>${L(t.rec.results) || "·"}</td>
880
+ <td>${K(e, t.team.id)}</td>
881
+ <td>${ie(e, h, t.team.id)}</td>
846
882
  </tr>
847
883
  `;
848
884
  }
849
885
  }
850
- globalThis?.customElements && !globalThis.customElements.get("hsot-standings") && globalThis.customElements.define("hsot-standings", Ce);
851
- const De = b`
886
+ globalThis?.customElements && !globalThis.customElements.get("hsot-standings") && globalThis.customElements.define("hsot-standings", ze);
887
+ const Be = b`
852
888
  .hero1 {
853
889
  border-radius: var(--hsot-radius-md); color: var(--hsot-white);
854
890
  padding: 1.3rem 1.4rem; display: flex; align-items: center; gap: 1.2rem;
@@ -865,10 +901,10 @@ const De = b`
865
901
  .delta.new { background: var(--hsot-straw); color: #6b5900; border-radius: var(--hsot-radius-xs); padding: 0.1rem 0.3rem; font-size: 0.7rem; }
866
902
  .sparkline { vertical-align: middle; }
867
903
  `;
868
- class Fe extends y {
869
- static styles = [...F, De];
904
+ class Pe extends $ {
905
+ static styles = [...F, Be];
870
906
  static properties = {
871
- ...y.properties,
907
+ ...$.properties,
872
908
  sport: { type: String },
873
909
  gender: { type: String },
874
910
  season: { type: String },
@@ -883,19 +919,19 @@ class Fe extends y {
883
919
  e && (this.pollDate = e);
884
920
  }
885
921
  async fetchData(e) {
886
- const t = this.season || L(), [s, r, o, c, n] = await Promise.all([
922
+ const t = this.season || N(), [s, o, i, d, n] = await Promise.all([
887
923
  e.listRankings({ sport: this.sport, ...this.gender ? { gender: this.gender } : {} }),
888
924
  e.listSchools(),
889
925
  e.listTeams({ sport: this.sport }),
890
926
  e.listConferences(),
891
927
  e.listGames({ sport: this.sport, season: t })
892
- ]), h = s.items.filter((l) => !this.gender || !l.gender || l.gender === this.gender).sort((l, d) => d.effectiveDate.localeCompare(l.effectiveDate));
928
+ ]), h = s.items.filter((l) => !this.gender || !l.gender || l.gender === this.gender).sort((l, c) => c.effectiveDate.localeCompare(l.effectiveDate));
893
929
  return {
894
930
  season: t,
895
931
  polls: h,
896
- schools: r.items,
897
- teams: o.items,
898
- conferences: c.items,
932
+ schools: o.items,
933
+ teams: i.items,
934
+ conferences: d.items,
899
935
  games: n.items
900
936
  };
901
937
  }
@@ -920,36 +956,36 @@ class Fe extends y {
920
956
  if (n.forEach((m) => {
921
957
  m ? l.push(m) : l.length && (h.push(l), l = []);
922
958
  }), l.length && h.push(l), !h.length) return p;
923
- const d = n[s];
924
- return i`<svg class="sparkline" width=${96} height=${26} viewBox="0 0 ${96} ${26}" role="img" aria-label="rank history">
925
- ${h.map((m) => X`<polyline fill="none" stroke="var(--hsot-red)" stroke-width="2"
959
+ const c = n[s];
960
+ return r`<svg class="sparkline" width=${96} height=${26} viewBox="0 0 ${96} ${26}" role="img" aria-label="rank history">
961
+ ${h.map((m) => Q`<polyline fill="none" stroke="var(--hsot-red)" stroke-width="2"
926
962
  points=${m.map((f) => `${f.x.toFixed(1)},${f.y.toFixed(1)}`).join(" ")}></polyline>`)}
927
- ${d ? X`<circle cx=${d.x.toFixed(1)} cy=${d.y.toFixed(1)} r="3" fill="var(--hsot-black)"></circle>` : p}
963
+ ${c ? Q`<circle cx=${c.x.toFixed(1)} cy=${c.y.toFixed(1)} r="3" fill="var(--hsot-black)"></circle>` : p}
928
964
  </svg>`;
929
965
  }
930
966
  movement(e, t, s) {
931
- const r = Te(e, t, s);
932
- return r.kind === "up" ? i`<span class="delta up">▲ ${r.delta}</span>` : r.kind === "down" ? i`<span class="delta down">▼ ${r.delta}</span>` : r.kind === "new" ? i`<span class="delta new">NEW</span>` : r.kind === "same" ? i`<span class="delta same">—</span>` : i`<span class="delta same">·</span>`;
967
+ const o = Se(e, t, s);
968
+ return o.kind === "up" ? r`<span class="delta up">▲ ${o.delta}</span>` : o.kind === "down" ? r`<span class="delta down">▼ ${o.delta}</span>` : o.kind === "new" ? r`<span class="delta new">NEW</span>` : o.kind === "same" ? r`<span class="delta same">—</span>` : r`<span class="delta same">·</span>`;
933
969
  }
934
970
  renderView() {
935
971
  const e = this.ctx, t = this.data.polls;
936
- if (!t.length) return i`<div class="view"><p class="empty">No ${this.sport} polls published yet this season.</p></div>`;
937
- const s = Math.max(0, t.findIndex((m) => m.effectiveDate === this.pollDate)), r = t[s] || t[0], o = t[s + 1] || null, c = t.slice().reverse(), n = c.indexOf(r), h = v(this.data.conferences), l = (r.teamIds || [])[0], d = l ? S(e, l) : null;
938
- return i`
939
- ${Y(this, e, {
940
- title: i`${T(this.sport)} Top 25`,
941
- sub: i`The HighSchoolOT poll · updated weekly · ${t.length} polls this season`,
972
+ if (!t.length) return r`<div class="view"><p class="empty">No ${this.sport} polls published yet this season.</p></div>`;
973
+ const s = Math.max(0, t.findIndex((m) => m.effectiveDate === this.pollDate)), o = t[s] || t[0], i = t[s + 1] || null, d = t.slice().reverse(), n = d.indexOf(o), h = v(this.data.conferences), l = (o.teamIds || [])[0], c = l ? S(e, l) : null;
974
+ return r`
975
+ ${V(this, e, {
976
+ title: r`${I(this.sport)} Top 25`,
977
+ sub: r`The HighSchoolOT poll · updated weekly · ${t.length} polls this season`,
942
978
  teams: this.data.teams
943
979
  })}
944
- ${B(this, i`
980
+ ${B(this, r`
945
981
  ${P(this)}
946
982
  <div class="toolbar">
947
983
  <label class="asof" for="pollsel">Poll of</label>
948
984
  <select id="pollsel" @change=${(m) => {
949
985
  this.pollDate = m.target.value;
950
986
  }}>
951
- ${t.map((m, f) => i`<option value=${m.effectiveDate} ?selected=${m === r}>
952
- ${$(m.effectiveDate, { month: "long", day: "numeric", year: "numeric" })}${f === 0 ? " · current" : ""}
987
+ ${t.map((m, f) => r`<option value=${m.effectiveDate} ?selected=${m === o}>
988
+ ${y(m.effectiveDate, { month: "long", day: "numeric", year: "numeric" })}${f === 0 ? " · current" : ""}
953
989
  </option>`)}
954
990
  </select>
955
991
  <button class="chip" ?disabled=${s >= t.length - 1}
@@ -963,45 +999,45 @@ class Fe extends y {
963
999
  <span class="spacer"></span>
964
1000
  <span class="asof">Movement vs. the previous poll · sparkline = season rank history</span>
965
1001
  </div>
966
- ${d ? this.renderHero(e, r, o, l, d, h) : p}
1002
+ ${c ? this.renderHero(e, o, i, l, c, h) : p}
967
1003
  <div class="card"><div class="tablewrap"><table class="data">
968
1004
  <thead><tr>
969
1005
  <th class="num">Rk</th><th>Mvmt</th><th>Team</th><th class="num">Record</th>
970
1006
  <th>Conference</th><th>Last result</th><th>Next</th><th>Season</th>
971
1007
  </tr></thead>
972
1008
  <tbody>
973
- ${(r.teamIds || []).map((m, f) => f === 0 || !m ? p : this.renderRow(e, r, o, c, n, h, m, f + 1))}
1009
+ ${(o.teamIds || []).map((m, f) => f === 0 || !m ? p : this.renderRow(e, o, i, d, n, h, m, f + 1))}
974
1010
  </tbody>
975
1011
  </table></div></div>
976
1012
  <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>
977
1013
  `)}
978
1014
  `;
979
1015
  }
980
- renderHero(e, t, s, r, o, c) {
981
- const n = e.records[r], h = ee(e.records, r), l = c[e.teamsById[r]?.conferenceId], d = `linear-gradient(120deg, ${o.colorPrimary || "#030711"} 0%, var(--hsot-black) 85%)`;
982
- return i`
983
- <div class="hero1" style="background:${d}">
1016
+ renderHero(e, t, s, o, i, d) {
1017
+ const n = e.records[o], h = J(e.records, o), l = d[e.teamsById[o]?.conferenceId], c = `linear-gradient(120deg, ${i.colorPrimary || "#030711"} 0%, var(--hsot-black) 85%)`;
1018
+ return r`
1019
+ <div class="hero1" style="background:${c}">
984
1020
  <div class="bigrank">#1</div>
985
- ${C(o, 64)}
1021
+ ${C(i, 64)}
986
1022
  <div>
987
- <h2><a href=${u(e.hrefs.school, { id: o.id })}>${o.name} ${o.mascot || ""}</a></h2>
1023
+ <h2><a href=${u(e.hrefs.school, { id: i.id })}>${i.name} ${i.mascot || ""}</a></h2>
988
1024
  <div class="facts">
989
- ${w(n)} overall${l ? i` · ${w(n, !0)} ${l.name}` : p}
990
- · streak ${N(n?.results) || "·"}
991
- ${h ? i` · last: ${h.mark} ${h.my}-${h.their} vs ${A(e, h.opp)}` : p}
992
- &nbsp;${this.movement(t, s, r)}
1025
+ ${w(n)} overall${l ? r` · ${w(n, !0)} ${l.name}` : p}
1026
+ · streak ${L(n?.results) || "·"}
1027
+ ${h ? r` · last: ${h.mark} ${h.my}-${h.their} vs ${_(e, h.opp)}` : p}
1028
+ &nbsp;${this.movement(t, s, o)}
993
1029
  </div>
994
1030
  </div>
995
1031
  </div>
996
1032
  `;
997
1033
  }
998
- renderRow(e, t, s, r, o, c, n, h) {
1034
+ renderRow(e, t, s, o, i, d, n, h) {
999
1035
  const l = S(e, n);
1000
1036
  if (!l) return p;
1001
- const d = e.records[n], m = ee(e.records, n), f = W(this.data.games, n), g = c[e.teamsById[n]?.conferenceId], k = () => {
1037
+ const c = e.records[n], m = J(e.records, n), f = q(this.data.games, n), g = d[e.teamsById[n]?.conferenceId], k = () => {
1002
1038
  location.href = u(e.hrefs.school, { id: l.id });
1003
1039
  };
1004
- return i`
1040
+ return r`
1005
1041
  <tr class="rowlink" @click=${(O) => {
1006
1042
  O.target.closest("a") || k();
1007
1043
  }}>
@@ -1009,19 +1045,19 @@ class Fe extends y {
1009
1045
  <td>${this.movement(t, s, n)}</td>
1010
1046
  <td class="teamcell">${C(l)}<a href=${u(e.hrefs.school, { id: l.id })}>${l.name}</a>
1011
1047
  <span class="mut" style="font-size:0.78rem">${l.mascot || ""}</span></td>
1012
- <td class="num">${w(d)}</td>
1048
+ <td class="num">${w(c)}</td>
1013
1049
  <td class="mut">${g?.name || "Independent"}</td>
1014
- <td>${m ? i`<a class="box" style="text-decoration:none" href=${u(e.hrefs.game, { sport: this.sport, id: m.gameId })}>
1050
+ <td>${m ? r`<a class="box" style="text-decoration:none" href=${u(e.hrefs.game, { sport: this.sport, id: m.gameId })}>
1015
1051
  <b style="color:${m.mark === "W" ? "var(--hsot-win)" : m.mark === "L" ? "var(--hsot-loss)" : "var(--hsot-tie)"}">${m.mark}</b>
1016
- ${m.my}-${m.their} vs ${A(e, m.opp)}</a>` : i`<span class="mut">·</span>`}</td>
1017
- <td>${oe(e, f, n)}</td>
1018
- <td>${this.sparkline(n, r, o)}</td>
1052
+ ${m.my}-${m.their} vs ${_(e, m.opp)}</a>` : r`<span class="mut">·</span>`}</td>
1053
+ <td>${ie(e, f, n)}</td>
1054
+ <td>${this.sparkline(n, o, i)}</td>
1019
1055
  </tr>
1020
1056
  `;
1021
1057
  }
1022
1058
  }
1023
- globalThis?.customElements && !globalThis.customElements.get("hsot-rankings") && globalThis.customElements.define("hsot-rankings", Fe);
1024
- const ze = b`
1059
+ globalThis?.customElements && !globalThis.customElements.get("hsot-rankings") && globalThis.customElements.define("hsot-rankings", Pe);
1060
+ const Ee = b`
1025
1061
  .schoolhero { color: var(--hsot-white); padding: 1.6rem 1.25rem 1.3rem; }
1026
1062
  .schoolhero .inner { max-width: 1366px; margin: 0 auto; display: flex; gap: 1.2rem; align-items: center; flex-wrap: wrap; }
1027
1063
  .schoolhero .crest {
@@ -1044,12 +1080,16 @@ const ze = b`
1044
1080
  .tile .v { font-family: var(--hsot-heading-font); font-weight: 700; font-size: 1.7rem; line-height: 1.15; color: var(--hsot-black); }
1045
1081
  .tile .s { font-size: 0.78rem; color: var(--hsot-gray-5); }
1046
1082
  .cols { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 1.25rem; }
1083
+ /* The season roster photo heads the roster card, above the table. Natural
1084
+ height: a team photo is never cropped to a box — the card's overflow
1085
+ rounds its top corners. */
1086
+ .rosterphoto { display: block; width: 100%; height: auto; background: var(--hsot-gray-1); border-bottom: 1px solid var(--hsot-gray-2); }
1047
1087
  @media (max-width: 900px) { .cols { grid-template-columns: 1fr; } .schoolhero h1 { font-size: 1.9rem; } }
1048
1088
  `;
1049
- class Be extends y {
1050
- static styles = [...F, ze];
1089
+ class Ae extends $ {
1090
+ static styles = [...F, Ee];
1051
1091
  static properties = {
1052
- ...y.properties,
1092
+ ...$.properties,
1053
1093
  schoolId: { type: String, attribute: "school-id" },
1054
1094
  sport: { type: String },
1055
1095
  season: { type: String },
@@ -1064,26 +1104,26 @@ class Be extends y {
1064
1104
  e && !this.sport && (this.sport = e);
1065
1105
  }
1066
1106
  async fetchData(e) {
1067
- const t = this.season || L(), s = await e.getSchool(this.schoolId), o = (await e.listTeams({ schoolId: this.schoolId })).items, c = o.find((k) => k.sport === (this.sport || "football")) || o[0] || null, [n, h, l, d, m, f, g] = await Promise.all([
1068
- c ? e.listGames({ sport: c.sport, season: t }) : Promise.resolve({ items: [] }),
1069
- c ? e.listTeams({ sport: c.sport }) : Promise.resolve({ items: [] }),
1107
+ const t = this.season || N(), s = await e.getSchool(this.schoolId), i = (await e.listTeams({ schoolId: this.schoolId })).items, d = i.find((k) => k.sport === (this.sport || "football")) || i[0] || null, [n, h, l, c, m, f, g] = await Promise.all([
1108
+ d ? e.listGames({ sport: d.sport, season: t }) : Promise.resolve({ items: [] }),
1109
+ d ? e.listTeams({ sport: d.sport }) : Promise.resolve({ items: [] }),
1070
1110
  e.listSchools(),
1071
1111
  e.listConferences(),
1072
- c ? e.listRankings({ sport: c.sport }) : Promise.resolve({ items: [] }),
1073
- c ? e.listRosters({ teamId: c.id }) : Promise.resolve({ items: [] }),
1112
+ d ? e.listRankings({ sport: d.sport }) : Promise.resolve({ items: [] }),
1113
+ d ? e.listRosters({ teamId: d.id }) : Promise.resolve({ items: [] }),
1074
1114
  // teamId is the public surface's one players filter (roster
1075
1115
  // membership) — never fetch the whole collection.
1076
- c ? e.listPlayers({ teamId: c.id }) : Promise.resolve({ items: [] })
1116
+ d ? e.listPlayers({ teamId: d.id }) : Promise.resolve({ items: [] })
1077
1117
  ]);
1078
1118
  return {
1079
1119
  season: t,
1080
1120
  school: s,
1081
- teams: o,
1082
- active: c,
1121
+ teams: i,
1122
+ active: d,
1083
1123
  games: n.items,
1084
1124
  allTeams: h.items,
1085
1125
  schools: l.items,
1086
- conferences: d.items,
1126
+ conferences: c.items,
1087
1127
  rankings: m.items,
1088
1128
  roster: f.items.find((k) => k.season === t) || null,
1089
1129
  players: g.items
@@ -1103,111 +1143,114 @@ class Be extends y {
1103
1143
  this.sport = e, this.load();
1104
1144
  }
1105
1145
  renderView() {
1106
- const { school: e, teams: t, active: s, season: r } = this.data;
1107
- if (!e) return i`<div class="view"><p class="empty">School not found.</p></div>`;
1108
- const o = this.ctx, c = E(e.colorPrimary || "#030711"), n = (e.adm || [])[0], h = v(this.data.conferences), l = s ? h[s.conferenceId] : null;
1109
- return i`
1110
- <div class="schoolhero" style="background:linear-gradient(115deg, ${e.colorPrimary || "#030711"} 0%, ${e.colorPrimary || "#030711"} 55%, var(--hsot-black) 100%);color:${c}">
1146
+ const { school: e, teams: t, active: s, season: o } = this.data;
1147
+ if (!e) return r`<div class="view"><p class="empty">School not found.</p></div>`;
1148
+ const i = this.ctx, d = E(e.colorPrimary || "#030711"), n = (e.adm || [])[0], h = v(this.data.conferences), l = s ? h[s.conferenceId] : null;
1149
+ return r`
1150
+ <div class="schoolhero" style="background:linear-gradient(115deg, ${e.colorPrimary || "#030711"} 0%, ${e.colorPrimary || "#030711"} 55%, var(--hsot-black) 100%);color:${d}">
1111
1151
  <div class="inner">
1112
- ${_(e, 84) ? i`<img class="crest logo" alt="" loading="lazy" src=${_(e, 84)} />` : i`<div class="crest" style="background:${e.colorSecondary || "#7C7C7C"};color:${E(e.colorSecondary || "#7C7C7C")}">${G(e)}</div>`}
1152
+ ${A(e, 84) ? r`<img class="crest logo" alt="" loading="lazy" src=${A(e, 84)} />` : r`<div class="crest" style="background:${e.colorSecondary || "#7C7C7C"};color:${E(e.colorSecondary || "#7C7C7C")}">${j(e)}</div>`}
1113
1153
  <div style="min-width:260px">
1114
1154
  <h1>${e.name} <span class="mascot">${e.mascot || ""}</span></h1>
1115
1155
  <div class="facts">
1116
- ${e.location ? i`<span><b>Location</b>${e.location}${e.county ? i` · ${e.county} County` : p}</span>` : p}
1117
- ${e.association ? i`<span><b>League</b>${e.association}${e.classification ? i` · ${e.classification}` : p}</span>` : p}
1118
- ${l ? i`<span><b>Conference</b>${l.name}</span>` : p}
1119
- ${n ? i`<span><b>Enrollment</b>${n.value.toLocaleString()} (${n.season} ADM)</span>` : p}
1120
- ${e.openingYear ? i`<span><b>Opened</b>${e.openingYear}</span>` : p}
1121
- ${e.areaCode ? i`<span><b>Area</b>${e.areaCode}</span>` : p}
1156
+ ${e.location ? r`<span><b>Location</b>${e.location}${e.county ? r` · ${e.county} County` : p}</span>` : p}
1157
+ ${e.association ? r`<span><b>League</b>${e.association}${e.classification ? r` · ${e.classification}` : p}</span>` : p}
1158
+ ${l ? r`<span><b>Conference</b>${l.name}</span>` : p}
1159
+ ${n ? r`<span><b>Enrollment</b>${n.value.toLocaleString()} (${n.season} ADM)</span>` : p}
1160
+ ${e.openingYear ? r`<span><b>Opened</b>${e.openingYear}</span>` : p}
1161
+ ${e.areaCode ? r`<span><b>Area</b>${e.areaCode}</span>` : p}
1122
1162
  </div>
1123
1163
  </div>
1124
1164
  </div>
1125
1165
  </div>
1126
1166
  <div class="band">
1127
1167
  <nav class="tabs" aria-label="Teams">
1128
- ${t.map((d) => d.id === s?.id ? i`<a class="on" href="#" @click=${(m) => m.preventDefault()}>${d.name}</a>` : i`<a href="#" @click=${(m) => {
1129
- m.preventDefault(), this.switchSport(d.sport);
1130
- }}>${d.name}</a>`)}
1168
+ ${t.map((c) => c.id === s?.id ? r`<a class="on" href="#" @click=${(m) => m.preventDefault()}>${c.name}</a>` : r`<a href="#" @click=${(m) => {
1169
+ m.preventDefault(), this.switchSport(c.sport);
1170
+ }}>${c.name}</a>`)}
1131
1171
  </nav>
1132
1172
  </div>
1133
- ${B(this, i`
1173
+ ${B(this, r`
1134
1174
  ${P(this)}
1135
- ${s ? this.renderTeam(o, s, l, r) : i`<p class="empty">No teams recorded for this school yet.</p>`}
1175
+ ${s ? this.renderTeam(i, s, l, o) : r`<p class="empty">No teams recorded for this school yet.</p>`}
1136
1176
  `)}
1137
1177
  `;
1138
1178
  }
1139
- renderTeam(e, t, s, r) {
1140
- const o = e.records[t.id] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] }, c = o.w + o.l + o.t, n = s ? this.data.allTeams.filter((m) => m.conferenceId === s.id) : [], h = s ? re(n, e.records).findIndex((m) => m.team.id === t.id) + 1 : 0, l = V(e.rankings, e.teamsById, t.id, t.sport, null), d = this.data.games.filter((m) => m.homeTeamId === t.id || m.awayTeamId === t.id).sort((m, f) => String(m.date).localeCompare(String(f.date)));
1141
- return i`
1179
+ renderTeam(e, t, s, o) {
1180
+ const i = e.records[t.id] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] }, d = i.w + i.l + i.t, n = s ? this.data.allTeams.filter((m) => m.conferenceId === s.id) : [], h = s ? ae(n, e.records).findIndex((m) => m.team.id === t.id) + 1 : 0, l = W(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)));
1181
+ return r`
1142
1182
  <div class="tiles">
1143
- <div class="tile"><div class="k">Overall</div><div class="v">${w(o)}</div><div class="s">${c} games played</div></div>
1144
- <div class="tile"><div class="k">${s?.name || "Conference"}</div><div class="v">${w(o, !0)}</div>
1145
- <div class="s">${h ? `${me(h)} of ${n.length}` : "·"}</div></div>
1146
- <div class="tile"><div class="k">Points</div><div class="v">${c ? (o.pf / c).toFixed(1) : "0.0"}</div>
1147
- <div class="s">scored per game · ${c ? (o.pa / c).toFixed(1) : "0.0"} allowed</div></div>
1148
- <div class="tile"><div class="k">Streak</div><div class="v">${N(o.results) || "·"}</div>
1149
- <div class="s">last 5: ${Q(e, t.id)}</div></div>
1183
+ <div class="tile"><div class="k">Overall</div><div class="v">${w(i)}</div><div class="s">${d} games played</div></div>
1184
+ <div class="tile"><div class="k">${s?.name || "Conference"}</div><div class="v">${w(i, !0)}</div>
1185
+ <div class="s">${h ? `${pe(h)} of ${n.length}` : "·"}</div></div>
1186
+ <div class="tile"><div class="k">Points</div><div class="v">${d ? (i.pf / d).toFixed(1) : "0.0"}</div>
1187
+ <div class="s">scored per game · ${d ? (i.pa / d).toFixed(1) : "0.0"} allowed</div></div>
1188
+ <div class="tile"><div class="k">Streak</div><div class="v">${L(i.results) || "·"}</div>
1189
+ <div class="s">last 5: ${K(e, t.id)}</div></div>
1150
1190
  <div class="tile"><div class="k">HSOT Top 25</div><div class="v">${l ? `#${l}` : "NR"}</div>
1151
1191
  <div class="s"><a href=${u(e.hrefs.section, { sport: t.sport, view: "rankings" })}>full poll</a></div></div>
1152
1192
  </div>
1153
- ${(t.championships || []).length ? i`
1193
+ ${(t.championships || []).length ? r`
1154
1194
  <div style="margin:-0.2rem 0 1rem;display:flex;gap:0.4rem;flex-wrap:wrap">
1155
- ${t.championships.map((m) => i`<span class="pill champ">★ ${m.season} ${m.title} champion${m.classification ? ` · ${m.classification}` : ""}${m.region ? ` · ${m.region}` : ""}</span>`)}
1195
+ ${t.championships.map((m) => r`<span class="pill champ">★ ${m.season} ${m.title} champion${m.classification ? ` · ${m.classification}` : ""}${m.region ? ` · ${m.region}` : ""}</span>`)}
1156
1196
  </div>` : p}
1157
1197
  <div class="cols">
1158
1198
  <div>
1159
1199
  <div class="section-title">Schedule &amp; results</div>
1160
1200
  <div class="card">
1161
- ${d.length ? i`<ul class="gamelist">${d.map((m) => this.renderGameRow(e, t, m))}</ul>` : i`<p class="empty">No ${t.sport} games recorded for ${r}.</p>`}
1201
+ ${c.length ? r`<ul class="gamelist">${c.map((m) => this.renderGameRow(e, t, m))}</ul>` : r`<p class="empty">No ${t.sport} games recorded for ${o}.</p>`}
1162
1202
  </div>
1163
1203
  </div>
1164
1204
  <div>
1165
- <div class="section-title">Roster · ${r}</div>
1166
- <div class="card">${this.renderRoster(r)}</div>
1205
+ <div class="section-title">Roster · ${o}</div>
1206
+ <div class="card">${this.renderRoster(t, o)}</div>
1167
1207
  </div>
1168
1208
  </div>
1169
1209
  `;
1170
1210
  }
1171
1211
  renderGameRow(e, t, s) {
1172
- const r = s.homeTeamId === t.id, o = r ? s.awayTeamId : s.homeTeamId, c = r ? s.homeScore : s.awayScore, n = r ? s.awayScore : s.homeScore;
1173
- let h = i`<span class="mut">${M(s.time)}</span>`;
1212
+ const o = s.homeTeamId === t.id, i = o ? s.awayTeamId : s.homeTeamId, d = o ? s.homeScore : s.awayScore, n = o ? s.awayScore : s.homeScore;
1213
+ let h = r`<span class="mut">${U(s.time)}</span>`;
1174
1214
  if (s.state === "final") {
1175
- const d = q(s), m = d === "tie" ? "T" : d === (r ? "home" : "away") ? "W" : "L";
1176
- h = i`<span class=${m}>${m}</span> ${c}-${n}${s.finish === "overtime" ? i` <span class="mut">OT</span>` : p}${s.forfeit && s.forfeit !== "none" ? i` <span class="mut">FF</span>` : p}`;
1177
- } else s.state === "live" && (h = i`<span style="color:var(--hsot-red)">${c}-${n}</span>`);
1215
+ const c = G(s), m = c === "tie" ? "T" : c === (o ? "home" : "away") ? "W" : "L";
1216
+ h = r`<span class=${m}>${m}</span> ${d}-${n}${s.finish === "overtime" ? r` <span class="mut">OT</span>` : p}${s.forfeit && s.forfeit !== "none" ? r` <span class="mut">FF</span>` : p}`;
1217
+ } else s.state === "live" && (h = r`<span style="color:var(--hsot-red)">${d}-${n}</span>`);
1178
1218
  const l = s.gameType === "conference" ? "Conf" : s.gameType === "nonconference" ? "Non-conf" : s.gameType === "playoff" ? `Playoff${s.label ? ` · ${s.label}` : ""}` : "Scrimmage";
1179
- return i`
1219
+ return r`
1180
1220
  <li>
1181
- <span class="d">${$(s.date)}</span>
1182
- ${se(s).kind === "sched" ? p : R(s)}
1221
+ <span class="d">${y(s.date)}</span>
1222
+ ${te(s).kind === "sched" ? p : R(s)}
1183
1223
  <span class="res">${h}</span>
1184
- <span class="opp">${r ? "vs" : "at"} ${U(e, o, s.date)}
1224
+ <span class="opp">${o ? "vs" : "at"} ${re(e, i, s.date)}
1185
1225
  <span class="pill type">${l}</span>
1186
- ${s.broadcast ? i`<span class="pill class">${s.broadcast}</span>` : p}
1226
+ ${s.broadcast ? r`<span class="pill class">${s.broadcast}</span>` : p}
1187
1227
  </span>
1188
1228
  <span class="where">${s.venue || ""}</span>
1189
1229
  <a class="box" href=${u(e.hrefs.game, { sport: t.sport, id: s.id })}>Box score →</a>
1190
1230
  </li>
1191
1231
  `;
1192
1232
  }
1193
- renderRoster(e) {
1194
- const t = this.data.roster;
1195
- if (!t)
1196
- return i`<p class="empty">Roster not published for ${e}.</p>`;
1197
- const s = v(this.data.players), r = t.entries.slice().sort((o, c) => (o.number || 0) - (c.number || 0));
1198
- return i`
1233
+ renderRoster(e, t) {
1234
+ const s = this.data.roster;
1235
+ if (!s)
1236
+ return r`<p class="empty">Roster not published for ${t}.</p>`;
1237
+ const o = De(s, 560), i = this.data.school?.name || "", d = v(this.data.players), n = s.entries.slice().sort((l, c) => (l.number || 0) - (c.number || 0)), h = n.some((l) => d[l.playerId]?.college);
1238
+ return r`
1239
+ ${o ? r`<img class="rosterphoto" src=${o} loading="lazy" decoding="async"
1240
+ alt="${i} ${e.name} ${t} team photo" />` : p}
1199
1241
  <div class="tablewrap"><table class="data">
1200
- <thead><tr><th class="num">No.</th><th>Player</th><th>Pos</th><th>Class</th><th class="num">Ht</th><th class="num">Wt</th></tr></thead>
1242
+ <thead><tr><th class="num">No.</th><th>Player</th><th>Pos</th><th>Class</th><th class="num">Ht</th><th class="num">Wt</th>${h ? r`<th>College</th>` : p}</tr></thead>
1201
1243
  <tbody>
1202
- ${r.map((o) => {
1203
- const c = s[o.playerId];
1204
- return c ? i`<tr>
1205
- <td class="num mut">${o.number ?? "·"}</td>
1244
+ ${n.map((l) => {
1245
+ const c = d[l.playerId];
1246
+ return c ? r`<tr>
1247
+ <td class="num mut">${l.number ?? "·"}</td>
1206
1248
  <td style="font-weight:500">${c.firstName} ${c.lastName}</td>
1207
- <td>${o.position || "·"}</td>
1249
+ <td>${l.position || "·"}</td>
1208
1250
  <td class="mut">${c.classOf || "·"}</td>
1209
- <td class="num">${de(c.heightIn)}</td>
1251
+ <td class="num">${he(c.heightIn)}</td>
1210
1252
  <td class="num">${c.weightLb || "·"}</td>
1253
+ ${h ? r`<td>${c.college || "·"}</td>` : p}
1211
1254
  </tr>` : p;
1212
1255
  })}
1213
1256
  </tbody>
@@ -1215,16 +1258,16 @@ class Be extends y {
1215
1258
  `;
1216
1259
  }
1217
1260
  }
1218
- globalThis?.customElements && !globalThis.customElements.get("hsot-school") && globalThis.customElements.define("hsot-school", Be);
1219
- const Pe = "https://api.wral.com/search";
1220
- function Ee(a) {
1261
+ globalThis?.customElements && !globalThis.customElements.get("hsot-school") && globalThis.customElements.define("hsot-school", Ae);
1262
+ const _e = "https://api.wral.com/search";
1263
+ function Re(a) {
1221
1264
  return a.map((e) => `uri:"${e}"`).join(" OR ");
1222
1265
  }
1223
- function _e(a, e) {
1224
- const t = String(a || Pe).replace(/\/+$/, ""), s = new URLSearchParams({ query: Ee(e), sort: "score", lang: "en" });
1266
+ function Ne(a, e) {
1267
+ const t = String(a || _e).replace(/\/+$/, ""), s = new URLSearchParams({ query: Re(e), sort: "score", lang: "en" });
1225
1268
  return `${t}/v1/query?${s}`;
1226
1269
  }
1227
- function ie(a) {
1270
+ function ne(a) {
1228
1271
  try {
1229
1272
  const e = new URL(a);
1230
1273
  if (/(^|\.)smugmug\.com$/i.test(e.hostname)) {
@@ -1239,13 +1282,13 @@ function ie(a) {
1239
1282
  }
1240
1283
  return { uri: a, title: a };
1241
1284
  }
1242
- async function Ae(a, e, t) {
1243
- const r = await ((...n) => fetch(...n))(_e(a, e));
1244
- if (!r.ok) throw new Error(`search answered ${r.status}`);
1245
- const o = await r.json(), c = new Map((o.items || []).map((n) => [n.uri, n]));
1246
- return e.map((n) => c.get(n) || ie(n));
1285
+ async function Le(a, e, t) {
1286
+ const o = await ((...n) => fetch(...n))(Ne(a, e));
1287
+ if (!o.ok) throw new Error(`search answered ${o.status}`);
1288
+ const i = await o.json(), d = new Map((i.items || []).map((n) => [n.uri, n]));
1289
+ return e.map((n) => d.get(n) || ne(n));
1247
1290
  }
1248
- const Re = b`
1291
+ const Oe = b`
1249
1292
  .breadcrumbs { font-size: 0.8125rem; margin: 0.9rem 0 0; color: var(--hsot-gray-5); }
1250
1293
  .breadcrumbs a { text-decoration: none; }
1251
1294
  .scorehead { display: grid; grid-template-columns: 1fr auto 1fr; gap: 1rem; align-items: center; padding: 1.4rem 1rem; }
@@ -1284,10 +1327,10 @@ const Re = b`
1284
1327
  .cols { grid-template-columns: 1fr; }
1285
1328
  }
1286
1329
  `;
1287
- class Le extends y {
1288
- static styles = [...F, Re];
1330
+ class He extends $ {
1331
+ static styles = [...F, Oe];
1289
1332
  static properties = {
1290
- ...y.properties,
1333
+ ...$.properties,
1291
1334
  gameId: { type: String, attribute: "game-id" },
1292
1335
  // The public site search that resolves Game.coverageUrls into cards
1293
1336
  // (DEV-1236). Shared cross-stage by design — see the studio host's
@@ -1299,7 +1342,7 @@ class Le extends y {
1299
1342
  super(), this.gameId = "", this.searchApi = "";
1300
1343
  }
1301
1344
  async fetchData(e) {
1302
- const t = await e.getGame(this.gameId), s = Array.isArray(t.coverageUrls) ? t.coverageUrls : [], [r, o, c, n, h, l] = await Promise.all([
1345
+ const t = await e.getGame(this.gameId), s = Array.isArray(t.coverageUrls) ? t.coverageUrls : [], [o, i, d, n, h, l] = await Promise.all([
1303
1346
  e.listSchools(),
1304
1347
  e.listTeams({ sport: t.sport }),
1305
1348
  e.listConferences(),
@@ -1307,13 +1350,13 @@ class Le extends y {
1307
1350
  e.listGames({ sport: t.sport, season: t.season }),
1308
1351
  // A search outage must not blank the box score — degrade to bare
1309
1352
  // links (fetchCoverage already degrades per-URL index misses).
1310
- s.length ? Ae(this.searchApi, s).catch(() => s.map(ie)) : Promise.resolve([])
1353
+ s.length ? Le(this.searchApi, s).catch(() => s.map(ne)) : Promise.resolve([])
1311
1354
  ]);
1312
1355
  return {
1313
1356
  game: t,
1314
- schools: r.items,
1315
- teams: o.items,
1316
- conferences: c.items,
1357
+ schools: o.items,
1358
+ teams: i.items,
1359
+ conferences: d.items,
1317
1360
  rankings: n.items,
1318
1361
  games: h.items,
1319
1362
  coverage: l
@@ -1331,19 +1374,19 @@ class Le extends y {
1331
1374
  }
1332
1375
  renderView() {
1333
1376
  const e = this.data.game;
1334
- if (!e) return i`<div class="view"><p class="empty">Game not found.</p></div>`;
1335
- 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, c = q(e), n = (d) => e.state === "final" && c !== d && c !== "tie" ? "opacity:0.45" : "", h = e.conferenceId ? s[e.conferenceId] : null, l = this.data.games.filter((d) => d.id !== e.id && d.state === "final" && d.gameType !== "scrimmage" && (d.homeTeamId === e.homeTeamId && d.awayTeamId === e.awayTeamId || d.homeTeamId === e.awayTeamId && d.awayTeamId === e.homeTeamId));
1336
- return i`
1337
- ${B(this, i`
1377
+ if (!e) return r`<div class="view"><p class="empty">Game not found.</p></div>`;
1378
+ const t = this.ctx, s = v(this.data.conferences), o = t.teamsById[e.awayTeamId] ? t.schoolsById[t.teamsById[e.awayTeamId].schoolId] : null, i = t.teamsById[e.homeTeamId] ? t.schoolsById[t.teamsById[e.homeTeamId].schoolId] : null, d = G(e), n = (c) => e.state === "final" && d !== c && d !== "tie" ? "opacity:0.45" : "", h = e.conferenceId ? s[e.conferenceId] : null, l = 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));
1379
+ return r`
1380
+ ${B(this, r`
1338
1381
  ${P(this)}
1339
1382
  <p class="breadcrumbs">
1340
- <a href=${u(t.hrefs.section, { sport: e.sport, view: "scores" })}>${T(e.sport)}</a> /
1383
+ <a href=${u(t.hrefs.section, { sport: e.sport, view: "scores" })}>${I(e.sport)}</a> /
1341
1384
  <a href=${u(t.hrefs.section, { sport: e.sport, view: "scores" })}>Scores/Schedules</a> /
1342
- ${I(t, e.awayTeamId)} at ${I(t, e.homeTeamId)}
1385
+ ${T(t, e.awayTeamId)} at ${T(t, e.homeTeamId)}
1343
1386
  </p>
1344
1387
  <div class="card">
1345
1388
  <div class="scorehead">
1346
- ${this.teamBlock(t, e, e.awayTeamId, r, !1)}
1389
+ ${this.teamBlock(t, e, e.awayTeamId, o, !1)}
1347
1390
  <div class="mid">
1348
1391
  <div class="bigscore">
1349
1392
  <span style=${n("away")}>${e.awayScore}</span>
@@ -1351,30 +1394,30 @@ class Le extends y {
1351
1394
  <span style=${n("home")}>${e.homeScore}</span>
1352
1395
  </div>
1353
1396
  <div class="status">${R(e)}</div>
1354
- <div class="status">${$(e.date, { weekday: "short", month: "short", day: "numeric", year: "numeric" })}${e.state === "scheduled" && e.time ? i` · ${M(e.time)}` : p} · ${e.venue || "Venue TBD"}
1355
- ${e.broadcast ? i` · <span class="pill class">${e.broadcast}</span>` : p}</div>
1397
+ <div class="status">${y(e.date, { weekday: "short", month: "short", day: "numeric", year: "numeric" })}${e.state === "scheduled" && e.time ? r` · ${U(e.time)}` : p} · ${e.venue || "Venue TBD"}
1398
+ ${e.broadcast ? r` · <span class="pill class">${e.broadcast}</span>` : p}</div>
1356
1399
  <div class="status">
1357
1400
  <span class="pill type">${e.gameType === "conference" ? `${h?.name || "Conference"} game` : e.gameType}</span>
1358
- ${e.label ? i`<span class="pill type">Bracket ${e.label}</span>` : p}
1359
- ${(e.tags || []).map((d) => i`<span class="pill type">${d}</span>`)}
1401
+ ${e.label ? r`<span class="pill type">Bracket ${e.label}</span>` : p}
1402
+ ${(e.tags || []).map((c) => r`<span class="pill type">${c}</span>`)}
1360
1403
  </div>
1361
1404
  </div>
1362
- ${this.teamBlock(t, e, e.homeTeamId, o, !0)}
1405
+ ${this.teamBlock(t, e, e.homeTeamId, i, !0)}
1363
1406
  </div>
1364
- ${this.renderLineScore(e, r, o)}
1365
- ${e.notes ? i`<p class="note" style="padding:0 1rem 0.9rem;text-align:center">${e.notes}</p>` : p}
1407
+ ${this.renderLineScore(e, o, i)}
1408
+ ${e.notes ? r`<p class="note" style="padding:0 1rem 0.9rem;text-align:center">${e.notes}</p>` : p}
1366
1409
  </div>
1367
- ${(this.data.coverage || []).length ? i`
1410
+ ${(this.data.coverage || []).length ? r`
1368
1411
  <div class="section-title">Coverage</div>
1369
1412
  <div class="covgrid">
1370
- ${this.data.coverage.map((d) => i`
1371
- <a class="card covcard" href=${d.uri}>
1372
- ${d.image ? i`<img class="covimg" src=${d.image} alt="" loading="lazy" />` : p}
1413
+ ${this.data.coverage.map((c) => r`
1414
+ <a class="card covcard" href=${c.uri}>
1415
+ ${c.image ? r`<img class="covimg" src=${c.image} alt="" loading="lazy" />` : p}
1373
1416
  <div class="covbody">
1374
- <div class="covtitle">${d.videoDuration ? i`<span class="pill live" style="animation:none">Video</span> ` : p}${d.photos ? i`<span class="pill live" style="animation:none">Photos</span> ` : p}${d.title || d.uri}</div>
1375
- ${d.description ? i`<p class="covdesc">${d.description}</p>` : p}
1376
- ${d.author || d.publishedTime ? i`
1377
- <div class="covmeta">${[d.author, d.publishedTime ? new Date(d.publishedTime).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }) : ""].filter(Boolean).join(" · ")}</div>
1417
+ <div class="covtitle">${c.videoDuration ? r`<span class="pill live" style="animation:none">Video</span> ` : p}${c.photos ? r`<span class="pill live" style="animation:none">Photos</span> ` : p}${c.title || c.uri}</div>
1418
+ ${c.description ? r`<p class="covdesc">${c.description}</p>` : p}
1419
+ ${c.author || c.publishedTime ? r`
1420
+ <div class="covmeta">${[c.author, c.publishedTime ? new Date(c.publishedTime).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }) : ""].filter(Boolean).join(" · ")}</div>
1378
1421
  ` : p}
1379
1422
  </div>
1380
1423
  </a>
@@ -1382,50 +1425,50 @@ class Le extends y {
1382
1425
  </div>` : p}
1383
1426
  <div class="section-title">Season context</div>
1384
1427
  <div class="cols">
1385
- ${[[e.awayTeamId, r], [e.homeTeamId, o]].map(([d, m]) => this.renderContext(t, d, m))}
1428
+ ${[[e.awayTeamId, o], [e.homeTeamId, i]].map(([c, m]) => this.renderContext(t, c, m))}
1386
1429
  </div>
1387
- ${l.length ? i`
1430
+ ${l.length ? r`
1388
1431
  <div class="section-title">Head to head this season</div>
1389
1432
  <div class="card"><ul class="gamelist">
1390
- ${l.map((d) => i`<li>
1391
- <span class="d">${$(d.date)}</span>${R(d)}
1392
- <span class="opp">${I(t, d.awayTeamId)} ${d.awayScore}, ${I(t, d.homeTeamId)} ${d.homeScore}</span>
1393
- <a class="box" href=${u(t.hrefs.game, { sport: e.sport, id: d.id })}>Box score →</a>
1433
+ ${l.map((c) => r`<li>
1434
+ <span class="d">${y(c.date)}</span>${R(c)}
1435
+ <span class="opp">${T(t, c.awayTeamId)} ${c.awayScore}, ${T(t, c.homeTeamId)} ${c.homeScore}</span>
1436
+ <a class="box" href=${u(t.hrefs.game, { sport: e.sport, id: c.id })}>Box score →</a>
1394
1437
  </li>`)}
1395
1438
  </ul></div>` : p}
1396
1439
  `)}
1397
1440
  `;
1398
1441
  }
1399
- teamBlock(e, t, s, r, o) {
1400
- if (!r) return i`<div class="teamblock ${o ? "right" : ""}"><div class="tname">TBD</div></div>`;
1401
- const c = e.teamsById[s], n = e.records[s], h = _(r, 58);
1402
- return i`
1403
- <div class="teamblock ${o ? "right" : ""}">
1404
- ${h ? i`<img class="crest logo" alt="" loading="lazy" src=${h} />` : i`<span class="crest" style="background:${r.colorPrimary || "#030711"};color:${E(r.colorPrimary || "#030711")}">${G(r)}</span>`}
1442
+ teamBlock(e, t, s, o, i) {
1443
+ if (!o) return r`<div class="teamblock ${i ? "right" : ""}"><div class="tname">TBD</div></div>`;
1444
+ const d = e.teamsById[s], n = e.records[s], h = A(o, 58);
1445
+ return r`
1446
+ <div class="teamblock ${i ? "right" : ""}">
1447
+ ${h ? r`<img class="crest logo" alt="" loading="lazy" src=${h} />` : r`<span class="crest" style="background:${o.colorPrimary || "#030711"};color:${E(o.colorPrimary || "#030711")}">${j(o)}</span>`}
1405
1448
  <div>
1406
- <div class="tname">${K(e, s, t.date)}<a href=${u(e.hrefs.school, { id: r.id })}>${r.name}</a></div>
1407
- <div class="trec">${r.mascot || ""} · ${w(n)}${c?.conferenceId ? i` · ${w(n, !0)} conf` : p}</div>
1449
+ <div class="tname">${Y(e, s, t.date)}<a href=${u(e.hrefs.school, { id: o.id })}>${o.name}</a></div>
1450
+ <div class="trec">${o.mascot || ""} · ${w(n)}${d?.conferenceId ? r` · ${w(n, !0)} conf` : p}</div>
1408
1451
  </div>
1409
1452
  </div>
1410
1453
  `;
1411
1454
  }
1412
1455
  renderLineScore(e, t, s) {
1413
- const r = e.periodScores || [];
1414
- if (!r.length)
1415
- return i`<p class="empty" style="text-align:center">Period scoring will appear once the game starts.</p>`;
1416
- const o = Math.max(4, ...r.map((l) => l.period)), c = (l) => l <= 4 ? String(l) : `OT${l > 5 ? l - 4 : ""}`, n = (l, d) => {
1417
- const m = r.find((f) => f.period === d);
1456
+ const o = e.periodScores || [];
1457
+ if (!o.length)
1458
+ return r`<p class="empty" style="text-align:center">Period scoring will appear once the game starts.</p>`;
1459
+ const i = Math.max(4, ...o.map((l) => l.period)), d = (l) => l <= 4 ? String(l) : `OT${l > 5 ? l - 4 : ""}`, n = (l, c) => {
1460
+ const m = o.find((f) => f.period === c);
1418
1461
  return m ? m[l] : e.state === "final" ? 0 : "·";
1419
- }, h = (l, d, m) => i`
1462
+ }, h = (l, c, m) => r`
1420
1463
  <tr>
1421
1464
  <td class="teamcell">${C(l, 20)}${l?.abbr || "TBD"}</td>
1422
- ${Array.from({ length: o }, (f, g) => i`<td class="num">${n(d, g + 1)}</td>`)}
1465
+ ${Array.from({ length: i }, (f, g) => r`<td class="num">${n(c, g + 1)}</td>`)}
1423
1466
  <td class="num" style="font-weight:700">${m}</td>
1424
1467
  </tr>`;
1425
- return i`
1468
+ return r`
1426
1469
  <div class="tablewrap" style="border-top:1px solid var(--hsot-gray-2)">
1427
1470
  <table class="data" style="max-width:560px;margin:0.6rem auto 0.9rem">
1428
- <thead><tr><th>Team</th>${Array.from({ length: o }, (l, d) => i`<th class="num">${c(d + 1)}</th>`)}<th class="num">T</th></tr></thead>
1471
+ <thead><tr><th>Team</th>${Array.from({ length: i }, (l, c) => r`<th class="num">${d(c + 1)}</th>`)}<th class="num">T</th></tr></thead>
1429
1472
  <tbody>
1430
1473
  ${h(t, "away", e.awayScore)}
1431
1474
  ${h(s, "home", e.homeScore)}
@@ -1436,24 +1479,24 @@ class Le extends y {
1436
1479
  }
1437
1480
  renderContext(e, t, s) {
1438
1481
  if (!s) return p;
1439
- const r = e.records[t], o = W(this.data.games, t);
1440
- return i`
1482
+ const o = e.records[t], i = q(this.data.games, t);
1483
+ return r`
1441
1484
  <div class="card ctxcard">
1442
1485
  <div class="who">${C(s)}${s.name}</div>
1443
1486
  <div class="row">
1444
- <span>Last 5: ${Q(e, t)}</span>
1445
- <span>Streak: <b>${r ? N(r.results) : "·"}</b></span>
1446
- <span>PF/PA: <b>${r ? `${r.pf} / ${r.pa}` : "·"}</b></span>
1447
- <span>Next: ${o ? i`${$(o.date, { month: "numeric", day: "numeric" })}
1448
- ${o.homeTeamId === t ? "vs" : "at"} ${A(e, o.homeTeamId === t ? o.awayTeamId : o.homeTeamId)}` : "·"}</span>
1487
+ <span>Last 5: ${K(e, t)}</span>
1488
+ <span>Streak: <b>${o ? L(o.results) : "·"}</b></span>
1489
+ <span>PF/PA: <b>${o ? `${o.pf} / ${o.pa}` : "·"}</b></span>
1490
+ <span>Next: ${i ? r`${y(i.date, { month: "numeric", day: "numeric" })}
1491
+ ${i.homeTeamId === t ? "vs" : "at"} ${_(e, i.homeTeamId === t ? i.awayTeamId : i.homeTeamId)}` : "·"}</span>
1449
1492
  </div>
1450
1493
  </div>
1451
1494
  `;
1452
1495
  }
1453
1496
  }
1454
- globalThis?.customElements && !globalThis.customElements.get("hsot-boxscore") && globalThis.customElements.define("hsot-boxscore", Le);
1455
- const Ne = 250, Oe = 2;
1456
- class He extends te {
1497
+ globalThis?.customElements && !globalThis.customElements.get("hsot-boxscore") && globalThis.customElements.define("hsot-boxscore", He);
1498
+ const Ue = 250, Me = 2;
1499
+ class je extends ee {
1457
1500
  static properties = {
1458
1501
  api: { type: String },
1459
1502
  schoolHref: { type: String, attribute: "school-href" },
@@ -1533,11 +1576,11 @@ class He extends te {
1533
1576
  }
1534
1577
  onInput(e) {
1535
1578
  const t = e.target.value.trim();
1536
- if (clearTimeout(this.debounceTimer), t.length < Oe) {
1579
+ if (clearTimeout(this.debounceTimer), t.length < Me) {
1537
1580
  this.abortController?.abort(), this.results = [], this.open = !1, this.searched = !1;
1538
1581
  return;
1539
1582
  }
1540
- this.debounceTimer = setTimeout(() => this.search(t), Ne);
1583
+ this.debounceTimer = setTimeout(() => this.search(t), Ue);
1541
1584
  }
1542
1585
  async search(e) {
1543
1586
  this.abortController?.abort(), this.abortController = new AbortController();
@@ -1547,8 +1590,8 @@ class He extends te {
1547
1590
  });
1548
1591
  if (!s.ok)
1549
1592
  return;
1550
- const r = await s.json();
1551
- this.results = r.items || [], this.activeIndex = -1, this.searched = !0, this.open = !0;
1593
+ const o = await s.json();
1594
+ this.results = o.items || [], this.activeIndex = -1, this.searched = !0, this.open = !0;
1552
1595
  } catch (t) {
1553
1596
  t.name !== "AbortError" && console.warn("school search failed", t);
1554
1597
  }
@@ -1582,36 +1625,36 @@ class He extends te {
1582
1625
  return [e.location, e.county && `${e.county} County`].filter(Boolean).join(" — ");
1583
1626
  }
1584
1627
  renderOption(e, t) {
1585
- const s = this.where(e), r = (o) => {
1586
- o.preventDefault(), this.go(e);
1628
+ const s = this.where(e), o = (i) => {
1629
+ i.preventDefault(), this.go(e);
1587
1630
  };
1588
- return i`
1631
+ return r`
1589
1632
  <li
1590
1633
  id="school-option-${t}"
1591
1634
  role="option"
1592
1635
  aria-selected="${t === this.activeIndex ? "true" : "false"}"
1593
- @pointerdown="${r}"
1636
+ @pointerdown="${o}"
1594
1637
  @mousemove="${() => {
1595
1638
  this.activeIndex = t;
1596
1639
  }}"
1597
1640
  >
1598
1641
  <span class="name">${e.name}</span>
1599
- ${s ? i`<span class="where">${s}</span>` : p}
1642
+ ${s ? r`<span class="where">${s}</span>` : p}
1600
1643
  </li>
1601
1644
  `;
1602
1645
  }
1603
1646
  renderListbox() {
1604
- const e = this.searched && !this.results.length, t = i`<li class="empty">No schools found</li>`;
1605
- return i`
1647
+ const e = this.searched && !this.results.length, t = r`<li class="empty">No schools found</li>`;
1648
+ return r`
1606
1649
  <ul id="school-search-listbox" role="listbox" aria-label="Schools">
1607
- ${this.results.map((s, r) => this.renderOption(s, r))}
1650
+ ${this.results.map((s, o) => this.renderOption(s, o))}
1608
1651
  ${e ? t : p}
1609
1652
  </ul>
1610
1653
  `;
1611
1654
  }
1612
1655
  render() {
1613
1656
  const e = this.activeIndex >= 0 ? `school-option-${this.activeIndex}` : "";
1614
- return i`
1657
+ return r`
1615
1658
  <input
1616
1659
  type="text"
1617
1660
  role="combobox"
@@ -1630,23 +1673,23 @@ class He extends te {
1630
1673
  `;
1631
1674
  }
1632
1675
  }
1633
- globalThis?.customElements && !globalThis.customElements.get("hsot-school-search") && globalThis.customElements.define("hsot-school-search", He);
1676
+ globalThis?.customElements && !globalThis.customElements.get("hsot-school-search") && globalThis.customElements.define("hsot-school-search", je);
1634
1677
  export {
1635
1678
  H as D,
1636
- Le as H,
1637
- Fe as a,
1638
- Be as b,
1639
- He as c,
1640
- Se as d,
1641
- Ce as e,
1679
+ He as H,
1680
+ Pe as a,
1681
+ Ae as b,
1682
+ je as c,
1683
+ Fe as d,
1684
+ ze as e,
1642
1685
  z as f,
1643
- ce as g,
1686
+ de as g,
1644
1687
  u as h,
1645
- q as i,
1646
- Me as j,
1647
- N as k,
1648
- Te as p,
1688
+ G as i,
1689
+ qe as j,
1690
+ L as k,
1691
+ Se as p,
1649
1692
  w as r,
1650
- re as s,
1651
- V as t
1693
+ ae as s,
1694
+ W as t
1652
1695
  };