@wral/hsot-data 0.1.4 → 0.1.5

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,32 +1,32 @@
1
- import { LitElement as ee, html as l, css as y, nothing as p, svg as q } from "lit";
2
- const te = 50;
3
- function se(a = {}) {
1
+ import { LitElement as ae, html as l, css as y, nothing as p, svg as Y } from "lit";
2
+ const re = 50;
3
+ function oe(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
7
  return e.forEach(([s, r]) => t.set(s, String(r))), `?${t.toString()}`;
8
8
  }
9
- function ae({ baseUrl: a, token: e = "", fetchFn: t } = {}) {
9
+ function ne({ baseUrl: a, token: e = "", fetchFn: t } = {}) {
10
10
  if (!a) throw new Error("createClient requires a baseUrl");
11
11
  const s = a.replace(/\/+$/, ""), r = t || ((...i) => fetch(...i));
12
12
  async function o(i) {
13
- const m = { Accept: "application/json" };
14
- e && (m.Authorization = `Bearer ${e}`);
15
- const d = await r(`${s}${i}`, { headers: m });
16
- if (!d.ok) {
17
- const c = new Error(`api-hsot ${d.status} on ${i}`);
18
- throw c.status = d.status, c;
13
+ const d = { Accept: "application/json" };
14
+ e && (d.Authorization = `Bearer ${e}`);
15
+ const h = await r(`${s}${i}`, { headers: d });
16
+ if (!h.ok) {
17
+ const c = new Error(`api-hsot ${h.status} on ${i}`);
18
+ throw c.status = h.status, c;
19
19
  }
20
- return d.json();
20
+ return h.json();
21
21
  }
22
- async function n(i, m = {}) {
23
- const d = [];
22
+ async function n(i, d = {}) {
23
+ const h = [];
24
24
  let c = null;
25
- for (let h = 0; h < te; h += 1) {
26
- const f = se(c ? { ...m, cursor: c } : m), u = await o(`${i}${f}`);
27
- if (d.push(...u.items || []), c = u.nextCursor || null, !c) break;
25
+ for (let m = 0; m < re; m += 1) {
26
+ const f = oe(c ? { ...d, cursor: c } : d), g = await o(`${i}${f}`);
27
+ if (h.push(...g.items || []), c = g.nextCursor || null, !c) break;
28
28
  }
29
- return { items: d, total: d.length, nextCursor: null };
29
+ return { items: h, total: h.length, nextCursor: null };
30
30
  }
31
31
  return {
32
32
  listSchools: (i) => n("/schools", i),
@@ -39,12 +39,116 @@ function ae({ baseUrl: a, token: e = "", fetchFn: t } = {}) {
39
39
  listGames: (i) => n("/games", i),
40
40
  getGame: (i) => o(`/games/${i}`),
41
41
  listTournaments: (i) => n("/tournaments", i),
42
- listSeedings: (i, m) => n(`/tournaments/${i}/seedings`, m),
42
+ listSeedings: (i, d) => n(`/tournaments/${i}/seedings`, d),
43
43
  listRankings: (i) => n("/rankings", i),
44
44
  listSports: () => o("/sports")
45
45
  };
46
46
  }
47
- class b extends ee {
47
+ const O = {
48
+ game: "/{sport}/game/{id}/",
49
+ school: "/school/{id}/",
50
+ section: "/{sport}/{view}/"
51
+ };
52
+ function u(a, e) {
53
+ return String(a).replace(/\{(\w+)\}/g, (t, s) => e[s] !== void 0 && e[s] !== null ? String(e[s]) : t);
54
+ }
55
+ function D(a) {
56
+ 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
60
+ };
61
+ }
62
+ const T = (a) => a ? a.charAt(0).toUpperCase() + a.slice(1) : "";
63
+ function b(a, e) {
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" });
67
+ }
68
+ function A(a) {
69
+ if (!a) return "";
70
+ const [e, t] = String(a).split(":").map(Number);
71
+ if (Number.isNaN(e)) return "";
72
+ const s = e >= 12 ? "PM" : "AM";
73
+ return `${(e + 11) % 12 + 1}:${String(t || 0).padStart(2, "0")} ${s}`;
74
+ }
75
+ function ie(a) {
76
+ return a ? `${Math.floor(a / 12)}-${a % 12}` : "·";
77
+ }
78
+ function E(a = /* @__PURE__ */ new Date()) {
79
+ const e = a.getFullYear();
80
+ return a.getMonth() >= 6 ? `${e}-${e + 1}` : `${e - 1}-${e}`;
81
+ }
82
+ function U(a = /* @__PURE__ */ new Date()) {
83
+ const e = (t) => String(t).padStart(2, "0");
84
+ return `${a.getFullYear()}-${e(a.getMonth() + 1)}-${e(a.getDate())}`;
85
+ }
86
+ function M(a) {
87
+ return a ? (a.abbr || a.name || "?").slice(0, 4).toUpperCase() : "?";
88
+ }
89
+ function B(a) {
90
+ if (!a || !/^#[0-9a-fA-F]{6}$/.test(a)) return "#FFFFFF";
91
+ const e = parseInt(a.slice(1), 16), t = e >> 16 & 255, s = e >> 8 & 255, r = e & 255;
92
+ return 0.299 * t + 0.587 * s + 0.114 * r > 150 ? "#0F1B33" : "#FFFFFF";
93
+ }
94
+ const le = (a) => {
95
+ const e = ["th", "st", "nd", "rd"], t = a % 100;
96
+ return a + (e[(t - 20) % 10] || e[t] || e[0]);
97
+ };
98
+ function ce(a) {
99
+ if (a.state === "live") return { kind: "live", label: `Live · ${a.period || ""}`.replace(/ · $/, "") };
100
+ if (a.state === "final") {
101
+ const e = [];
102
+ 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(" · ")}` : ""}` };
103
+ }
104
+ return a.state === "postponed" ? { kind: "warn", label: "Postponed" } : a.state === "canceled" ? { kind: "warn", label: "Canceled" } : { kind: "sched", label: `${b(a.date, { month: "short", day: "numeric" })} · ${A(a.time)}`.replace(/ · $/, "") };
105
+ }
106
+ const de = /* @__PURE__ */ new Set(["game", "story", "page", "forum", "video", "gallery"]);
107
+ function x(a) {
108
+ let e = String(a || "").replace(/^[a-z][a-z0-9+.-]*:\/\/[^/#?]*/i, "");
109
+ const t = e.indexOf("#");
110
+ let s = "";
111
+ t !== -1 && (s = e.slice(t).split("?")[0], e = e.slice(0, t));
112
+ let r = e.split("?")[0] + s;
113
+ return r = r.replace(/([^:])\/{2,}/g, "$1/").replace(/^\/{2,}/, "/"), r = r.replace(/^\/(?=#)/, ""), r.length > 1 && (r = r.replace(/\/+$/, "")), r.toLowerCase();
114
+ }
115
+ function Z() {
116
+ const a = globalThis.location;
117
+ if (!a) return "";
118
+ const e = (a.hash || "").startsWith("#/") ? a.hash : "";
119
+ return x((a.pathname || "") + e);
120
+ }
121
+ function he(a, e, t) {
122
+ if (!t) return null;
123
+ const s = x(a);
124
+ if (!s) return null;
125
+ const r = x(u(e.game, { sport: t, id: "" })), o = x(u(e.school, { id: "" }));
126
+ if (s === r || s.startsWith(`${r}/`) || s === o || s.startsWith(`${o}/`)) return null;
127
+ const n = x(u(e.section, { sport: t, view: "" }));
128
+ if (s === n) return "";
129
+ if (!s.startsWith(`${n}/`)) return null;
130
+ const i = s.slice(n.length + 1), d = i.split("/");
131
+ return d.length > 2 || d.some((h) => !/^[a-z][a-z-]*$/.test(h)) || de.has(d[0]) ? null : i;
132
+ }
133
+ function me(a, e, t) {
134
+ const s = (n) => u(t.section, { sport: a, view: n }).replace(/([^:])\/{2,}/g, "$1/"), o = new Set((e || []).map((n) => n && n.gender).filter((n) => n === "boys" || n === "girls")).size === 2 ? [
135
+ { label: "Boys Standings", href: s("boys/standings") },
136
+ { label: "Girls Standings", href: s("girls/standings") }
137
+ ] : [{ label: "Standings", href: s("standings") }];
138
+ return [
139
+ { label: `${T(a)} Home`, href: s("") },
140
+ { label: "Scores/Schedule", href: s("scores") },
141
+ { label: "Playoff Brackets", href: s("brackets") },
142
+ ...o,
143
+ { label: "Polls & Rankings", href: s("rankings") }
144
+ ];
145
+ }
146
+ function pe(a, e = Z()) {
147
+ const t = x(e);
148
+ for (const s of a.querySelectorAll(':scope > a[slot="nav"]'))
149
+ t && x(s.getAttribute("href")) === t ? s.setAttribute("aria-current", "page") : s.removeAttribute("aria-current");
150
+ }
151
+ class $ extends ae {
48
152
  static properties = {
49
153
  api: { type: String },
50
154
  refreshInterval: { type: Number, attribute: "refresh-interval" },
@@ -60,7 +164,7 @@ class b extends ee {
60
164
  this._client = e, this.isConnected && this.load();
61
165
  }
62
166
  get client() {
63
- return this._client ? this._client : this.api ? ae({ baseUrl: this.api }) : null;
167
+ return this._client ? this._client : this.api ? ne({ baseUrl: this.api }) : null;
64
168
  }
65
169
  connectedCallback() {
66
170
  super.connectedCallback(), this._setupInterval();
@@ -72,7 +176,7 @@ class b extends ee {
72
176
  this.load();
73
177
  }
74
178
  updated(e) {
75
- e.has("api") && e.get("api") !== void 0 && e.get("api") !== this.api && this.load(), e.has("refreshInterval") && this._setupInterval();
179
+ e.has("api") && e.get("api") !== void 0 && e.get("api") !== this.api && this.load(), e.has("refreshInterval") && this._setupInterval(), pe(this);
76
180
  }
77
181
  async load() {
78
182
  const e = this.client;
@@ -107,7 +211,7 @@ class b extends ee {
107
211
  return l``;
108
212
  }
109
213
  }
110
- const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), re = y`
214
+ const v = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), fe = y`
111
215
  :host {
112
216
  --hsot-red: var(--color-red, #D1232A);
113
217
  --hsot-red-deep: var(--color-red-dark, #951C21);
@@ -125,6 +229,10 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), re = y`
125
229
  --hsot-win: var(--color-green-dark, #66A208);
126
230
  --hsot-loss: var(--color-red, #D1232A);
127
231
  --hsot-tie: var(--color-gray-4, #7C7C7C);
232
+ --hsot-section-bg: var(--color-section-header, #1A1A1A);
233
+ --hsot-section-text: var(--color-section-header-text, #FFFFFF);
234
+ --hsot-section-divider: var(--color-section-header-divider, rgba(255, 255, 255, 0.2));
235
+ --hsot-section-red: #B90100;
128
236
  --hsot-heading-font: var(--heading-font-family, 'IBM Plex Sans Condensed', 'Helvetica Neue', Helvetica, sans-serif);
129
237
  --hsot-body-font: var(--body-font-family, Roboto, 'Helvetica Neue', Helvetica, sans-serif);
130
238
  --hsot-radius-xs: var(--radius-xs, 0.15rem);
@@ -141,7 +249,7 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), re = y`
141
249
  outline-offset: 1px;
142
250
  }
143
251
  .mut { color: var(--hsot-gray-5); }
144
- `, oe = y`
252
+ `, ue = y`
145
253
  .band { background: var(--hsot-white); color: var(--hsot-black); }
146
254
  .band .inner { max-width: 1366px; margin: 0 auto; padding: 1.1rem 1.25rem 0; }
147
255
  .band h1, .band h2.bandtitle {
@@ -160,8 +268,37 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), re = y`
160
268
  }
161
269
  .band nav.tabs a.on { border-bottom-color: var(--hsot-red); }
162
270
  .band nav.tabs span.off { color: var(--hsot-gray-4); cursor: not-allowed; }
163
- @media (max-width: 720px) { .band h1, .band h2.bandtitle { font-size: 1.8rem; } }
164
- `, ie = y`
271
+ /* Section-front treatment, matching the site's hsot-section-header: dark
272
+ band, red baseline, sub-nav row of section links. The section tokens
273
+ inherit from the page when it defines the --color-section-header set. */
274
+ .band.section {
275
+ background: var(--hsot-section-bg); color: var(--hsot-section-text);
276
+ border-bottom: 3px solid var(--hsot-section-red);
277
+ }
278
+ .band.section .inner { padding: 1.25rem; }
279
+ .band.section h1, .band.section h2.bandtitle {
280
+ color: inherit; font-size: 2.875rem; font-weight: 700; line-height: 1;
281
+ }
282
+ .band.section .sub { color: #CFCFCF; margin: 0.4rem 0 0; }
283
+ nav.sectionnav { border-top: 1px solid var(--hsot-section-divider); }
284
+ .sectionnav .navrow {
285
+ display: flex; gap: 1rem; max-width: 1366px; margin: 0 auto;
286
+ padding: 0 1.25rem; overflow-x: auto; box-sizing: border-box;
287
+ }
288
+ .sectionnav a, .sectionnav ::slotted(a) {
289
+ font-family: var(--hsot-heading-font); font-weight: 500; font-size: 0.875rem;
290
+ line-height: 1.5rem; text-transform: uppercase; text-decoration: none;
291
+ white-space: nowrap; padding: 0.5rem; color: #CFCFCF;
292
+ border-bottom: 2px solid transparent; transition: color 0.15s, border-color 0.15s;
293
+ }
294
+ .sectionnav a:hover, .sectionnav a:focus-visible, .sectionnav a[aria-current="page"],
295
+ .sectionnav ::slotted(a:hover), .sectionnav ::slotted(a:focus-visible), .sectionnav ::slotted(a[aria-current="page"]) {
296
+ color: var(--hsot-section-text); border-bottom-color: var(--hsot-section-red);
297
+ }
298
+ @media (max-width: 720px) {
299
+ .band h1, .band h2.bandtitle, .band.section h1, .band.section h2.bandtitle { font-size: 1.8rem; }
300
+ }
301
+ `, ge = y`
165
302
  .view { max-width: 1366px; margin: 0 auto; padding: 1.25rem; box-sizing: border-box; }
166
303
  .toolbar { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; margin: 0 0 1.1rem; }
167
304
  .toolbar .spacer { flex: 1; }
@@ -204,7 +341,7 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), re = y`
204
341
  .error { padding: 1.2rem 1rem; color: var(--hsot-red-deep); font-size: 0.9rem; }
205
342
  .note { font-size: 0.8125rem; color: var(--hsot-gray-5); margin: 0.6rem 0 0; }
206
343
  .loading { padding: 1.2rem; color: var(--hsot-gray-5); font-family: var(--hsot-heading-font); }
207
- `, ne = y`
344
+ `, ve = y`
208
345
  .pill {
209
346
  display: inline-block; font-family: var(--hsot-heading-font); font-weight: 700;
210
347
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em;
@@ -219,7 +356,7 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), re = y`
219
356
  .pill.champ { background: var(--hsot-straw); color: #6b5900; }
220
357
  @keyframes hsot-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
221
358
  @media (prefers-reduced-motion: reduce) { .pill.live { animation: none; } }
222
- `, le = y`
359
+ `, be = y`
223
360
  .tablewrap { overflow-x: auto; }
224
361
  table.data { font-family: var(--hsot-heading-font); font-size: 14px; border-collapse: collapse; width: 100%; }
225
362
  table.data th {
@@ -237,7 +374,7 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), re = y`
237
374
  table.data tbody tr.rowlink:hover { background: var(--hsot-gray-1); }
238
375
  table.data td.teamcell a { color: inherit; text-decoration: none; font-weight: 500; }
239
376
  table.data td.teamcell a:hover { text-decoration: underline; }
240
- `, ce = y`
377
+ `, $e = y`
241
378
  .swatch {
242
379
  display: inline-flex; align-items: center; justify-content: center;
243
380
  width: 26px; height: 26px; border-radius: 50%;
@@ -261,7 +398,7 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), re = y`
261
398
  .dot.W { background: var(--hsot-win); }
262
399
  .dot.L { background: var(--hsot-loss); }
263
400
  .dot.T { background: var(--hsot-tie); }
264
- `, de = y`
401
+ `, ye = y`
265
402
  ul.gamelist { list-style: none; margin: 0; padding: 0; }
266
403
  .gamelist li {
267
404
  display: flex; align-items: center; gap: 0.7rem; padding: 0.55rem 1rem;
@@ -278,136 +415,77 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), re = y`
278
415
  .gamelist .opp a:hover { text-decoration: underline; }
279
416
  .gamelist .where { color: var(--hsot-gray-5); font-size: 0.78rem; }
280
417
  .gamelist a.box { font-size: 0.78rem; }
281
- `, S = [re, oe, ie, ne, le, ce, de];
418
+ `, F = [fe, ue, ge, ve, be, $e, ye];
282
419
  function j(a) {
283
420
  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";
284
421
  }
285
- function D(a, e) {
422
+ function z(a, e) {
286
423
  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, n) => String(o.date).localeCompare(String(n.date)));
287
424
  for (const o of r) {
288
425
  const n = j(o), i = o.gameType === "conference";
289
- for (const m of ["home", "away"]) {
290
- const d = m === "home" ? o.homeTeamId : o.awayTeamId;
291
- if (!d) continue;
292
- const c = s(d), h = m === "home" ? o.homeScore : o.awayScore, f = m === "home" ? o.awayScore : o.homeScore;
293
- c.pf += h, c.pa += f;
294
- let u = "T";
295
- n === "tie" ? (c.t += 1, i && (c.ct += 1)) : n === m ? (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: h, their: f, opp: m === "home" ? o.awayTeamId : o.homeTeamId, conf: i });
426
+ for (const d of ["home", "away"]) {
427
+ const h = d === "home" ? o.homeTeamId : o.awayTeamId;
428
+ if (!h) continue;
429
+ const c = s(h), m = d === "home" ? o.homeScore : o.awayScore, f = d === "home" ? o.awayScore : o.homeScore;
430
+ c.pf += m, c.pa += f;
431
+ let g = "T";
432
+ n === "tie" ? (c.t += 1, i && (c.ct += 1)) : n === d ? (c.w += 1, i && (c.cw += 1), g = "W") : (c.l += 1, i && (c.cl += 1), g = "L"), c.results.push({ gameId: o.id, date: o.date, mark: g, my: m, their: f, opp: d === "home" ? o.awayTeamId : o.homeTeamId, conf: i });
296
433
  }
297
434
  }
298
435
  return t;
299
436
  }
300
- function _(a) {
437
+ function L(a) {
301
438
  if (!a || !a.length) return "";
302
439
  const e = a[a.length - 1].mark;
303
440
  let t = 0;
304
441
  for (let s = a.length - 1; s >= 0 && a[s].mark === e; s -= 1) t += 1;
305
442
  return e + t;
306
443
  }
307
- const V = (a, e, t) => {
444
+ const Q = (a, e, t) => {
308
445
  const s = a + e + t;
309
446
  return s ? (a + t / 2) / s : 0;
310
- }, Y = (a) => a.toFixed(3).replace("0.", ".");
447
+ }, K = (a) => a.toFixed(3).replace("0.", ".");
311
448
  function w(a, e = !1) {
312
449
  if (!a) return "0-0";
313
450
  const t = e ? a.cw : a.w, s = e ? a.cl : a.l, r = e ? a.ct : a.t;
314
451
  return `${t}-${s}${r ? `-${r}` : ""}`;
315
452
  }
316
- function K(a, e) {
453
+ function J(a, e) {
317
454
  return a.map((t) => {
318
455
  const s = e[t.id] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] };
319
- return { team: t, rec: s, confPct: V(s.cw, s.cl, s.ct), overallPct: V(s.w, s.l, s.t) };
456
+ return { team: t, rec: s, confPct: Q(s.cw, s.cl, s.ct), overallPct: Q(s.w, s.l, s.t) };
320
457
  }).sort((t, s) => s.confPct - t.confPct || s.overallPct - t.overallPct || s.rec.pf - s.rec.pa - (t.rec.pf - t.rec.pa));
321
458
  }
322
- function H(a, e) {
459
+ function G(a, e) {
323
460
  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;
324
461
  }
325
- function Q(a, e) {
462
+ function X(a, e) {
326
463
  const t = a[e];
327
464
  return t && t.results.length ? t.results[t.results.length - 1] : null;
328
465
  }
329
- const N = {
330
- game: "/{sport}/game/{id}/",
331
- school: "/school/{id}/",
332
- section: "/{sport}/{view}/"
333
- };
334
- function v(a, e) {
335
- return String(a).replace(/\{(\w+)\}/g, (t, s) => e[s] !== void 0 && e[s] !== null ? String(e[s]) : t);
336
- }
337
- function C(a) {
338
- return {
339
- game: a.getAttribute("game-href") || N.game,
340
- school: a.getAttribute("school-href") || N.school,
341
- section: a.getAttribute("section-href") || N.section
342
- };
343
- }
344
- const R = (a) => a ? a.charAt(0).toUpperCase() + a.slice(1) : "";
345
- function $(a, e) {
346
- if (!a) return "TBD";
347
- const [t, s, r] = String(a).split("-").map(Number);
348
- return !t || !s || !r ? "TBD" : new Date(t, s - 1, r).toLocaleDateString("en-US", e || { weekday: "short", month: "short", day: "numeric" });
349
- }
350
- function E(a) {
351
- if (!a) return "";
352
- const [e, t] = String(a).split(":").map(Number);
353
- if (Number.isNaN(e)) return "";
354
- const s = e >= 12 ? "PM" : "AM";
355
- return `${(e + 11) % 12 + 1}:${String(t || 0).padStart(2, "0")} ${s}`;
356
- }
357
- function he(a) {
358
- return a ? `${Math.floor(a / 12)}-${a % 12}` : "·";
359
- }
360
- function A(a = /* @__PURE__ */ new Date()) {
361
- const e = a.getFullYear();
362
- return a.getMonth() >= 6 ? `${e}-${e + 1}` : `${e - 1}-${e}`;
363
- }
364
- function O(a = /* @__PURE__ */ new Date()) {
365
- const e = (t) => String(t).padStart(2, "0");
366
- return `${a.getFullYear()}-${e(a.getMonth() + 1)}-${e(a.getDate())}`;
367
- }
368
- function M(a) {
369
- return a ? (a.abbr || a.name || "?").slice(0, 4).toUpperCase() : "?";
370
- }
371
- function F(a) {
372
- if (!a || !/^#[0-9a-fA-F]{6}$/.test(a)) return "#FFFFFF";
373
- const e = parseInt(a.slice(1), 16), t = e >> 16 & 255, s = e >> 8 & 255, r = e & 255;
374
- return 0.299 * t + 0.587 * s + 0.114 * r > 150 ? "#0F1B33" : "#FFFFFF";
375
- }
376
- const me = (a) => {
377
- const e = ["th", "st", "nd", "rd"], t = a % 100;
378
- return a + (e[(t - 20) % 10] || e[t] || e[0]);
379
- };
380
- function pe(a) {
381
- if (a.state === "live") return { kind: "live", label: `Live · ${a.period || ""}`.replace(/ · $/, "") };
382
- if (a.state === "final") {
383
- const e = [];
384
- 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(" · ")}` : ""}` };
385
- }
386
- return a.state === "postponed" ? { kind: "warn", label: "Postponed" } : a.state === "canceled" ? { kind: "warn", label: "Canceled" } : { kind: "sched", label: `${$(a.date, { month: "short", day: "numeric" })} · ${E(a.time)}`.replace(/ · $/, "") };
387
- }
388
- function Fe(a, e, t, s = "") {
466
+ function Ee(a, e, t, s = "") {
389
467
  let r = null;
390
468
  for (const o of a || [])
391
469
  o.sport === e && (t && o.effectiveDate > t || s && o.gender && o.gender !== s || (!r || o.effectiveDate > r.effectiveDate) && (r = o));
392
470
  return r;
393
471
  }
394
- function X(a, e, t, s, r) {
472
+ function ee(a, e, t, s, r) {
395
473
  const o = e[t];
396
474
  if (!o) return null;
397
475
  const n = /* @__PURE__ */ new Map();
398
- for (const m of a || []) {
399
- if (m.sport !== s || r && m.effectiveDate > r || m.gender && o.gender !== m.gender && o.gender !== "coed") continue;
400
- const d = m.gender || "", c = n.get(d);
401
- (!c || m.effectiveDate > c.effectiveDate) && n.set(d, m);
476
+ for (const d of a || []) {
477
+ if (d.sport !== s || r && d.effectiveDate > r || d.gender && o.gender !== d.gender && o.gender !== "coed") continue;
478
+ const h = d.gender || "", c = n.get(h);
479
+ (!c || d.effectiveDate > c.effectiveDate) && n.set(h, d);
402
480
  }
403
481
  let i = null;
404
- for (const m of n.values()) {
405
- const d = (m.teamIds || []).indexOf(t);
406
- d !== -1 && (!i || m.effectiveDate > i.effectiveDate) && (i = { poll: m, rank: d + 1 });
482
+ for (const d of n.values()) {
483
+ const h = (d.teamIds || []).indexOf(t);
484
+ h !== -1 && (!i || d.effectiveDate > i.effectiveDate) && (i = { poll: d, rank: h + 1 });
407
485
  }
408
486
  return i ? i.rank : null;
409
487
  }
410
- function fe(a, e, t) {
488
+ function we(a, e, t) {
411
489
  if (!a) return { kind: "none", delta: 0 };
412
490
  const s = (a.teamIds || []).indexOf(t) + 1;
413
491
  if (!s) return { kind: "none", delta: 0 };
@@ -417,61 +495,81 @@ function fe(a, e, t) {
417
495
  const o = r - s;
418
496
  return o > 0 ? { kind: "up", delta: o } : o < 0 ? { kind: "down", delta: -o } : { kind: "same", delta: 0 };
419
497
  }
420
- function ue(a) {
498
+ function xe(a) {
421
499
  return /^https?:\/\//i.test(String(a || ""));
422
500
  }
423
501
  function P(a, e) {
424
502
  const t = a?.logoAssetId;
425
- if (!ue(t)) return "";
503
+ if (!xe(t)) return "";
426
504
  const s = Math.max(1, Math.round(e * 2)), r = t.includes("?") ? "&" : "?";
427
505
  return `${t}${r}w=${s}&h=${s}&f=webp`;
428
506
  }
429
- const T = (a, e) => {
507
+ function W(a, e, { title: t, sub: s, teams: r }) {
508
+ const o = Z(), i = !!a.querySelector(':scope > a[slot="nav"]') || he(o, e.hrefs, e.sport) !== null;
509
+ return l`
510
+ <div class="band section">
511
+ <div class="inner">
512
+ <h1>${t}</h1>
513
+ ${s ? l`<p class="sub">${s}</p>` : p}
514
+ </div>
515
+ ${i ? l`
516
+ <nav class="sectionnav" aria-label="${T(e.sport)} section">
517
+ <div class="navrow">
518
+ <slot name="nav">
519
+ ${me(e.sport, r, e.hrefs).map((d) => l`<a href=${d.href}
520
+ aria-current=${o && x(d.href) === o ? "page" : p}>${d.label}</a>`)}
521
+ </slot>
522
+ </div>
523
+ </nav>` : p}
524
+ </div>
525
+ `;
526
+ }
527
+ const I = (a, e) => {
430
528
  const t = a.teamsById[e];
431
529
  return t ? a.schoolsById[t.schoolId] : null;
432
- }, k = (a, e) => T(a, e)?.name || "TBD", z = (a, e) => T(a, e)?.abbr || "TBD";
433
- function I(a, e = 26) {
530
+ }, S = (a, e) => I(a, e)?.name || "TBD", _ = (a, e) => I(a, e)?.abbr || "TBD";
531
+ function C(a, e = 26) {
434
532
  if (!a) return p;
435
533
  const t = P(a, e);
436
534
  if (t)
437
535
  return l`<img class="swatch logo" aria-hidden="true" alt="" loading="lazy"
438
536
  src=${t} style="width:${e}px;height:${e}px" />`;
439
- const s = a.colorPrimary || "#030711", r = F(s);
537
+ const s = a.colorPrimary || "#030711", r = B(s);
440
538
  return l`<span class="swatch" aria-hidden="true"
441
539
  style="width:${e}px;height:${e}px;background:${s};color:${r};font-size:${Math.max(8, e * 0.28)}px"
442
540
  >${M(a)}</span>`;
443
541
  }
444
- function G(a, e, t) {
445
- const s = X(a.rankings, a.teamsById, e, a.sport, t);
542
+ function q(a, e, t) {
543
+ const s = ee(a.rankings, a.teamsById, e, a.sport, t);
446
544
  return s ? l`<span class="rankbadge">#${s}</span>` : p;
447
545
  }
448
- function U(a, e, t) {
449
- const s = T(a, e);
450
- return s ? l`${G(a, e, t)}<a href=${v(a.hrefs.school, { id: s.id })}>${s.name}</a>` : l`<span class="mut">TBD</span>`;
546
+ function H(a, e, t) {
547
+ const s = I(a, e);
548
+ return s ? l`${q(a, e, t)}<a href=${u(a.hrefs.school, { id: s.id })}>${s.name}</a>` : l`<span class="mut">TBD</span>`;
451
549
  }
452
- function W(a, e, t = 5) {
550
+ function V(a, e, t = 5) {
453
551
  const s = a.records[e];
454
552
  if (!s || !s.results.length) return l`<span class="mut">·</span>`;
455
553
  const r = s.results.slice(-1 * t);
456
554
  return l`<span class="dots" role="img" aria-label="last ${r.length} results">
457
555
  ${r.map((o) => l`<a class="dot ${o.mark}"
458
- title="${o.mark} ${o.my}-${o.their} vs ${k(a, o.opp)}"
459
- href=${v(a.hrefs.game, { sport: a.sport, id: o.gameId })}>${o.mark}</a>`)}
556
+ title="${o.mark} ${o.my}-${o.their} vs ${S(a, o.opp)}"
557
+ href=${u(a.hrefs.game, { sport: a.sport, id: o.gameId })}>${o.mark}</a>`)}
460
558
  </span>`;
461
559
  }
462
- function B(a) {
463
- const e = pe(a);
560
+ function R(a) {
561
+ const e = ce(a);
464
562
  return l`<span class="pill ${e.kind}">${e.label}</span>`;
465
563
  }
466
- function Z(a, e, t) {
564
+ function te(a, e, t) {
467
565
  if (!e) return l`<span class="mut">·</span>`;
468
566
  const s = e.homeTeamId === t ? e.awayTeamId : e.homeTeamId, r = e.homeTeamId === t ? "vs" : "at";
469
- return l`${e.state === "live" ? l`<span class="pill live">Live</span> ` : l`${$(e.date, { month: "numeric", day: "numeric" })} `}${r} ${z(a, s)}`;
567
+ return l`${e.state === "live" ? l`<span class="pill live">Live</span> ` : l`${b(e.date, { month: "numeric", day: "numeric" })} `}${r} ${_(a, s)}`;
470
568
  }
471
- class ge extends b {
472
- static styles = S;
569
+ class ke extends $ {
570
+ static styles = F;
473
571
  static properties = {
474
- ...b.properties,
572
+ ...$.properties,
475
573
  sport: { type: String },
476
574
  season: { type: String },
477
575
  date: { type: String }
@@ -482,11 +580,11 @@ class ge extends b {
482
580
  connectedCallback() {
483
581
  if (super.connectedCallback(), !this.date) {
484
582
  const e = new URLSearchParams(globalThis.location?.search || "").get("date");
485
- this.date = e || O();
583
+ this.date = e || U();
486
584
  }
487
585
  }
488
586
  async fetchData(e) {
489
- const t = this.season || A(), [s, r, o, n, i] = await Promise.all([
587
+ const t = this.season || E(), [s, r, o, n, i] = await Promise.all([
490
588
  e.listSchools(),
491
589
  e.listTeams({ sport: this.sport }),
492
590
  e.listConferences(),
@@ -504,26 +602,25 @@ class ge extends b {
504
602
  }
505
603
  get ctx() {
506
604
  return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
507
- teamsById: g(this.data.teams),
508
- schoolsById: g(this.data.schools),
509
- records: D(this.data.games),
605
+ teamsById: v(this.data.teams),
606
+ schoolsById: v(this.data.schools),
607
+ records: z(this.data.games),
510
608
  rankings: this.data.rankings,
511
- hrefs: C(this),
609
+ hrefs: D(this),
512
610
  sport: this.sport
513
611
  }, this._ctxData = this.data), this._ctx;
514
612
  }
515
613
  renderView() {
516
- const e = this.ctx, t = g(this.data.conferences), s = [...new Set(this.data.games.map((n) => n.date).filter(Boolean))].sort(), r = this.data.games.filter((n) => n.date === this.date).sort((n, i) => (n.state === "live" ? -1 : 1) - (i.state === "live" ? -1 : 1)), o = /* @__PURE__ */ new Map();
614
+ const e = this.ctx, t = v(this.data.conferences), s = [...new Set(this.data.games.map((n) => n.date).filter(Boolean))].sort(), r = this.data.games.filter((n) => n.date === this.date).sort((n, i) => (n.state === "live" ? -1 : 1) - (i.state === "live" ? -1 : 1)), o = /* @__PURE__ */ new Map();
517
615
  return r.forEach((n) => {
518
616
  const i = n.gameType === "conference" && n.conferenceId ? t[n.conferenceId]?.name || "Conference" : n.gameType === "playoff" ? "Playoffs" : n.gameType === "scrimmage" ? "Scrimmages" : "Nonconference";
519
617
  o.has(i) || o.set(i, []), o.get(i).push(n);
520
618
  }), l`
521
- <div class="band">
522
- <div class="inner">
523
- <h1>${R(this.sport)} scores &amp; schedules</h1>
524
- <p class="sub">${$(this.date, { weekday: "long", month: "long", day: "numeric", year: "numeric" })} · ${r.length} games</p>
525
- </div>
526
- </div>
619
+ ${W(this, e, {
620
+ title: l`${T(this.sport)} scores &amp; schedules`,
621
+ sub: l`${b(this.date, { weekday: "long", month: "long", day: "numeric", year: "numeric" })} · ${r.length} games`,
622
+ teams: this.data.teams
623
+ })}
527
624
  <div class="view">
528
625
  <div class="toolbar">
529
626
  <label class="asof" for="datesel">Date</label>
@@ -531,7 +628,7 @@ class ge extends b {
531
628
  this.date = n.target.value;
532
629
  }}>
533
630
  ${s.map((n) => l`<option value=${n} ?selected=${n === this.date}>
534
- ${$(n, { weekday: "short", month: "short", day: "numeric" })}${n === O() ? " · today" : ""}
631
+ ${b(n, { weekday: "short", month: "short", day: "numeric" })}${n === U() ? " · today" : ""}
535
632
  </option>`)}
536
633
  </select>
537
634
  <button class="chip" ?disabled=${s.indexOf(this.date) <= 0}
@@ -549,31 +646,31 @@ class ge extends b {
549
646
  ${[...o.entries()].map(([n, i]) => l`
550
647
  <div class="section-title">${n}</div>
551
648
  <div class="card"><ul class="gamelist">
552
- ${i.map((m) => this.renderGame(e, m))}
649
+ ${i.map((d) => this.renderGame(e, d))}
553
650
  </ul></div>
554
651
  `)}
555
652
  </div>
556
653
  `;
557
654
  }
558
655
  renderGame(e, t) {
559
- const s = t.state === "final" || t.state === "live" ? `${t.awayScore}-${t.homeScore}` : E(t.time);
656
+ const s = t.state === "final" || t.state === "live" ? `${t.awayScore}-${t.homeScore}` : A(t.time);
560
657
  return l`
561
658
  <li>
562
- ${B(t)}
563
- <span class="opp">${U(e, t.awayTeamId, t.date)} at ${U(e, t.homeTeamId, t.date)}</span>
659
+ ${R(t)}
660
+ <span class="opp">${H(e, t.awayTeamId, t.date)} at ${H(e, t.homeTeamId, t.date)}</span>
564
661
  <span class="res" style="width:auto">${s}</span>
565
662
  <span class="where">${t.venue || ""}</span>
566
663
  ${t.broadcast ? l`<span class="pill class">${t.broadcast}</span>` : p}
567
- <a class="box" href=${v(e.hrefs.game, { sport: this.sport, id: t.id })}>Box score →</a>
664
+ <a class="box" href=${u(e.hrefs.game, { sport: this.sport, id: t.id })}>Box score →</a>
568
665
  </li>
569
666
  `;
570
667
  }
571
668
  }
572
- globalThis?.customElements && !globalThis.customElements.get("hsot-scores") && globalThis.customElements.define("hsot-scores", ge);
573
- class ve extends b {
574
- static styles = S;
669
+ globalThis?.customElements && !globalThis.customElements.get("hsot-scores") && globalThis.customElements.define("hsot-scores", ke);
670
+ class Te extends $ {
671
+ static styles = F;
575
672
  static properties = {
576
- ...b.properties,
673
+ ...$.properties,
577
674
  sport: { type: String },
578
675
  season: { type: String },
579
676
  classFilter: { state: !0 },
@@ -583,7 +680,7 @@ class ve extends b {
583
680
  super(), this.sport = "football", this.season = "", this.classFilter = "All", this.query = "";
584
681
  }
585
682
  async fetchData(e) {
586
- const t = this.season || A(), [s, r, o, n, i] = await Promise.all([
683
+ const t = this.season || E(), [s, r, o, n, i] = await Promise.all([
587
684
  e.listConferences({ active: !0 }),
588
685
  e.listSchools(),
589
686
  e.listTeams({ sport: this.sport }),
@@ -601,23 +698,22 @@ class ve extends b {
601
698
  }
602
699
  get ctx() {
603
700
  return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
604
- teamsById: g(this.data.teams),
605
- schoolsById: g(this.data.schools),
606
- records: D(this.data.games),
701
+ teamsById: v(this.data.teams),
702
+ schoolsById: v(this.data.schools),
703
+ records: z(this.data.games),
607
704
  rankings: this.data.rankings,
608
- hrefs: C(this),
705
+ hrefs: D(this),
609
706
  sport: this.sport
610
707
  }, this._ctxData = this.data), this._ctx;
611
708
  }
612
709
  renderView() {
613
710
  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));
614
711
  return l`
615
- <div class="band">
616
- <div class="inner">
617
- <h1>${R(this.sport)} standings</h1>
618
- <p class="sub">${this.data.season} season · every conference, computed live from reported results</p>
619
- </div>
620
- </div>
712
+ ${W(this, e, {
713
+ title: l`${T(this.sport)} standings`,
714
+ sub: l`${this.data.season} season · every conference, computed live from reported results`,
715
+ teams: this.data.teams
716
+ })}
621
717
  <div class="view">
622
718
  <div class="toolbar">
623
719
  <div role="group" aria-label="Classification filter">
@@ -631,7 +727,7 @@ class ve extends b {
631
727
  this.query = r.target.value;
632
728
  }}>
633
729
  <span class="spacer"></span>
634
- <span class="asof">Records through ${$(O(), { month: "long", day: "numeric" })} · conference games count toward both records · scrimmages toward neither</span>
730
+ <span class="asof">Records through ${b(U(), { month: "long", day: "numeric" })} · conference games count toward both records · scrimmages toward neither</span>
635
731
  </div>
636
732
  ${s.map((r) => this.renderConference(e, r))}
637
733
  </div>
@@ -640,7 +736,7 @@ class ve extends b {
640
736
  renderConference(e, t) {
641
737
  const s = this.data.teams.filter((n) => n.conferenceId === t.id);
642
738
  if (!s.length) return p;
643
- const r = this.query.trim().toLowerCase(), o = K(s, e.records);
739
+ const r = this.query.trim().toLowerCase(), o = J(s, e.records);
644
740
  return l`
645
741
  <div class="card">
646
742
  <div class="card-head">
@@ -664,35 +760,35 @@ class ve extends b {
664
760
  renderRow(e, t, s, r) {
665
761
  const o = e.schoolsById[t.team.schoolId], n = o?.name || t.team.name || "TBD";
666
762
  if (r && !n.toLowerCase().includes(r)) return p;
667
- const i = t.rec.pf - t.rec.pa, m = H(this.data.games, t.team.id), d = (t.team.championships || []).map((h) => l`
668
- <span class="pill champ" title="${h.season} ${h.title} champion">★ ${h.season} ${h.title}</span>`), c = () => {
669
- location.href = v(e.hrefs.school, { id: t.team.schoolId });
763
+ const i = t.rec.pf - t.rec.pa, d = G(this.data.games, t.team.id), h = (t.team.championships || []).map((m) => l`
764
+ <span class="pill champ" title="${m.season} ${m.title} champion">★ ${m.season} ${m.title}</span>`), c = () => {
765
+ location.href = u(e.hrefs.school, { id: t.team.schoolId });
670
766
  };
671
767
  return l`
672
- <tr class="rowlink" @click=${(h) => {
673
- h.target.closest("a") || c();
768
+ <tr class="rowlink" @click=${(m) => {
769
+ m.target.closest("a") || c();
674
770
  }}>
675
771
  <td class="mut">${s + 1}</td>
676
772
  <td class="teamcell">
677
- ${I(o)}${G(e, t.team.id, null)}
678
- <a href=${v(e.hrefs.school, { id: t.team.schoolId })}>${n}</a> ${d}
773
+ ${C(o)}${q(e, t.team.id, null)}
774
+ <a href=${u(e.hrefs.school, { id: t.team.schoolId })}>${n}</a> ${h}
679
775
  </td>
680
776
  <td class="num">${w(t.rec, !0)}</td>
681
- <td class="num">${Y(t.confPct)}</td>
777
+ <td class="num">${K(t.confPct)}</td>
682
778
  <td class="num">${w(t.rec)}</td>
683
- <td class="num">${Y(t.overallPct)}</td>
779
+ <td class="num">${K(t.overallPct)}</td>
684
780
  <td class="num">${t.rec.pf}</td>
685
781
  <td class="num">${t.rec.pa}</td>
686
782
  <td class="num" style="color:${i >= 0 ? "var(--hsot-win)" : "var(--hsot-loss)"}">${i > 0 ? "+" : ""}${i}</td>
687
- <td>${_(t.rec.results) || "·"}</td>
688
- <td>${W(e, t.team.id)}</td>
689
- <td>${Z(e, m, t.team.id)}</td>
783
+ <td>${L(t.rec.results) || "·"}</td>
784
+ <td>${V(e, t.team.id)}</td>
785
+ <td>${te(e, d, t.team.id)}</td>
690
786
  </tr>
691
787
  `;
692
788
  }
693
789
  }
694
- globalThis?.customElements && !globalThis.customElements.get("hsot-standings") && globalThis.customElements.define("hsot-standings", ve);
695
- const $e = y`
790
+ globalThis?.customElements && !globalThis.customElements.get("hsot-standings") && globalThis.customElements.define("hsot-standings", Te);
791
+ const Se = y`
696
792
  .hero1 {
697
793
  border-radius: var(--hsot-radius-md); color: var(--hsot-white);
698
794
  padding: 1.3rem 1.4rem; display: flex; align-items: center; gap: 1.2rem;
@@ -709,10 +805,10 @@ const $e = y`
709
805
  .delta.new { background: var(--hsot-straw); color: #6b5900; border-radius: var(--hsot-radius-xs); padding: 0.1rem 0.3rem; font-size: 0.7rem; }
710
806
  .sparkline { vertical-align: middle; }
711
807
  `;
712
- class be extends b {
713
- static styles = [...S, $e];
808
+ class Ie extends $ {
809
+ static styles = [...F, Se];
714
810
  static properties = {
715
- ...b.properties,
811
+ ...$.properties,
716
812
  sport: { type: String },
717
813
  gender: { type: String },
718
814
  season: { type: String },
@@ -727,16 +823,16 @@ class be extends b {
727
823
  e && (this.pollDate = e);
728
824
  }
729
825
  async fetchData(e) {
730
- const t = this.season || A(), [s, r, o, n, i] = await Promise.all([
826
+ const t = this.season || E(), [s, r, o, n, i] = await Promise.all([
731
827
  e.listRankings({ sport: this.sport, ...this.gender ? { gender: this.gender } : {} }),
732
828
  e.listSchools(),
733
829
  e.listTeams({ sport: this.sport }),
734
830
  e.listConferences(),
735
831
  e.listGames({ sport: this.sport, season: t })
736
- ]), m = s.items.filter((d) => !this.gender || !d.gender || d.gender === this.gender).sort((d, c) => c.effectiveDate.localeCompare(d.effectiveDate));
832
+ ]), d = s.items.filter((h) => !this.gender || !h.gender || h.gender === this.gender).sort((h, c) => c.effectiveDate.localeCompare(h.effectiveDate));
737
833
  return {
738
834
  season: t,
739
- polls: m,
835
+ polls: d,
740
836
  schools: r.items,
741
837
  teams: o.items,
742
838
  conferences: n.items,
@@ -745,55 +841,54 @@ class be extends b {
745
841
  }
746
842
  get ctx() {
747
843
  return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
748
- teamsById: g(this.data.teams),
749
- schoolsById: g(this.data.schools),
750
- records: D(this.data.games),
844
+ teamsById: v(this.data.teams),
845
+ schoolsById: v(this.data.schools),
846
+ records: z(this.data.games),
751
847
  rankings: this.data.polls,
752
- hrefs: C(this),
848
+ hrefs: D(this),
753
849
  sport: this.sport
754
850
  }, this._ctxData = this.data), this._ctx;
755
851
  }
756
852
  sparkline(e, t, s) {
757
- const i = t.map((h, f) => {
758
- const u = (h.teamIds || []).indexOf(e);
759
- if (u === -1) return null;
760
- const x = t.length === 1 ? 96 / 2 : f / (t.length - 1) * 90 + 3, L = 3 + u / 24 * 20;
761
- return { x, y: L };
762
- }), m = [];
763
- let d = [];
764
- if (i.forEach((h) => {
765
- h ? d.push(h) : d.length && (m.push(d), d = []);
766
- }), d.length && m.push(d), !m.length) return p;
853
+ const i = t.map((m, f) => {
854
+ const g = (m.teamIds || []).indexOf(e);
855
+ if (g === -1) return null;
856
+ const k = t.length === 1 ? 96 / 2 : f / (t.length - 1) * 90 + 3, N = 3 + g / 24 * 20;
857
+ return { x: k, y: N };
858
+ }), d = [];
859
+ let h = [];
860
+ if (i.forEach((m) => {
861
+ m ? h.push(m) : h.length && (d.push(h), h = []);
862
+ }), h.length && d.push(h), !d.length) return p;
767
863
  const c = i[s];
768
864
  return l`<svg class="sparkline" width=${96} height=${26} viewBox="0 0 ${96} ${26}" role="img" aria-label="rank history">
769
- ${m.map((h) => q`<polyline fill="none" stroke="var(--hsot-red)" stroke-width="2"
770
- points=${h.map((f) => `${f.x.toFixed(1)},${f.y.toFixed(1)}`).join(" ")}></polyline>`)}
771
- ${c ? q`<circle cx=${c.x.toFixed(1)} cy=${c.y.toFixed(1)} r="3" fill="var(--hsot-black)"></circle>` : p}
865
+ ${d.map((m) => Y`<polyline fill="none" stroke="var(--hsot-red)" stroke-width="2"
866
+ points=${m.map((f) => `${f.x.toFixed(1)},${f.y.toFixed(1)}`).join(" ")}></polyline>`)}
867
+ ${c ? Y`<circle cx=${c.x.toFixed(1)} cy=${c.y.toFixed(1)} r="3" fill="var(--hsot-black)"></circle>` : p}
772
868
  </svg>`;
773
869
  }
774
870
  movement(e, t, s) {
775
- const r = fe(e, t, s);
871
+ const r = we(e, t, s);
776
872
  return r.kind === "up" ? l`<span class="delta up">▲ ${r.delta}</span>` : r.kind === "down" ? l`<span class="delta down">▼ ${r.delta}</span>` : r.kind === "new" ? l`<span class="delta new">NEW</span>` : r.kind === "same" ? l`<span class="delta same">—</span>` : l`<span class="delta same">·</span>`;
777
873
  }
778
874
  renderView() {
779
875
  const e = this.ctx, t = this.data.polls;
780
876
  if (!t.length) return l`<div class="view"><p class="empty">No ${this.sport} polls published yet this season.</p></div>`;
781
- const s = Math.max(0, t.findIndex((h) => h.effectiveDate === this.pollDate)), r = t[s] || t[0], o = t[s + 1] || null, n = t.slice().reverse(), i = n.indexOf(r), m = g(this.data.conferences), d = (r.teamIds || [])[0], c = d ? T(e, d) : null;
877
+ const s = Math.max(0, t.findIndex((m) => m.effectiveDate === this.pollDate)), r = t[s] || t[0], o = t[s + 1] || null, n = t.slice().reverse(), i = n.indexOf(r), d = v(this.data.conferences), h = (r.teamIds || [])[0], c = h ? I(e, h) : null;
782
878
  return l`
783
- <div class="band">
784
- <div class="inner">
785
- <h1>${R(this.sport)} Top 25</h1>
786
- <p class="sub">The HighSchoolOT poll · updated weekly · ${t.length} polls this season</p>
787
- </div>
788
- </div>
879
+ ${W(this, e, {
880
+ title: l`${T(this.sport)} Top 25`,
881
+ sub: l`The HighSchoolOT poll · updated weekly · ${t.length} polls this season`,
882
+ teams: this.data.teams
883
+ })}
789
884
  <div class="view">
790
885
  <div class="toolbar">
791
886
  <label class="asof" for="pollsel">Poll of</label>
792
- <select id="pollsel" @change=${(h) => {
793
- this.pollDate = h.target.value;
887
+ <select id="pollsel" @change=${(m) => {
888
+ this.pollDate = m.target.value;
794
889
  }}>
795
- ${t.map((h, f) => l`<option value=${h.effectiveDate} ?selected=${h === r}>
796
- ${$(h.effectiveDate, { month: "long", day: "numeric", year: "numeric" })}${f === 0 ? " · current" : ""}
890
+ ${t.map((m, f) => l`<option value=${m.effectiveDate} ?selected=${m === r}>
891
+ ${b(m.effectiveDate, { month: "long", day: "numeric", year: "numeric" })}${f === 0 ? " · current" : ""}
797
892
  </option>`)}
798
893
  </select>
799
894
  <button class="chip" ?disabled=${s >= t.length - 1}
@@ -807,14 +902,14 @@ class be extends b {
807
902
  <span class="spacer"></span>
808
903
  <span class="asof">Movement vs. the previous poll · sparkline = season rank history</span>
809
904
  </div>
810
- ${c ? this.renderHero(e, r, o, d, c, m) : p}
905
+ ${c ? this.renderHero(e, r, o, h, c, d) : p}
811
906
  <div class="card"><div class="tablewrap"><table class="data">
812
907
  <thead><tr>
813
908
  <th class="num">Rk</th><th>Mvmt</th><th>Team</th><th class="num">Record</th>
814
909
  <th>Conference</th><th>Last result</th><th>Next</th><th>Season</th>
815
910
  </tr></thead>
816
911
  <tbody>
817
- ${(r.teamIds || []).map((h, f) => f === 0 || !h ? p : this.renderRow(e, r, o, n, i, m, h, f + 1))}
912
+ ${(r.teamIds || []).map((m, f) => f === 0 || !m ? p : this.renderRow(e, r, o, n, i, d, m, f + 1))}
818
913
  </tbody>
819
914
  </table></div></div>
820
915
  <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>
@@ -822,50 +917,50 @@ class be extends b {
822
917
  `;
823
918
  }
824
919
  renderHero(e, t, s, r, o, n) {
825
- const i = e.records[r], m = Q(e.records, r), d = n[e.teamsById[r]?.conferenceId], c = `linear-gradient(120deg, ${o.colorPrimary || "#030711"} 0%, var(--hsot-black) 85%)`;
920
+ const i = e.records[r], d = X(e.records, r), h = n[e.teamsById[r]?.conferenceId], c = `linear-gradient(120deg, ${o.colorPrimary || "#030711"} 0%, var(--hsot-black) 85%)`;
826
921
  return l`
827
922
  <div class="hero1" style="background:${c}">
828
923
  <div class="bigrank">#1</div>
829
- ${I(o, 64)}
924
+ ${C(o, 64)}
830
925
  <div>
831
- <h2><a href=${v(e.hrefs.school, { id: o.id })}>${o.name} ${o.mascot || ""}</a></h2>
926
+ <h2><a href=${u(e.hrefs.school, { id: o.id })}>${o.name} ${o.mascot || ""}</a></h2>
832
927
  <div class="facts">
833
- ${w(i)} overall${d ? l` · ${w(i, !0)} ${d.name}` : p}
834
- · streak ${_(i?.results) || "·"}
835
- ${m ? l` · last: ${m.mark} ${m.my}-${m.their} vs ${z(e, m.opp)}` : p}
928
+ ${w(i)} overall${h ? l` · ${w(i, !0)} ${h.name}` : p}
929
+ · streak ${L(i?.results) || "·"}
930
+ ${d ? l` · last: ${d.mark} ${d.my}-${d.their} vs ${_(e, d.opp)}` : p}
836
931
  &nbsp;${this.movement(t, s, r)}
837
932
  </div>
838
933
  </div>
839
934
  </div>
840
935
  `;
841
936
  }
842
- renderRow(e, t, s, r, o, n, i, m) {
843
- const d = T(e, i);
844
- if (!d) return p;
845
- const c = e.records[i], h = Q(e.records, i), f = H(this.data.games, i), u = n[e.teamsById[i]?.conferenceId], x = () => {
846
- location.href = v(e.hrefs.school, { id: d.id });
937
+ renderRow(e, t, s, r, o, n, i, d) {
938
+ const h = I(e, i);
939
+ if (!h) return p;
940
+ const c = e.records[i], m = X(e.records, i), f = G(this.data.games, i), g = n[e.teamsById[i]?.conferenceId], k = () => {
941
+ location.href = u(e.hrefs.school, { id: h.id });
847
942
  };
848
943
  return l`
849
- <tr class="rowlink" @click=${(L) => {
850
- L.target.closest("a") || x();
944
+ <tr class="rowlink" @click=${(N) => {
945
+ N.target.closest("a") || k();
851
946
  }}>
852
- <td class="num" style="font-weight:700">${m}</td>
947
+ <td class="num" style="font-weight:700">${d}</td>
853
948
  <td>${this.movement(t, s, i)}</td>
854
- <td class="teamcell">${I(d)}<a href=${v(e.hrefs.school, { id: d.id })}>${d.name}</a>
855
- <span class="mut" style="font-size:0.78rem">${d.mascot || ""}</span></td>
949
+ <td class="teamcell">${C(h)}<a href=${u(e.hrefs.school, { id: h.id })}>${h.name}</a>
950
+ <span class="mut" style="font-size:0.78rem">${h.mascot || ""}</span></td>
856
951
  <td class="num">${w(c)}</td>
857
- <td class="mut">${u?.name || "Independent"}</td>
858
- <td>${h ? l`<a class="box" style="text-decoration:none" href=${v(e.hrefs.game, { sport: this.sport, id: h.gameId })}>
859
- <b style="color:${h.mark === "W" ? "var(--hsot-win)" : h.mark === "L" ? "var(--hsot-loss)" : "var(--hsot-tie)"}">${h.mark}</b>
860
- ${h.my}-${h.their} vs ${z(e, h.opp)}</a>` : l`<span class="mut">·</span>`}</td>
861
- <td>${Z(e, f, i)}</td>
952
+ <td class="mut">${g?.name || "Independent"}</td>
953
+ <td>${m ? l`<a class="box" style="text-decoration:none" href=${u(e.hrefs.game, { sport: this.sport, id: m.gameId })}>
954
+ <b style="color:${m.mark === "W" ? "var(--hsot-win)" : m.mark === "L" ? "var(--hsot-loss)" : "var(--hsot-tie)"}">${m.mark}</b>
955
+ ${m.my}-${m.their} vs ${_(e, m.opp)}</a>` : l`<span class="mut">·</span>`}</td>
956
+ <td>${te(e, f, i)}</td>
862
957
  <td>${this.sparkline(i, r, o)}</td>
863
958
  </tr>
864
959
  `;
865
960
  }
866
961
  }
867
- globalThis?.customElements && !globalThis.customElements.get("hsot-rankings") && globalThis.customElements.define("hsot-rankings", be);
868
- const ye = y`
962
+ globalThis?.customElements && !globalThis.customElements.get("hsot-rankings") && globalThis.customElements.define("hsot-rankings", Ie);
963
+ const Ce = y`
869
964
  .schoolhero { color: var(--hsot-white); padding: 1.6rem 1.25rem 1.3rem; }
870
965
  .schoolhero .inner { max-width: 1366px; margin: 0 auto; display: flex; gap: 1.2rem; align-items: center; flex-wrap: wrap; }
871
966
  .schoolhero .crest {
@@ -890,10 +985,10 @@ const ye = y`
890
985
  .cols { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 1.25rem; }
891
986
  @media (max-width: 900px) { .cols { grid-template-columns: 1fr; } .schoolhero h1 { font-size: 1.9rem; } }
892
987
  `;
893
- class we extends b {
894
- static styles = [...S, ye];
988
+ class De extends $ {
989
+ static styles = [...F, Ce];
895
990
  static properties = {
896
- ...b.properties,
991
+ ...$.properties,
897
992
  schoolId: { type: String, attribute: "school-id" },
898
993
  sport: { type: String },
899
994
  season: { type: String },
@@ -908,7 +1003,7 @@ class we extends b {
908
1003
  e && !this.sport && (this.sport = e);
909
1004
  }
910
1005
  async fetchData(e) {
911
- const t = this.season || A(), s = await e.getSchool(this.schoolId), o = (await e.listTeams({ schoolId: this.schoolId })).items, n = o.find((x) => x.sport === (this.sport || "football")) || o[0] || null, [i, m, d, c, h, f, u] = await Promise.all([
1006
+ const t = this.season || E(), s = await e.getSchool(this.schoolId), o = (await e.listTeams({ schoolId: this.schoolId })).items, n = o.find((k) => k.sport === (this.sport || "football")) || o[0] || null, [i, d, h, c, m, f, g] = await Promise.all([
912
1007
  n ? e.listGames({ sport: n.sport, season: t }) : Promise.resolve({ items: [] }),
913
1008
  n ? e.listTeams({ sport: n.sport }) : Promise.resolve({ items: [] }),
914
1009
  e.listSchools(),
@@ -925,21 +1020,21 @@ class we extends b {
925
1020
  teams: o,
926
1021
  active: n,
927
1022
  games: i.items,
928
- allTeams: m.items,
929
- schools: d.items,
1023
+ allTeams: d.items,
1024
+ schools: h.items,
930
1025
  conferences: c.items,
931
- rankings: h.items,
932
- roster: f.items.find((x) => x.season === t) || null,
933
- players: u.items
1026
+ rankings: m.items,
1027
+ roster: f.items.find((k) => k.season === t) || null,
1028
+ players: g.items
934
1029
  };
935
1030
  }
936
1031
  get ctx() {
937
1032
  return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
938
- teamsById: g(this.data.allTeams.length ? this.data.allTeams : this.data.teams),
939
- schoolsById: g(this.data.schools),
940
- records: D(this.data.games),
1033
+ teamsById: v(this.data.allTeams.length ? this.data.allTeams : this.data.teams),
1034
+ schoolsById: v(this.data.schools),
1035
+ records: z(this.data.games),
941
1036
  rankings: this.data.rankings,
942
- hrefs: C(this),
1037
+ hrefs: D(this),
943
1038
  sport: this.data.active?.sport || "football"
944
1039
  }, this._ctxData = this.data), this._ctx;
945
1040
  }
@@ -949,17 +1044,17 @@ class we extends b {
949
1044
  renderView() {
950
1045
  const { school: e, teams: t, active: s, season: r } = this.data;
951
1046
  if (!e) return l`<div class="view"><p class="empty">School not found.</p></div>`;
952
- const o = this.ctx, n = F(e.colorPrimary || "#030711"), i = (e.adm || [])[0], m = g(this.data.conferences), d = s ? m[s.conferenceId] : null;
1047
+ const o = this.ctx, n = B(e.colorPrimary || "#030711"), i = (e.adm || [])[0], d = v(this.data.conferences), h = s ? d[s.conferenceId] : null;
953
1048
  return l`
954
1049
  <div class="schoolhero" style="background:linear-gradient(115deg, ${e.colorPrimary || "#030711"} 0%, ${e.colorPrimary || "#030711"} 55%, var(--hsot-black) 100%);color:${n}">
955
1050
  <div class="inner">
956
- ${P(e, 84) ? l`<img class="crest logo" alt="" loading="lazy" src=${P(e, 84)} />` : l`<div class="crest" style="background:${e.colorSecondary || "#7C7C7C"};color:${F(e.colorSecondary || "#7C7C7C")}">${M(e)}</div>`}
1051
+ ${P(e, 84) ? l`<img class="crest logo" alt="" loading="lazy" src=${P(e, 84)} />` : l`<div class="crest" style="background:${e.colorSecondary || "#7C7C7C"};color:${B(e.colorSecondary || "#7C7C7C")}">${M(e)}</div>`}
957
1052
  <div style="min-width:260px">
958
1053
  <h1>${e.name} <span class="mascot">${e.mascot || ""}</span></h1>
959
1054
  <div class="facts">
960
1055
  ${e.location ? l`<span><b>Location</b>${e.location}${e.county ? l` · ${e.county} County` : p}</span>` : p}
961
1056
  ${e.association ? l`<span><b>League</b>${e.association}${e.classification ? l` · ${e.classification}` : p}</span>` : p}
962
- ${d ? l`<span><b>Conference</b>${d.name}</span>` : p}
1057
+ ${h ? l`<span><b>Conference</b>${h.name}</span>` : p}
963
1058
  ${i ? l`<span><b>Enrollment</b>${i.value.toLocaleString()} (${i.season} ADM)</span>` : p}
964
1059
  ${e.openingYear ? l`<span><b>Opened</b>${e.openingYear}</span>` : p}
965
1060
  ${e.areaCode ? l`<span><b>Area</b>${e.areaCode}</span>` : p}
@@ -970,39 +1065,39 @@ class we extends b {
970
1065
  </div>
971
1066
  <div class="band">
972
1067
  <nav class="tabs" aria-label="Teams">
973
- ${t.map((c) => c.id === s?.id ? l`<a class="on" href="#" @click=${(h) => h.preventDefault()}>${c.name}</a>` : l`<a href="#" @click=${(h) => {
974
- h.preventDefault(), this.switchSport(c.sport);
1068
+ ${t.map((c) => c.id === s?.id ? l`<a class="on" href="#" @click=${(m) => m.preventDefault()}>${c.name}</a>` : l`<a href="#" @click=${(m) => {
1069
+ m.preventDefault(), this.switchSport(c.sport);
975
1070
  }}>${c.name}</a>`)}
976
1071
  </nav>
977
1072
  </div>
978
1073
  <div class="view">
979
- ${s ? this.renderTeam(o, s, d, r) : l`<p class="empty">No teams recorded for this school yet.</p>`}
1074
+ ${s ? this.renderTeam(o, s, h, r) : l`<p class="empty">No teams recorded for this school yet.</p>`}
980
1075
  </div>
981
1076
  `;
982
1077
  }
983
1078
  renderTeam(e, t, s, r) {
984
- const o = e.records[t.id] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] }, n = o.w + o.l + o.t, i = s ? this.data.allTeams.filter((h) => h.conferenceId === s.id) : [], m = s ? K(i, e.records).findIndex((h) => h.team.id === t.id) + 1 : 0, d = X(e.rankings, e.teamsById, t.id, t.sport, null), c = this.data.games.filter((h) => h.homeTeamId === t.id || h.awayTeamId === t.id).sort((h, f) => String(h.date).localeCompare(String(f.date)));
1079
+ const o = e.records[t.id] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] }, n = o.w + o.l + o.t, i = s ? this.data.allTeams.filter((m) => m.conferenceId === s.id) : [], d = s ? J(i, e.records).findIndex((m) => m.team.id === t.id) + 1 : 0, h = ee(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)));
985
1080
  return l`
986
1081
  <div class="tiles">
987
1082
  <div class="tile"><div class="k">Overall</div><div class="v">${w(o)}</div><div class="s">${n} games played</div></div>
988
1083
  <div class="tile"><div class="k">${s?.name || "Conference"}</div><div class="v">${w(o, !0)}</div>
989
- <div class="s">${m ? `${me(m)} of ${i.length}` : "·"}</div></div>
1084
+ <div class="s">${d ? `${le(d)} of ${i.length}` : "·"}</div></div>
990
1085
  <div class="tile"><div class="k">Points</div><div class="v">${n ? (o.pf / n).toFixed(1) : "0.0"}</div>
991
1086
  <div class="s">scored per game · ${n ? (o.pa / n).toFixed(1) : "0.0"} allowed</div></div>
992
- <div class="tile"><div class="k">Streak</div><div class="v">${_(o.results) || "·"}</div>
993
- <div class="s">last 5: ${W(e, t.id)}</div></div>
994
- <div class="tile"><div class="k">HSOT Top 25</div><div class="v">${d ? `#${d}` : "NR"}</div>
995
- <div class="s"><a href=${v(e.hrefs.section, { sport: t.sport, view: "rankings" })}>full poll</a></div></div>
1087
+ <div class="tile"><div class="k">Streak</div><div class="v">${L(o.results) || "·"}</div>
1088
+ <div class="s">last 5: ${V(e, t.id)}</div></div>
1089
+ <div class="tile"><div class="k">HSOT Top 25</div><div class="v">${h ? `#${h}` : "NR"}</div>
1090
+ <div class="s"><a href=${u(e.hrefs.section, { sport: t.sport, view: "rankings" })}>full poll</a></div></div>
996
1091
  </div>
997
1092
  ${(t.championships || []).length ? l`
998
1093
  <div style="margin:-0.2rem 0 1rem;display:flex;gap:0.4rem;flex-wrap:wrap">
999
- ${t.championships.map((h) => l`<span class="pill champ">★ ${h.season} ${h.title} champion${h.classification ? ` · ${h.classification}` : ""}${h.region ? ` · ${h.region}` : ""}</span>`)}
1094
+ ${t.championships.map((m) => l`<span class="pill champ">★ ${m.season} ${m.title} champion${m.classification ? ` · ${m.classification}` : ""}${m.region ? ` · ${m.region}` : ""}</span>`)}
1000
1095
  </div>` : p}
1001
1096
  <div class="cols">
1002
1097
  <div>
1003
1098
  <div class="section-title">Schedule &amp; results</div>
1004
1099
  <div class="card">
1005
- ${c.length ? l`<ul class="gamelist">${c.map((h) => this.renderGameRow(e, t, h))}</ul>` : l`<p class="empty">No ${t.sport} games recorded for ${r}.</p>`}
1100
+ ${c.length ? l`<ul class="gamelist">${c.map((m) => this.renderGameRow(e, t, m))}</ul>` : l`<p class="empty">No ${t.sport} games recorded for ${r}.</p>`}
1006
1101
  </div>
1007
1102
  </div>
1008
1103
  <div>
@@ -1014,23 +1109,23 @@ class we extends b {
1014
1109
  }
1015
1110
  renderGameRow(e, t, s) {
1016
1111
  const r = s.homeTeamId === t.id, o = r ? s.awayTeamId : s.homeTeamId, n = r ? s.homeScore : s.awayScore, i = r ? s.awayScore : s.homeScore;
1017
- let m = l`<span class="mut">${E(s.time)}</span>`;
1112
+ let d = l`<span class="mut">${A(s.time)}</span>`;
1018
1113
  if (s.state === "final") {
1019
- const c = j(s), h = c === "tie" ? "T" : c === (r ? "home" : "away") ? "W" : "L";
1020
- m = l`<span class=${h}>${h}</span> ${n}-${i}${s.finish === "overtime" ? l` <span class="mut">OT</span>` : p}${s.forfeit && s.forfeit !== "none" ? l` <span class="mut">FF</span>` : p}`;
1021
- } else s.state === "live" && (m = l`<span style="color:var(--hsot-red)">${n}-${i}</span>`);
1022
- const d = s.gameType === "conference" ? "Conf" : s.gameType === "nonconference" ? "Non-conf" : s.gameType === "playoff" ? `Playoff${s.label ? ` · ${s.label}` : ""}` : "Scrimmage";
1114
+ const c = j(s), m = c === "tie" ? "T" : c === (r ? "home" : "away") ? "W" : "L";
1115
+ d = l`<span class=${m}>${m}</span> ${n}-${i}${s.finish === "overtime" ? l` <span class="mut">OT</span>` : p}${s.forfeit && s.forfeit !== "none" ? l` <span class="mut">FF</span>` : p}`;
1116
+ } else s.state === "live" && (d = l`<span style="color:var(--hsot-red)">${n}-${i}</span>`);
1117
+ const h = s.gameType === "conference" ? "Conf" : s.gameType === "nonconference" ? "Non-conf" : s.gameType === "playoff" ? `Playoff${s.label ? ` · ${s.label}` : ""}` : "Scrimmage";
1023
1118
  return l`
1024
1119
  <li>
1025
- <span class="d">${$(s.date)}</span>
1026
- ${B(s)}
1027
- <span class="res">${m}</span>
1028
- <span class="opp">${r ? "vs" : "at"} ${U(e, o, s.date)}
1029
- <span class="pill type">${d}</span>
1120
+ <span class="d">${b(s.date)}</span>
1121
+ ${R(s)}
1122
+ <span class="res">${d}</span>
1123
+ <span class="opp">${r ? "vs" : "at"} ${H(e, o, s.date)}
1124
+ <span class="pill type">${h}</span>
1030
1125
  ${s.broadcast ? l`<span class="pill class">${s.broadcast}</span>` : p}
1031
1126
  </span>
1032
1127
  <span class="where">${s.venue || ""}</span>
1033
- <a class="box" href=${v(e.hrefs.game, { sport: t.sport, id: s.id })}>Box score →</a>
1128
+ <a class="box" href=${u(e.hrefs.game, { sport: t.sport, id: s.id })}>Box score →</a>
1034
1129
  </li>
1035
1130
  `;
1036
1131
  }
@@ -1038,7 +1133,7 @@ class we extends b {
1038
1133
  const t = this.data.roster;
1039
1134
  if (!t)
1040
1135
  return l`<p class="empty">Roster not published for ${e}.</p>`;
1041
- const s = g(this.data.players), r = t.entries.slice().sort((o, n) => (o.number || 0) - (n.number || 0));
1136
+ const s = v(this.data.players), r = t.entries.slice().sort((o, n) => (o.number || 0) - (n.number || 0));
1042
1137
  return l`
1043
1138
  <div class="tablewrap"><table class="data">
1044
1139
  <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>
@@ -1050,7 +1145,7 @@ class we extends b {
1050
1145
  <td style="font-weight:500">${n.firstName} ${n.lastName}</td>
1051
1146
  <td>${o.position || "·"}</td>
1052
1147
  <td class="mut">${n.classOf || "·"}</td>
1053
- <td class="num">${he(n.heightIn)}</td>
1148
+ <td class="num">${ie(n.heightIn)}</td>
1054
1149
  <td class="num">${n.weightLb || "·"}</td>
1055
1150
  </tr>` : p;
1056
1151
  })}
@@ -1059,16 +1154,16 @@ class we extends b {
1059
1154
  `;
1060
1155
  }
1061
1156
  }
1062
- globalThis?.customElements && !globalThis.customElements.get("hsot-school") && globalThis.customElements.define("hsot-school", we);
1063
- const xe = "https://api.wral.com/search";
1064
- function ke(a) {
1157
+ globalThis?.customElements && !globalThis.customElements.get("hsot-school") && globalThis.customElements.define("hsot-school", De);
1158
+ const Fe = "https://api.wral.com/search";
1159
+ function ze(a) {
1065
1160
  return a.map((e) => `uri:"${e}"`).join(" OR ");
1066
1161
  }
1067
- function Te(a, e) {
1068
- const t = String(a || xe).replace(/\/+$/, ""), s = new URLSearchParams({ query: ke(e), sort: "score", lang: "en" });
1162
+ function Be(a, e) {
1163
+ const t = String(a || Fe).replace(/\/+$/, ""), s = new URLSearchParams({ query: ze(e), sort: "score", lang: "en" });
1069
1164
  return `${t}/v1/query?${s}`;
1070
1165
  }
1071
- function J(a) {
1166
+ function se(a) {
1072
1167
  try {
1073
1168
  const e = new URL(a);
1074
1169
  if (/(^|\.)smugmug\.com$/i.test(e.hostname)) {
@@ -1083,13 +1178,13 @@ function J(a) {
1083
1178
  }
1084
1179
  return { uri: a, title: a };
1085
1180
  }
1086
- async function Ie(a, e, t) {
1087
- const r = await ((...i) => fetch(...i))(Te(a, e));
1181
+ async function Pe(a, e, t) {
1182
+ const r = await ((...i) => fetch(...i))(Be(a, e));
1088
1183
  if (!r.ok) throw new Error(`search answered ${r.status}`);
1089
1184
  const o = await r.json(), n = new Map((o.items || []).map((i) => [i.uri, i]));
1090
- return e.map((i) => n.get(i) || J(i));
1185
+ return e.map((i) => n.get(i) || se(i));
1091
1186
  }
1092
- const Se = y`
1187
+ const _e = y`
1093
1188
  .breadcrumbs { font-size: 0.8125rem; margin: 0.9rem 0 0; color: var(--hsot-gray-5); }
1094
1189
  .breadcrumbs a { text-decoration: none; }
1095
1190
  .scorehead { display: grid; grid-template-columns: 1fr auto 1fr; gap: 1rem; align-items: center; padding: 1.4rem 1rem; }
@@ -1128,10 +1223,10 @@ const Se = y`
1128
1223
  .cols { grid-template-columns: 1fr; }
1129
1224
  }
1130
1225
  `;
1131
- class De extends b {
1132
- static styles = [...S, Se];
1226
+ class Re extends $ {
1227
+ static styles = [...F, _e];
1133
1228
  static properties = {
1134
- ...b.properties,
1229
+ ...$.properties,
1135
1230
  gameId: { type: String, attribute: "game-id" },
1136
1231
  // The public site search that resolves Game.coverageUrls into cards
1137
1232
  // (DEV-1236). Shared cross-stage by design — see the studio host's
@@ -1143,7 +1238,7 @@ class De extends b {
1143
1238
  super(), this.gameId = "", this.searchApi = "";
1144
1239
  }
1145
1240
  async fetchData(e) {
1146
- const t = await e.getGame(this.gameId), s = Array.isArray(t.coverageUrls) ? t.coverageUrls : [], [r, o, n, i, m, d] = await Promise.all([
1241
+ const t = await e.getGame(this.gameId), s = Array.isArray(t.coverageUrls) ? t.coverageUrls : [], [r, o, n, i, d, h] = await Promise.all([
1147
1242
  e.listSchools(),
1148
1243
  e.listTeams({ sport: t.sport }),
1149
1244
  e.listConferences(),
@@ -1151,7 +1246,7 @@ class De extends b {
1151
1246
  e.listGames({ sport: t.sport, season: t.season }),
1152
1247
  // A search outage must not blank the box score — degrade to bare
1153
1248
  // links (fetchCoverage already degrades per-URL index misses).
1154
- s.length ? Ie(this.searchApi, s).catch(() => s.map(J)) : Promise.resolve([])
1249
+ s.length ? Pe(this.searchApi, s).catch(() => s.map(se)) : Promise.resolve([])
1155
1250
  ]);
1156
1251
  return {
1157
1252
  game: t,
@@ -1159,30 +1254,30 @@ class De extends b {
1159
1254
  teams: o.items,
1160
1255
  conferences: n.items,
1161
1256
  rankings: i.items,
1162
- games: m.items,
1163
- coverage: d
1257
+ games: d.items,
1258
+ coverage: h
1164
1259
  };
1165
1260
  }
1166
1261
  get ctx() {
1167
1262
  return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
1168
- teamsById: g(this.data.teams),
1169
- schoolsById: g(this.data.schools),
1170
- records: D(this.data.games),
1263
+ teamsById: v(this.data.teams),
1264
+ schoolsById: v(this.data.schools),
1265
+ records: z(this.data.games),
1171
1266
  rankings: this.data.rankings,
1172
- hrefs: C(this),
1267
+ hrefs: D(this),
1173
1268
  sport: this.data.game.sport
1174
1269
  }, this._ctxData = this.data), this._ctx;
1175
1270
  }
1176
1271
  renderView() {
1177
1272
  const e = this.data.game;
1178
1273
  if (!e) return l`<div class="view"><p class="empty">Game not found.</p></div>`;
1179
- const t = this.ctx, s = g(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, n = j(e), i = (c) => e.state === "final" && n !== c && n !== "tie" ? "opacity:0.45" : "", m = 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));
1274
+ 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, n = j(e), i = (c) => e.state === "final" && n !== c && n !== "tie" ? "opacity:0.45" : "", d = e.conferenceId ? s[e.conferenceId] : null, h = 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));
1180
1275
  return l`
1181
1276
  <div class="view">
1182
1277
  <p class="breadcrumbs">
1183
- <a href=${v(t.hrefs.section, { sport: e.sport, view: "scores" })}>${R(e.sport)}</a> /
1184
- <a href=${v(t.hrefs.section, { sport: e.sport, view: "scores" })}>Scores/Schedules</a> /
1185
- ${k(t, e.awayTeamId)} at ${k(t, e.homeTeamId)}
1278
+ <a href=${u(t.hrefs.section, { sport: e.sport, view: "scores" })}>${T(e.sport)}</a> /
1279
+ <a href=${u(t.hrefs.section, { sport: e.sport, view: "scores" })}>Scores/Schedules</a> /
1280
+ ${S(t, e.awayTeamId)} at ${S(t, e.homeTeamId)}
1186
1281
  </p>
1187
1282
  <div class="card">
1188
1283
  <div class="scorehead">
@@ -1193,11 +1288,11 @@ class De extends b {
1193
1288
  <span class="mut" style="font-size:1.6rem">–</span>
1194
1289
  <span style=${i("home")}>${e.homeScore}</span>
1195
1290
  </div>
1196
- <div class="status">${B(e)}</div>
1197
- <div class="status">${$(e.date, { weekday: "short", month: "short", day: "numeric", year: "numeric" })}${e.state === "scheduled" && e.time ? l` · ${E(e.time)}` : p} · ${e.venue || "Venue TBD"}
1291
+ <div class="status">${R(e)}</div>
1292
+ <div class="status">${b(e.date, { weekday: "short", month: "short", day: "numeric", year: "numeric" })}${e.state === "scheduled" && e.time ? l` · ${A(e.time)}` : p} · ${e.venue || "Venue TBD"}
1198
1293
  ${e.broadcast ? l` · <span class="pill class">${e.broadcast}</span>` : p}</div>
1199
1294
  <div class="status">
1200
- <span class="pill type">${e.gameType === "conference" ? `${m?.name || "Conference"} game` : e.gameType}</span>
1295
+ <span class="pill type">${e.gameType === "conference" ? `${d?.name || "Conference"} game` : e.gameType}</span>
1201
1296
  ${e.label ? l`<span class="pill type">Bracket ${e.label}</span>` : p}
1202
1297
  ${(e.tags || []).map((c) => l`<span class="pill type">${c}</span>`)}
1203
1298
  </div>
@@ -1225,15 +1320,15 @@ class De extends b {
1225
1320
  </div>` : p}
1226
1321
  <div class="section-title">Season context</div>
1227
1322
  <div class="cols">
1228
- ${[[e.awayTeamId, r], [e.homeTeamId, o]].map(([c, h]) => this.renderContext(t, c, h))}
1323
+ ${[[e.awayTeamId, r], [e.homeTeamId, o]].map(([c, m]) => this.renderContext(t, c, m))}
1229
1324
  </div>
1230
- ${d.length ? l`
1325
+ ${h.length ? l`
1231
1326
  <div class="section-title">Head to head this season</div>
1232
1327
  <div class="card"><ul class="gamelist">
1233
- ${d.map((c) => l`<li>
1234
- <span class="d">${$(c.date)}</span>${B(c)}
1235
- <span class="opp">${k(t, c.awayTeamId)} ${c.awayScore}, ${k(t, c.homeTeamId)} ${c.homeScore}</span>
1236
- <a class="box" href=${v(t.hrefs.game, { sport: e.sport, id: c.id })}>Box score →</a>
1328
+ ${h.map((c) => l`<li>
1329
+ <span class="d">${b(c.date)}</span>${R(c)}
1330
+ <span class="opp">${S(t, c.awayTeamId)} ${c.awayScore}, ${S(t, c.homeTeamId)} ${c.homeScore}</span>
1331
+ <a class="box" href=${u(t.hrefs.game, { sport: e.sport, id: c.id })}>Box score →</a>
1237
1332
  </li>`)}
1238
1333
  </ul></div>` : p}
1239
1334
  </div>
@@ -1241,12 +1336,12 @@ class De extends b {
1241
1336
  }
1242
1337
  teamBlock(e, t, s, r, o) {
1243
1338
  if (!r) return l`<div class="teamblock ${o ? "right" : ""}"><div class="tname">TBD</div></div>`;
1244
- const n = e.teamsById[s], i = e.records[s], m = P(r, 58);
1339
+ const n = e.teamsById[s], i = e.records[s], d = P(r, 58);
1245
1340
  return l`
1246
1341
  <div class="teamblock ${o ? "right" : ""}">
1247
- ${m ? l`<img class="crest logo" alt="" loading="lazy" src=${m} />` : l`<span class="crest" style="background:${r.colorPrimary || "#030711"};color:${F(r.colorPrimary || "#030711")}">${M(r)}</span>`}
1342
+ ${d ? l`<img class="crest logo" alt="" loading="lazy" src=${d} />` : l`<span class="crest" style="background:${r.colorPrimary || "#030711"};color:${B(r.colorPrimary || "#030711")}">${M(r)}</span>`}
1248
1343
  <div>
1249
- <div class="tname">${G(e, s, t.date)}<a href=${v(e.hrefs.school, { id: r.id })}>${r.name}</a></div>
1344
+ <div class="tname">${q(e, s, t.date)}<a href=${u(e.hrefs.school, { id: r.id })}>${r.name}</a></div>
1250
1345
  <div class="trec">${r.mascot || ""} · ${w(i)}${n?.conferenceId ? l` · ${w(i, !0)} conf` : p}</div>
1251
1346
  </div>
1252
1347
  </div>
@@ -1256,22 +1351,22 @@ class De extends b {
1256
1351
  const r = e.periodScores || [];
1257
1352
  if (!r.length)
1258
1353
  return l`<p class="empty" style="text-align:center">Period scoring will appear once the game starts.</p>`;
1259
- const o = Math.max(4, ...r.map((d) => d.period)), n = (d) => d <= 4 ? String(d) : `OT${d > 5 ? d - 4 : ""}`, i = (d, c) => {
1260
- const h = r.find((f) => f.period === c);
1261
- return h ? h[d] : e.state === "final" ? 0 : "·";
1262
- }, m = (d, c, h) => l`
1354
+ const o = Math.max(4, ...r.map((h) => h.period)), n = (h) => h <= 4 ? String(h) : `OT${h > 5 ? h - 4 : ""}`, i = (h, c) => {
1355
+ const m = r.find((f) => f.period === c);
1356
+ return m ? m[h] : e.state === "final" ? 0 : "·";
1357
+ }, d = (h, c, m) => l`
1263
1358
  <tr>
1264
- <td class="teamcell">${I(d, 20)}${d?.abbr || "TBD"}</td>
1265
- ${Array.from({ length: o }, (f, u) => l`<td class="num">${i(c, u + 1)}</td>`)}
1266
- <td class="num" style="font-weight:700">${h}</td>
1359
+ <td class="teamcell">${C(h, 20)}${h?.abbr || "TBD"}</td>
1360
+ ${Array.from({ length: o }, (f, g) => l`<td class="num">${i(c, g + 1)}</td>`)}
1361
+ <td class="num" style="font-weight:700">${m}</td>
1267
1362
  </tr>`;
1268
1363
  return l`
1269
1364
  <div class="tablewrap" style="border-top:1px solid var(--hsot-gray-2)">
1270
1365
  <table class="data" style="max-width:560px;margin:0.6rem auto 0.9rem">
1271
- <thead><tr><th>Team</th>${Array.from({ length: o }, (d, c) => l`<th class="num">${n(c + 1)}</th>`)}<th class="num">T</th></tr></thead>
1366
+ <thead><tr><th>Team</th>${Array.from({ length: o }, (h, c) => l`<th class="num">${n(c + 1)}</th>`)}<th class="num">T</th></tr></thead>
1272
1367
  <tbody>
1273
- ${m(t, "away", e.awayScore)}
1274
- ${m(s, "home", e.homeScore)}
1368
+ ${d(t, "away", e.awayScore)}
1369
+ ${d(s, "home", e.homeScore)}
1275
1370
  </tbody>
1276
1371
  </table>
1277
1372
  </div>
@@ -1279,37 +1374,37 @@ class De extends b {
1279
1374
  }
1280
1375
  renderContext(e, t, s) {
1281
1376
  if (!s) return p;
1282
- const r = e.records[t], o = H(this.data.games, t);
1377
+ const r = e.records[t], o = G(this.data.games, t);
1283
1378
  return l`
1284
1379
  <div class="card ctxcard">
1285
- <div class="who">${I(s)}${s.name}</div>
1380
+ <div class="who">${C(s)}${s.name}</div>
1286
1381
  <div class="row">
1287
- <span>Last 5: ${W(e, t)}</span>
1288
- <span>Streak: <b>${r ? _(r.results) : "·"}</b></span>
1382
+ <span>Last 5: ${V(e, t)}</span>
1383
+ <span>Streak: <b>${r ? L(r.results) : "·"}</b></span>
1289
1384
  <span>PF/PA: <b>${r ? `${r.pf} / ${r.pa}` : "·"}</b></span>
1290
- <span>Next: ${o ? l`${$(o.date, { month: "numeric", day: "numeric" })}
1291
- ${o.homeTeamId === t ? "vs" : "at"} ${z(e, o.homeTeamId === t ? o.awayTeamId : o.homeTeamId)}` : "·"}</span>
1385
+ <span>Next: ${o ? l`${b(o.date, { month: "numeric", day: "numeric" })}
1386
+ ${o.homeTeamId === t ? "vs" : "at"} ${_(e, o.homeTeamId === t ? o.awayTeamId : o.homeTeamId)}` : "·"}</span>
1292
1387
  </div>
1293
1388
  </div>
1294
1389
  `;
1295
1390
  }
1296
1391
  }
1297
- globalThis?.customElements && !globalThis.customElements.get("hsot-boxscore") && globalThis.customElements.define("hsot-boxscore", De);
1392
+ globalThis?.customElements && !globalThis.customElements.get("hsot-boxscore") && globalThis.customElements.define("hsot-boxscore", Re);
1298
1393
  export {
1299
- N as D,
1300
- De as H,
1301
- be as a,
1302
- we as b,
1303
- ge as c,
1304
- ve as d,
1305
- D as e,
1306
- ae as f,
1307
- v as g,
1394
+ O as D,
1395
+ Re as H,
1396
+ Ie as a,
1397
+ De as b,
1398
+ ke as c,
1399
+ Te as d,
1400
+ z as e,
1401
+ ne as f,
1402
+ u as g,
1308
1403
  j as h,
1309
- Fe as i,
1310
- _ as j,
1311
- fe as p,
1404
+ Ee as i,
1405
+ L as j,
1406
+ we as p,
1312
1407
  w as r,
1313
- K as s,
1314
- X as t
1408
+ J as s,
1409
+ ee as t
1315
1410
  };