@wral/hsot-data 0.1.1 → 0.1.3
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.
- package/dist/define.mjs +1 -1
- package/dist/define.standalone.js +386 -319
- package/dist/{hsot-boxscore-D-tEuTZe.js → hsot-boxscore-CY8jCxLh.js} +388 -321
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
import { LitElement as
|
|
2
|
-
const
|
|
3
|
-
function
|
|
1
|
+
import { LitElement as Z, html as l, css as $, nothing as p, svg as q } from "lit";
|
|
2
|
+
const ee = 50;
|
|
3
|
+
function te(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,
|
|
7
|
+
return e.forEach(([s, r]) => t.set(s, String(r))), `?${t.toString()}`;
|
|
8
8
|
}
|
|
9
|
-
function
|
|
9
|
+
function se({ baseUrl: a, token: e = "", fetchFn: t } = {}) {
|
|
10
10
|
if (!a) throw new Error("createClient requires a baseUrl");
|
|
11
|
-
const s = a.replace(/\/+$/, ""),
|
|
12
|
-
async function
|
|
11
|
+
const s = a.replace(/\/+$/, ""), r = t || ((...i) => fetch(...i));
|
|
12
|
+
async function o(i) {
|
|
13
13
|
const m = { Accept: "application/json" };
|
|
14
14
|
e && (m.Authorization = `Bearer ${e}`);
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
17
|
-
const c = new Error(`api-hsot ${
|
|
18
|
-
throw c.status =
|
|
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;
|
|
19
19
|
}
|
|
20
|
-
return
|
|
20
|
+
return d.json();
|
|
21
21
|
}
|
|
22
22
|
async function n(i, m = {}) {
|
|
23
|
-
const
|
|
23
|
+
const d = [];
|
|
24
24
|
let c = null;
|
|
25
|
-
for (let
|
|
26
|
-
const f =
|
|
27
|
-
if (
|
|
25
|
+
for (let h = 0; h < ee; h += 1) {
|
|
26
|
+
const f = te(c ? { ...m, cursor: c } : m), u = await o(`${i}${f}`);
|
|
27
|
+
if (d.push(...u.items || []), c = u.nextCursor || null, !c) break;
|
|
28
28
|
}
|
|
29
|
-
return { items:
|
|
29
|
+
return { items: d, total: d.length, nextCursor: null };
|
|
30
30
|
}
|
|
31
31
|
return {
|
|
32
32
|
listSchools: (i) => n("/schools", i),
|
|
33
|
-
getSchool: (i) =>
|
|
33
|
+
getSchool: (i) => o(`/schools/${i}`),
|
|
34
34
|
listTeams: (i) => n("/teams", i),
|
|
35
|
-
getTeam: (i) =>
|
|
35
|
+
getTeam: (i) => o(`/teams/${i}`),
|
|
36
36
|
listConferences: (i) => n("/conferences", i),
|
|
37
37
|
listPlayers: (i) => n("/players", i),
|
|
38
38
|
listRosters: (i) => n("/rosters", i),
|
|
39
39
|
listGames: (i) => n("/games", i),
|
|
40
|
-
getGame: (i) =>
|
|
40
|
+
getGame: (i) => o(`/games/${i}`),
|
|
41
41
|
listTournaments: (i) => n("/tournaments", i),
|
|
42
42
|
listSeedings: (i, m) => n(`/tournaments/${i}/seedings`, m),
|
|
43
43
|
listRankings: (i) => n("/rankings", i),
|
|
44
|
-
listSports: () =>
|
|
44
|
+
listSports: () => o("/sports")
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
-
class y extends
|
|
47
|
+
class y extends Z {
|
|
48
48
|
static properties = {
|
|
49
49
|
api: { type: String },
|
|
50
50
|
refreshInterval: { type: Number, attribute: "refresh-interval" },
|
|
@@ -60,7 +60,7 @@ class y extends J {
|
|
|
60
60
|
this._client = e, this.isConnected && this.load();
|
|
61
61
|
}
|
|
62
62
|
get client() {
|
|
63
|
-
return this._client ? this._client : this.api ?
|
|
63
|
+
return this._client ? this._client : this.api ? se({ baseUrl: this.api }) : null;
|
|
64
64
|
}
|
|
65
65
|
connectedCallback() {
|
|
66
66
|
super.connectedCallback(), this._setupInterval();
|
|
@@ -107,7 +107,7 @@ class y extends J {
|
|
|
107
107
|
return l``;
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
-
const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])),
|
|
110
|
+
const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), ae = $`
|
|
111
111
|
:host {
|
|
112
112
|
--hsot-red: var(--color-red, #D1232A);
|
|
113
113
|
--hsot-red-deep: var(--color-red-dark, #951C21);
|
|
@@ -141,7 +141,7 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), se = b`
|
|
|
141
141
|
outline-offset: 1px;
|
|
142
142
|
}
|
|
143
143
|
.mut { color: var(--hsot-gray-5); }
|
|
144
|
-
`,
|
|
144
|
+
`, re = $`
|
|
145
145
|
.band { background: var(--hsot-white); color: var(--hsot-black); }
|
|
146
146
|
.band .inner { max-width: 1366px; margin: 0 auto; padding: 1.1rem 1.25rem 0; }
|
|
147
147
|
.band h1, .band h2.bandtitle {
|
|
@@ -161,7 +161,7 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), se = b`
|
|
|
161
161
|
.band nav.tabs a.on { border-bottom-color: var(--hsot-red); }
|
|
162
162
|
.band nav.tabs span.off { color: var(--hsot-gray-4); cursor: not-allowed; }
|
|
163
163
|
@media (max-width: 720px) { .band h1, .band h2.bandtitle { font-size: 1.8rem; } }
|
|
164
|
-
`,
|
|
164
|
+
`, oe = $`
|
|
165
165
|
.view { max-width: 1366px; margin: 0 auto; padding: 1.25rem; box-sizing: border-box; }
|
|
166
166
|
.toolbar { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; margin: 0 0 1.1rem; }
|
|
167
167
|
.toolbar .spacer { flex: 1; }
|
|
@@ -204,7 +204,7 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), se = b`
|
|
|
204
204
|
.error { padding: 1.2rem 1rem; color: var(--hsot-red-deep); font-size: 0.9rem; }
|
|
205
205
|
.note { font-size: 0.8125rem; color: var(--hsot-gray-5); margin: 0.6rem 0 0; }
|
|
206
206
|
.loading { padding: 1.2rem; color: var(--hsot-gray-5); font-family: var(--hsot-heading-font); }
|
|
207
|
-
`,
|
|
207
|
+
`, ie = $`
|
|
208
208
|
.pill {
|
|
209
209
|
display: inline-block; font-family: var(--hsot-heading-font); font-weight: 700;
|
|
210
210
|
font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em;
|
|
@@ -219,7 +219,7 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), se = b`
|
|
|
219
219
|
.pill.champ { background: var(--hsot-straw); color: #6b5900; }
|
|
220
220
|
@keyframes hsot-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
|
|
221
221
|
@media (prefers-reduced-motion: reduce) { .pill.live { animation: none; } }
|
|
222
|
-
`, ne =
|
|
222
|
+
`, ne = $`
|
|
223
223
|
.tablewrap { overflow-x: auto; }
|
|
224
224
|
table.data { font-family: var(--hsot-heading-font); font-size: 14px; border-collapse: collapse; width: 100%; }
|
|
225
225
|
table.data th {
|
|
@@ -237,13 +237,19 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), se = b`
|
|
|
237
237
|
table.data tbody tr.rowlink:hover { background: var(--hsot-gray-1); }
|
|
238
238
|
table.data td.teamcell a { color: inherit; text-decoration: none; font-weight: 500; }
|
|
239
239
|
table.data td.teamcell a:hover { text-decoration: underline; }
|
|
240
|
-
`,
|
|
240
|
+
`, le = $`
|
|
241
241
|
.swatch {
|
|
242
242
|
display: inline-flex; align-items: center; justify-content: center;
|
|
243
243
|
width: 26px; height: 26px; border-radius: 50%;
|
|
244
244
|
font-family: var(--hsot-heading-font); font-weight: 700; font-size: 0.55rem;
|
|
245
245
|
margin-right: 0.5rem; vertical-align: middle; flex: none;
|
|
246
246
|
}
|
|
247
|
+
/* Picked school logo (DEV-1236 ref) in the same footprint: contained,
|
|
248
|
+
never cropped, on white so any logo art stays legible. */
|
|
249
|
+
.swatch.logo {
|
|
250
|
+
object-fit: contain; background: var(--hsot-white);
|
|
251
|
+
border: 1px solid var(--hsot-gray-2); padding: 2px; box-sizing: border-box;
|
|
252
|
+
}
|
|
247
253
|
.rankbadge { font-weight: 700; color: var(--hsot-red-deep); font-size: 0.8em; margin-right: 0.22rem; }
|
|
248
254
|
.dots { display: inline-flex; gap: 3px; }
|
|
249
255
|
.dot {
|
|
@@ -255,7 +261,7 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), se = b`
|
|
|
255
261
|
.dot.W { background: var(--hsot-win); }
|
|
256
262
|
.dot.L { background: var(--hsot-loss); }
|
|
257
263
|
.dot.T { background: var(--hsot-tie); }
|
|
258
|
-
`,
|
|
264
|
+
`, ce = $`
|
|
259
265
|
ul.gamelist { list-style: none; margin: 0; padding: 0; }
|
|
260
266
|
.gamelist li {
|
|
261
267
|
display: flex; align-items: center; gap: 0.7rem; padding: 0.55rem 1rem;
|
|
@@ -272,55 +278,55 @@ const g = (a) => Object.fromEntries((a || []).map((e) => [e.id, e])), se = b`
|
|
|
272
278
|
.gamelist .opp a:hover { text-decoration: underline; }
|
|
273
279
|
.gamelist .where { color: var(--hsot-gray-5); font-size: 0.78rem; }
|
|
274
280
|
.gamelist a.box { font-size: 0.78rem; }
|
|
275
|
-
`, S = [
|
|
276
|
-
function
|
|
281
|
+
`, S = [ae, re, oe, ie, ne, le, ce];
|
|
282
|
+
function H(a) {
|
|
277
283
|
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";
|
|
278
284
|
}
|
|
279
|
-
function
|
|
280
|
-
const t = {}, s = (
|
|
281
|
-
for (const
|
|
282
|
-
const n =
|
|
285
|
+
function D(a, e) {
|
|
286
|
+
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
|
+
for (const o of r) {
|
|
288
|
+
const n = H(o), i = o.gameType === "conference";
|
|
283
289
|
for (const m of ["home", "away"]) {
|
|
284
|
-
const
|
|
285
|
-
if (!
|
|
286
|
-
const c = s(
|
|
287
|
-
c.pf +=
|
|
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;
|
|
288
294
|
let u = "T";
|
|
289
|
-
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:
|
|
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 });
|
|
290
296
|
}
|
|
291
297
|
}
|
|
292
298
|
return t;
|
|
293
299
|
}
|
|
294
|
-
function
|
|
300
|
+
function _(a) {
|
|
295
301
|
if (!a || !a.length) return "";
|
|
296
302
|
const e = a[a.length - 1].mark;
|
|
297
303
|
let t = 0;
|
|
298
304
|
for (let s = a.length - 1; s >= 0 && a[s].mark === e; s -= 1) t += 1;
|
|
299
305
|
return e + t;
|
|
300
306
|
}
|
|
301
|
-
const
|
|
307
|
+
const V = (a, e, t) => {
|
|
302
308
|
const s = a + e + t;
|
|
303
309
|
return s ? (a + t / 2) / s : 0;
|
|
304
|
-
},
|
|
310
|
+
}, Y = (a) => a.toFixed(3).replace("0.", ".");
|
|
305
311
|
function w(a, e = !1) {
|
|
306
312
|
if (!a) return "0-0";
|
|
307
|
-
const t = e ? a.cw : a.w, s = e ? a.cl : a.l,
|
|
308
|
-
return `${t}-${s}${
|
|
313
|
+
const t = e ? a.cw : a.w, s = e ? a.cl : a.l, r = e ? a.ct : a.t;
|
|
314
|
+
return `${t}-${s}${r ? `-${r}` : ""}`;
|
|
309
315
|
}
|
|
310
316
|
function K(a, e) {
|
|
311
317
|
return a.map((t) => {
|
|
312
318
|
const s = e[t.id] || { w: 0, l: 0, t: 0, cw: 0, cl: 0, ct: 0, pf: 0, pa: 0, results: [] };
|
|
313
|
-
return { team: t, rec: s, confPct:
|
|
319
|
+
return { team: t, rec: s, confPct: V(s.cw, s.cl, s.ct), overallPct: V(s.w, s.l, s.t) };
|
|
314
320
|
}).sort((t, s) => s.confPct - t.confPct || s.overallPct - t.overallPct || s.rec.pf - s.rec.pa - (t.rec.pf - t.rec.pa));
|
|
315
321
|
}
|
|
316
|
-
function
|
|
322
|
+
function M(a, e) {
|
|
317
323
|
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;
|
|
318
324
|
}
|
|
319
|
-
function
|
|
325
|
+
function Q(a, e) {
|
|
320
326
|
const t = a[e];
|
|
321
327
|
return t && t.results.length ? t.results[t.results.length - 1] : null;
|
|
322
328
|
}
|
|
323
|
-
const
|
|
329
|
+
const N = {
|
|
324
330
|
game: "/{sport}/game/{id}/",
|
|
325
331
|
school: "/school/{id}/",
|
|
326
332
|
section: "/{sport}/{view}/"
|
|
@@ -328,128 +334,141 @@ const L = {
|
|
|
328
334
|
function v(a, e) {
|
|
329
335
|
return String(a).replace(/\{(\w+)\}/g, (t, s) => e[s] !== void 0 && e[s] !== null ? String(e[s]) : t);
|
|
330
336
|
}
|
|
331
|
-
function
|
|
337
|
+
function C(a) {
|
|
332
338
|
return {
|
|
333
|
-
game: a.getAttribute("game-href") ||
|
|
334
|
-
school: a.getAttribute("school-href") ||
|
|
335
|
-
section: a.getAttribute("section-href") ||
|
|
339
|
+
game: a.getAttribute("game-href") || N.game,
|
|
340
|
+
school: a.getAttribute("school-href") || N.school,
|
|
341
|
+
section: a.getAttribute("section-href") || N.section
|
|
336
342
|
};
|
|
337
343
|
}
|
|
338
|
-
const
|
|
339
|
-
function
|
|
344
|
+
const R = (a) => a ? a.charAt(0).toUpperCase() + a.slice(1) : "";
|
|
345
|
+
function b(a, e) {
|
|
340
346
|
if (!a) return "TBD";
|
|
341
|
-
const [t, s,
|
|
342
|
-
return !t || !s || !
|
|
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" });
|
|
343
349
|
}
|
|
344
|
-
function
|
|
350
|
+
function E(a) {
|
|
345
351
|
if (!a) return "";
|
|
346
352
|
const [e, t] = String(a).split(":").map(Number);
|
|
347
353
|
if (Number.isNaN(e)) return "";
|
|
348
354
|
const s = e >= 12 ? "PM" : "AM";
|
|
349
355
|
return `${(e + 11) % 12 + 1}:${String(t || 0).padStart(2, "0")} ${s}`;
|
|
350
356
|
}
|
|
351
|
-
function
|
|
357
|
+
function de(a) {
|
|
352
358
|
return a ? `${Math.floor(a / 12)}-${a % 12}` : "·";
|
|
353
359
|
}
|
|
354
360
|
function A(a = /* @__PURE__ */ new Date()) {
|
|
355
361
|
const e = a.getFullYear();
|
|
356
362
|
return a.getMonth() >= 6 ? `${e}-${e + 1}` : `${e - 1}-${e}`;
|
|
357
363
|
}
|
|
358
|
-
function
|
|
364
|
+
function O(a = /* @__PURE__ */ new Date()) {
|
|
359
365
|
const e = (t) => String(t).padStart(2, "0");
|
|
360
366
|
return `${a.getFullYear()}-${e(a.getMonth() + 1)}-${e(a.getDate())}`;
|
|
361
367
|
}
|
|
362
|
-
function
|
|
368
|
+
function j(a) {
|
|
363
369
|
return a ? (a.abbr || a.name || "?").slice(0, 4).toUpperCase() : "?";
|
|
364
370
|
}
|
|
365
371
|
function F(a) {
|
|
366
372
|
if (!a || !/^#[0-9a-fA-F]{6}$/.test(a)) return "#FFFFFF";
|
|
367
|
-
const e = parseInt(a.slice(1), 16), t = e >> 16 & 255, s = e >> 8 & 255,
|
|
368
|
-
return 0.299 * t + 0.587 * s + 0.114 *
|
|
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";
|
|
369
375
|
}
|
|
370
|
-
const
|
|
376
|
+
const he = (a) => {
|
|
371
377
|
const e = ["th", "st", "nd", "rd"], t = a % 100;
|
|
372
378
|
return a + (e[(t - 20) % 10] || e[t] || e[0]);
|
|
373
379
|
};
|
|
374
|
-
function
|
|
380
|
+
function me(a) {
|
|
375
381
|
if (a.state === "live") return { kind: "live", label: `Live · ${a.period || ""}`.replace(/ · $/, "") };
|
|
376
382
|
if (a.state === "final") {
|
|
377
383
|
const e = [];
|
|
378
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(" · ")}` : ""}` };
|
|
379
385
|
}
|
|
380
|
-
return a.state === "postponed" ? { kind: "warn", label: "Postponed" } : a.state === "canceled" ? { kind: "warn", label: "Canceled" } : { kind: "sched", label: `${
|
|
386
|
+
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" })} · ${E(a.time)}`.replace(/ · $/, "") };
|
|
381
387
|
}
|
|
382
|
-
function
|
|
383
|
-
let
|
|
384
|
-
for (const
|
|
385
|
-
|
|
386
|
-
return
|
|
388
|
+
function Ce(a, e, t, s = "") {
|
|
389
|
+
let r = null;
|
|
390
|
+
for (const o of a || [])
|
|
391
|
+
o.sport === e && (t && o.effectiveDate > t || s && o.gender && o.gender !== s || (!r || o.effectiveDate > r.effectiveDate) && (r = o));
|
|
392
|
+
return r;
|
|
387
393
|
}
|
|
388
|
-
function
|
|
389
|
-
const
|
|
390
|
-
if (!
|
|
394
|
+
function X(a, e, t, s, r) {
|
|
395
|
+
const o = e[t];
|
|
396
|
+
if (!o) return null;
|
|
391
397
|
const n = /* @__PURE__ */ new Map();
|
|
392
398
|
for (const m of a || []) {
|
|
393
|
-
if (m.sport !== s ||
|
|
394
|
-
const
|
|
395
|
-
(!c || m.effectiveDate > c.effectiveDate) && n.set(
|
|
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);
|
|
396
402
|
}
|
|
397
403
|
let i = null;
|
|
398
404
|
for (const m of n.values()) {
|
|
399
|
-
const
|
|
400
|
-
|
|
405
|
+
const d = (m.teamIds || []).indexOf(t);
|
|
406
|
+
d !== -1 && (!i || m.effectiveDate > i.effectiveDate) && (i = { poll: m, rank: d + 1 });
|
|
401
407
|
}
|
|
402
408
|
return i ? i.rank : null;
|
|
403
409
|
}
|
|
404
|
-
function
|
|
410
|
+
function pe(a, e, t) {
|
|
405
411
|
if (!a) return { kind: "none", delta: 0 };
|
|
406
412
|
const s = (a.teamIds || []).indexOf(t) + 1;
|
|
407
413
|
if (!s) return { kind: "none", delta: 0 };
|
|
408
414
|
if (!e) return { kind: "same", delta: 0 };
|
|
409
|
-
const
|
|
410
|
-
if (!
|
|
411
|
-
const
|
|
412
|
-
return
|
|
415
|
+
const r = (e.teamIds || []).indexOf(t) + 1;
|
|
416
|
+
if (!r) return { kind: "new", delta: 0 };
|
|
417
|
+
const o = r - s;
|
|
418
|
+
return o > 0 ? { kind: "up", delta: o } : o < 0 ? { kind: "down", delta: -o } : { kind: "same", delta: 0 };
|
|
419
|
+
}
|
|
420
|
+
function fe(a) {
|
|
421
|
+
return /^https?:\/\//i.test(String(a || ""));
|
|
422
|
+
}
|
|
423
|
+
function P(a, e) {
|
|
424
|
+
const t = a?.logoAssetId;
|
|
425
|
+
if (!fe(t)) return "";
|
|
426
|
+
const s = Math.max(1, Math.round(e * 2)), r = t.includes("?") ? "&" : "?";
|
|
427
|
+
return `${t}${r}w=${s}&h=${s}&f=webp`;
|
|
413
428
|
}
|
|
414
429
|
const T = (a, e) => {
|
|
415
430
|
const t = a.teamsById[e];
|
|
416
431
|
return t ? a.schoolsById[t.schoolId] : null;
|
|
417
|
-
},
|
|
432
|
+
}, k = (a, e) => T(a, e)?.name || "TBD", z = (a, e) => T(a, e)?.abbr || "TBD";
|
|
418
433
|
function I(a, e = 26) {
|
|
419
434
|
if (!a) return p;
|
|
420
|
-
const t = a
|
|
435
|
+
const t = P(a, e);
|
|
436
|
+
if (t)
|
|
437
|
+
return l`<img class="swatch logo" aria-hidden="true" alt="" loading="lazy"
|
|
438
|
+
src=${t} style="width:${e}px;height:${e}px" />`;
|
|
439
|
+
const s = a.colorPrimary || "#030711", r = F(s);
|
|
421
440
|
return l`<span class="swatch" aria-hidden="true"
|
|
422
|
-
style="width:${e}px;height:${e}px;background:${
|
|
423
|
-
>${
|
|
441
|
+
style="width:${e}px;height:${e}px;background:${s};color:${r};font-size:${Math.max(8, e * 0.28)}px"
|
|
442
|
+
>${j(a)}</span>`;
|
|
424
443
|
}
|
|
425
|
-
function
|
|
426
|
-
const s =
|
|
444
|
+
function G(a, e, t) {
|
|
445
|
+
const s = X(a.rankings, a.teamsById, e, a.sport, t);
|
|
427
446
|
return s ? l`<span class="rankbadge">#${s}</span>` : p;
|
|
428
447
|
}
|
|
429
|
-
function
|
|
448
|
+
function U(a, e, t) {
|
|
430
449
|
const s = T(a, e);
|
|
431
|
-
return s ? l`${
|
|
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>`;
|
|
432
451
|
}
|
|
433
|
-
function
|
|
452
|
+
function W(a, e, t = 5) {
|
|
434
453
|
const s = a.records[e];
|
|
435
454
|
if (!s || !s.results.length) return l`<span class="mut">·</span>`;
|
|
436
|
-
const
|
|
437
|
-
return l`<span class="dots" role="img" aria-label="last ${
|
|
438
|
-
${
|
|
439
|
-
title="${
|
|
440
|
-
href=${v(a.hrefs.game, { sport: a.sport, id:
|
|
455
|
+
const r = s.results.slice(-1 * t);
|
|
456
|
+
return l`<span class="dots" role="img" aria-label="last ${r.length} results">
|
|
457
|
+
${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>`)}
|
|
441
460
|
</span>`;
|
|
442
461
|
}
|
|
443
|
-
function
|
|
444
|
-
const e =
|
|
462
|
+
function B(a) {
|
|
463
|
+
const e = me(a);
|
|
445
464
|
return l`<span class="pill ${e.kind}">${e.label}</span>`;
|
|
446
465
|
}
|
|
447
|
-
function
|
|
466
|
+
function J(a, e, t) {
|
|
448
467
|
if (!e) return l`<span class="mut">·</span>`;
|
|
449
|
-
const s = e.homeTeamId === t ? e.awayTeamId : e.homeTeamId,
|
|
450
|
-
return l`${e.state === "live" ? l`<span class="pill live">Live</span> ` : l`${
|
|
468
|
+
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`${b(e.date, { month: "numeric", day: "numeric" })} `}${r} ${z(a, s)}`;
|
|
451
470
|
}
|
|
452
|
-
class
|
|
471
|
+
class ue extends y {
|
|
453
472
|
static styles = S;
|
|
454
473
|
static properties = {
|
|
455
474
|
...y.properties,
|
|
@@ -463,11 +482,11 @@ class pe extends y {
|
|
|
463
482
|
connectedCallback() {
|
|
464
483
|
if (super.connectedCallback(), !this.date) {
|
|
465
484
|
const e = new URLSearchParams(globalThis.location?.search || "").get("date");
|
|
466
|
-
this.date = e ||
|
|
485
|
+
this.date = e || O();
|
|
467
486
|
}
|
|
468
487
|
}
|
|
469
488
|
async fetchData(e) {
|
|
470
|
-
const t = this.season || A(), [s,
|
|
489
|
+
const t = this.season || A(), [s, r, o, n, i] = await Promise.all([
|
|
471
490
|
e.listSchools(),
|
|
472
491
|
e.listTeams({ sport: this.sport }),
|
|
473
492
|
e.listConferences(),
|
|
@@ -477,8 +496,8 @@ class pe extends y {
|
|
|
477
496
|
return {
|
|
478
497
|
season: t,
|
|
479
498
|
schools: s.items,
|
|
480
|
-
teams:
|
|
481
|
-
conferences:
|
|
499
|
+
teams: r.items,
|
|
500
|
+
conferences: o.items,
|
|
482
501
|
games: n.items,
|
|
483
502
|
rankings: i.items
|
|
484
503
|
};
|
|
@@ -487,22 +506,22 @@ class pe extends y {
|
|
|
487
506
|
return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
|
|
488
507
|
teamsById: g(this.data.teams),
|
|
489
508
|
schoolsById: g(this.data.schools),
|
|
490
|
-
records:
|
|
509
|
+
records: D(this.data.games),
|
|
491
510
|
rankings: this.data.rankings,
|
|
492
|
-
hrefs:
|
|
511
|
+
hrefs: C(this),
|
|
493
512
|
sport: this.sport
|
|
494
513
|
}, this._ctxData = this.data), this._ctx;
|
|
495
514
|
}
|
|
496
515
|
renderView() {
|
|
497
|
-
const e = this.ctx, t = g(this.data.conferences), s = [...new Set(this.data.games.map((n) => n.date).filter(Boolean))].sort(),
|
|
498
|
-
return
|
|
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();
|
|
517
|
+
return r.forEach((n) => {
|
|
499
518
|
const i = n.gameType === "conference" && n.conferenceId ? t[n.conferenceId]?.name || "Conference" : n.gameType === "playoff" ? "Playoffs" : n.gameType === "scrimmage" ? "Scrimmages" : "Nonconference";
|
|
500
|
-
|
|
519
|
+
o.has(i) || o.set(i, []), o.get(i).push(n);
|
|
501
520
|
}), l`
|
|
502
521
|
<div class="band">
|
|
503
522
|
<div class="inner">
|
|
504
|
-
<h1>${
|
|
505
|
-
<p class="sub">${
|
|
523
|
+
<h1>${R(this.sport)} scores & schedules</h1>
|
|
524
|
+
<p class="sub">${b(this.date, { weekday: "long", month: "long", day: "numeric", year: "numeric" })} · ${r.length} games</p>
|
|
506
525
|
</div>
|
|
507
526
|
</div>
|
|
508
527
|
<div class="view">
|
|
@@ -512,7 +531,7 @@ class pe extends y {
|
|
|
512
531
|
this.date = n.target.value;
|
|
513
532
|
}}>
|
|
514
533
|
${s.map((n) => l`<option value=${n} ?selected=${n === this.date}>
|
|
515
|
-
${
|
|
534
|
+
${b(n, { weekday: "short", month: "short", day: "numeric" })}${n === O() ? " · today" : ""}
|
|
516
535
|
</option>`)}
|
|
517
536
|
</select>
|
|
518
537
|
<button class="chip" ?disabled=${s.indexOf(this.date) <= 0}
|
|
@@ -526,8 +545,8 @@ class pe extends y {
|
|
|
526
545
|
<span class="spacer"></span>
|
|
527
546
|
<span class="asof">Live games first · report a score to see it update here</span>
|
|
528
547
|
</div>
|
|
529
|
-
${
|
|
530
|
-
${[...
|
|
548
|
+
${r.length ? p : l`<p class="empty">No ${this.sport} games on this date.</p>`}
|
|
549
|
+
${[...o.entries()].map(([n, i]) => l`
|
|
531
550
|
<div class="section-title">${n}</div>
|
|
532
551
|
<div class="card"><ul class="gamelist">
|
|
533
552
|
${i.map((m) => this.renderGame(e, m))}
|
|
@@ -537,11 +556,11 @@ class pe extends y {
|
|
|
537
556
|
`;
|
|
538
557
|
}
|
|
539
558
|
renderGame(e, t) {
|
|
540
|
-
const s = t.state === "final" || t.state === "live" ? `${t.awayScore}-${t.homeScore}` :
|
|
559
|
+
const s = t.state === "final" || t.state === "live" ? `${t.awayScore}-${t.homeScore}` : E(t.time);
|
|
541
560
|
return l`
|
|
542
561
|
<li>
|
|
543
|
-
${
|
|
544
|
-
<span class="opp">${
|
|
562
|
+
${B(t)}
|
|
563
|
+
<span class="opp">${U(e, t.awayTeamId, t.date)} at ${U(e, t.homeTeamId, t.date)}</span>
|
|
545
564
|
<span class="res" style="width:auto">${s}</span>
|
|
546
565
|
<span class="where">${t.venue || ""}</span>
|
|
547
566
|
${t.broadcast ? l`<span class="pill class">${t.broadcast}</span>` : p}
|
|
@@ -550,8 +569,8 @@ class pe extends y {
|
|
|
550
569
|
`;
|
|
551
570
|
}
|
|
552
571
|
}
|
|
553
|
-
globalThis?.customElements && !globalThis.customElements.get("hsot-scores") && globalThis.customElements.define("hsot-scores",
|
|
554
|
-
class
|
|
572
|
+
globalThis?.customElements && !globalThis.customElements.get("hsot-scores") && globalThis.customElements.define("hsot-scores", ue);
|
|
573
|
+
class ge extends y {
|
|
555
574
|
static styles = S;
|
|
556
575
|
static properties = {
|
|
557
576
|
...y.properties,
|
|
@@ -564,7 +583,7 @@ class fe extends y {
|
|
|
564
583
|
super(), this.sport = "football", this.season = "", this.classFilter = "All", this.query = "";
|
|
565
584
|
}
|
|
566
585
|
async fetchData(e) {
|
|
567
|
-
const t = this.season || A(), [s,
|
|
586
|
+
const t = this.season || A(), [s, r, o, n, i] = await Promise.all([
|
|
568
587
|
e.listConferences({ active: !0 }),
|
|
569
588
|
e.listSchools(),
|
|
570
589
|
e.listTeams({ sport: this.sport }),
|
|
@@ -574,8 +593,8 @@ class fe extends y {
|
|
|
574
593
|
return {
|
|
575
594
|
season: t,
|
|
576
595
|
conferences: s.items,
|
|
577
|
-
schools:
|
|
578
|
-
teams:
|
|
596
|
+
schools: r.items,
|
|
597
|
+
teams: o.items,
|
|
579
598
|
games: n.items,
|
|
580
599
|
rankings: i.items
|
|
581
600
|
};
|
|
@@ -584,50 +603,50 @@ class fe extends y {
|
|
|
584
603
|
return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
|
|
585
604
|
teamsById: g(this.data.teams),
|
|
586
605
|
schoolsById: g(this.data.schools),
|
|
587
|
-
records:
|
|
606
|
+
records: D(this.data.games),
|
|
588
607
|
rankings: this.data.rankings,
|
|
589
|
-
hrefs:
|
|
608
|
+
hrefs: C(this),
|
|
590
609
|
sport: this.sport
|
|
591
610
|
}, this._ctxData = this.data), this._ctx;
|
|
592
611
|
}
|
|
593
612
|
renderView() {
|
|
594
|
-
const e = this.ctx, t = ["All", ...new Set(this.data.conferences.flatMap((
|
|
613
|
+
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));
|
|
595
614
|
return l`
|
|
596
615
|
<div class="band">
|
|
597
616
|
<div class="inner">
|
|
598
|
-
<h1>${
|
|
617
|
+
<h1>${R(this.sport)} standings</h1>
|
|
599
618
|
<p class="sub">${this.data.season} season · every conference, computed live from reported results</p>
|
|
600
619
|
</div>
|
|
601
620
|
</div>
|
|
602
621
|
<div class="view">
|
|
603
622
|
<div class="toolbar">
|
|
604
623
|
<div role="group" aria-label="Classification filter">
|
|
605
|
-
${t.map((
|
|
624
|
+
${t.map((r) => l`<button class="chip ${this.classFilter === r ? "on" : ""}"
|
|
606
625
|
@click=${() => {
|
|
607
|
-
this.classFilter =
|
|
608
|
-
}}>${
|
|
626
|
+
this.classFilter = r;
|
|
627
|
+
}}>${r}</button>`)}
|
|
609
628
|
</div>
|
|
610
629
|
<input type="search" placeholder="Find a school…" aria-label="Find a school"
|
|
611
|
-
.value=${this.query} @input=${(
|
|
612
|
-
this.query =
|
|
630
|
+
.value=${this.query} @input=${(r) => {
|
|
631
|
+
this.query = r.target.value;
|
|
613
632
|
}}>
|
|
614
633
|
<span class="spacer"></span>
|
|
615
|
-
<span class="asof">Records through ${
|
|
634
|
+
<span class="asof">Records through ${b(O(), { month: "long", day: "numeric" })} · conference games count toward both records · scrimmages toward neither</span>
|
|
616
635
|
</div>
|
|
617
|
-
${s.map((
|
|
636
|
+
${s.map((r) => this.renderConference(e, r))}
|
|
618
637
|
</div>
|
|
619
638
|
`;
|
|
620
639
|
}
|
|
621
640
|
renderConference(e, t) {
|
|
622
641
|
const s = this.data.teams.filter((n) => n.conferenceId === t.id);
|
|
623
642
|
if (!s.length) return p;
|
|
624
|
-
const
|
|
643
|
+
const r = this.query.trim().toLowerCase(), o = K(s, e.records);
|
|
625
644
|
return l`
|
|
626
645
|
<div class="card">
|
|
627
646
|
<div class="card-head">
|
|
628
647
|
<h2>${t.name}</h2>
|
|
629
648
|
${(t.classifications || []).map((n) => l`<span class="pill class">${n}</span>`)}
|
|
630
|
-
<span class="meta">${
|
|
649
|
+
<span class="meta">${o.length} teams · membership derives from teams</span>
|
|
631
650
|
</div>
|
|
632
651
|
<div class="tablewrap"><table class="data">
|
|
633
652
|
<thead><tr>
|
|
@@ -636,44 +655,44 @@ class fe extends y {
|
|
|
636
655
|
<th>Streak</th><th>Last 5</th><th>Next</th>
|
|
637
656
|
</tr></thead>
|
|
638
657
|
<tbody>
|
|
639
|
-
${
|
|
658
|
+
${o.map((n, i) => this.renderRow(e, n, i, r))}
|
|
640
659
|
</tbody>
|
|
641
660
|
</table></div>
|
|
642
661
|
</div>
|
|
643
662
|
`;
|
|
644
663
|
}
|
|
645
|
-
renderRow(e, t, s,
|
|
646
|
-
const
|
|
647
|
-
if (
|
|
648
|
-
const i = t.rec.pf - t.rec.pa, m =
|
|
649
|
-
<span class="pill champ" title="${
|
|
664
|
+
renderRow(e, t, s, r) {
|
|
665
|
+
const o = e.schoolsById[t.team.schoolId], n = o?.name || t.team.name || "TBD";
|
|
666
|
+
if (r && !n.toLowerCase().includes(r)) return p;
|
|
667
|
+
const i = t.rec.pf - t.rec.pa, m = M(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 = () => {
|
|
650
669
|
location.href = v(e.hrefs.school, { id: t.team.schoolId });
|
|
651
670
|
};
|
|
652
671
|
return l`
|
|
653
|
-
<tr class="rowlink" @click=${(
|
|
654
|
-
|
|
672
|
+
<tr class="rowlink" @click=${(h) => {
|
|
673
|
+
h.target.closest("a") || c();
|
|
655
674
|
}}>
|
|
656
675
|
<td class="mut">${s + 1}</td>
|
|
657
676
|
<td class="teamcell">
|
|
658
|
-
${I(
|
|
659
|
-
<a href=${v(e.hrefs.school, { id: t.team.schoolId })}>${n}</a> ${
|
|
677
|
+
${I(o)}${G(e, t.team.id, null)}
|
|
678
|
+
<a href=${v(e.hrefs.school, { id: t.team.schoolId })}>${n}</a> ${d}
|
|
660
679
|
</td>
|
|
661
680
|
<td class="num">${w(t.rec, !0)}</td>
|
|
662
|
-
<td class="num">${
|
|
681
|
+
<td class="num">${Y(t.confPct)}</td>
|
|
663
682
|
<td class="num">${w(t.rec)}</td>
|
|
664
|
-
<td class="num">${
|
|
683
|
+
<td class="num">${Y(t.overallPct)}</td>
|
|
665
684
|
<td class="num">${t.rec.pf}</td>
|
|
666
685
|
<td class="num">${t.rec.pa}</td>
|
|
667
686
|
<td class="num" style="color:${i >= 0 ? "var(--hsot-win)" : "var(--hsot-loss)"}">${i > 0 ? "+" : ""}${i}</td>
|
|
668
|
-
<td>${
|
|
669
|
-
<td>${
|
|
670
|
-
<td>${
|
|
687
|
+
<td>${_(t.rec.results) || "·"}</td>
|
|
688
|
+
<td>${W(e, t.team.id)}</td>
|
|
689
|
+
<td>${J(e, m, t.team.id)}</td>
|
|
671
690
|
</tr>
|
|
672
691
|
`;
|
|
673
692
|
}
|
|
674
693
|
}
|
|
675
|
-
globalThis?.customElements && !globalThis.customElements.get("hsot-standings") && globalThis.customElements.define("hsot-standings",
|
|
676
|
-
const
|
|
694
|
+
globalThis?.customElements && !globalThis.customElements.get("hsot-standings") && globalThis.customElements.define("hsot-standings", ge);
|
|
695
|
+
const ve = $`
|
|
677
696
|
.hero1 {
|
|
678
697
|
border-radius: var(--hsot-radius-md); color: var(--hsot-white);
|
|
679
698
|
padding: 1.3rem 1.4rem; display: flex; align-items: center; gap: 1.2rem;
|
|
@@ -690,8 +709,8 @@ const ue = b`
|
|
|
690
709
|
.delta.new { background: var(--hsot-straw); color: #6b5900; border-radius: var(--hsot-radius-xs); padding: 0.1rem 0.3rem; font-size: 0.7rem; }
|
|
691
710
|
.sparkline { vertical-align: middle; }
|
|
692
711
|
`;
|
|
693
|
-
class
|
|
694
|
-
static styles = [...S,
|
|
712
|
+
class be extends y {
|
|
713
|
+
static styles = [...S, ve];
|
|
695
714
|
static properties = {
|
|
696
715
|
...y.properties,
|
|
697
716
|
sport: { type: String },
|
|
@@ -708,18 +727,18 @@ class ge extends y {
|
|
|
708
727
|
e && (this.pollDate = e);
|
|
709
728
|
}
|
|
710
729
|
async fetchData(e) {
|
|
711
|
-
const t = this.season || A(), [s,
|
|
730
|
+
const t = this.season || A(), [s, r, o, n, i] = await Promise.all([
|
|
712
731
|
e.listRankings({ sport: this.sport, ...this.gender ? { gender: this.gender } : {} }),
|
|
713
732
|
e.listSchools(),
|
|
714
733
|
e.listTeams({ sport: this.sport }),
|
|
715
734
|
e.listConferences(),
|
|
716
735
|
e.listGames({ sport: this.sport, season: t })
|
|
717
|
-
]), m = s.items.filter((
|
|
736
|
+
]), m = s.items.filter((d) => !this.gender || !d.gender || d.gender === this.gender).sort((d, c) => c.effectiveDate.localeCompare(d.effectiveDate));
|
|
718
737
|
return {
|
|
719
738
|
season: t,
|
|
720
739
|
polls: m,
|
|
721
|
-
schools:
|
|
722
|
-
teams:
|
|
740
|
+
schools: r.items,
|
|
741
|
+
teams: o.items,
|
|
723
742
|
conferences: n.items,
|
|
724
743
|
games: i.items
|
|
725
744
|
};
|
|
@@ -728,53 +747,53 @@ class ge extends y {
|
|
|
728
747
|
return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
|
|
729
748
|
teamsById: g(this.data.teams),
|
|
730
749
|
schoolsById: g(this.data.schools),
|
|
731
|
-
records:
|
|
750
|
+
records: D(this.data.games),
|
|
732
751
|
rankings: this.data.polls,
|
|
733
|
-
hrefs:
|
|
752
|
+
hrefs: C(this),
|
|
734
753
|
sport: this.sport
|
|
735
754
|
}, this._ctxData = this.data), this._ctx;
|
|
736
755
|
}
|
|
737
756
|
sparkline(e, t, s) {
|
|
738
|
-
const i = t.map((
|
|
739
|
-
const u = (
|
|
757
|
+
const i = t.map((h, f) => {
|
|
758
|
+
const u = (h.teamIds || []).indexOf(e);
|
|
740
759
|
if (u === -1) return null;
|
|
741
|
-
const
|
|
742
|
-
return { x
|
|
760
|
+
const x = t.length === 1 ? 96 / 2 : f / (t.length - 1) * 90 + 3, L = 3 + u / 24 * 20;
|
|
761
|
+
return { x, y: L };
|
|
743
762
|
}), m = [];
|
|
744
|
-
let
|
|
745
|
-
if (i.forEach((
|
|
746
|
-
|
|
747
|
-
}),
|
|
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;
|
|
748
767
|
const c = i[s];
|
|
749
768
|
return l`<svg class="sparkline" width=${96} height=${26} viewBox="0 0 ${96} ${26}" role="img" aria-label="rank history">
|
|
750
|
-
${m.map((
|
|
751
|
-
points=${
|
|
752
|
-
${c ?
|
|
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}
|
|
753
772
|
</svg>`;
|
|
754
773
|
}
|
|
755
774
|
movement(e, t, s) {
|
|
756
|
-
const
|
|
757
|
-
return
|
|
775
|
+
const r = pe(e, t, s);
|
|
776
|
+
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>`;
|
|
758
777
|
}
|
|
759
778
|
renderView() {
|
|
760
779
|
const e = this.ctx, t = this.data.polls;
|
|
761
780
|
if (!t.length) return l`<div class="view"><p class="empty">No ${this.sport} polls published yet this season.</p></div>`;
|
|
762
|
-
const s = Math.max(0, t.findIndex((
|
|
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;
|
|
763
782
|
return l`
|
|
764
783
|
<div class="band">
|
|
765
784
|
<div class="inner">
|
|
766
|
-
<h1>${
|
|
785
|
+
<h1>${R(this.sport)} Top 25</h1>
|
|
767
786
|
<p class="sub">The HighSchoolOT poll · updated weekly · ${t.length} polls this season</p>
|
|
768
787
|
</div>
|
|
769
788
|
</div>
|
|
770
789
|
<div class="view">
|
|
771
790
|
<div class="toolbar">
|
|
772
791
|
<label class="asof" for="pollsel">Poll of</label>
|
|
773
|
-
<select id="pollsel" @change=${(
|
|
774
|
-
this.pollDate =
|
|
792
|
+
<select id="pollsel" @change=${(h) => {
|
|
793
|
+
this.pollDate = h.target.value;
|
|
775
794
|
}}>
|
|
776
|
-
${t.map((
|
|
777
|
-
${
|
|
795
|
+
${t.map((h, f) => l`<option value=${h.effectiveDate} ?selected=${h === r}>
|
|
796
|
+
${b(h.effectiveDate, { month: "long", day: "numeric", year: "numeric" })}${f === 0 ? " · current" : ""}
|
|
778
797
|
</option>`)}
|
|
779
798
|
</select>
|
|
780
799
|
<button class="chip" ?disabled=${s >= t.length - 1}
|
|
@@ -788,65 +807,65 @@ class ge extends y {
|
|
|
788
807
|
<span class="spacer"></span>
|
|
789
808
|
<span class="asof">Movement vs. the previous poll · sparkline = season rank history</span>
|
|
790
809
|
</div>
|
|
791
|
-
${c ? this.renderHero(e,
|
|
810
|
+
${c ? this.renderHero(e, r, o, d, c, m) : p}
|
|
792
811
|
<div class="card"><div class="tablewrap"><table class="data">
|
|
793
812
|
<thead><tr>
|
|
794
813
|
<th class="num">Rk</th><th>Mvmt</th><th>Team</th><th class="num">Record</th>
|
|
795
814
|
<th>Conference</th><th>Last result</th><th>Next</th><th>Season</th>
|
|
796
815
|
</tr></thead>
|
|
797
816
|
<tbody>
|
|
798
|
-
${(
|
|
817
|
+
${(r.teamIds || []).map((h, f) => f === 0 || !h ? p : this.renderRow(e, r, o, n, i, m, h, f + 1))}
|
|
799
818
|
</tbody>
|
|
800
819
|
</table></div></div>
|
|
801
820
|
<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>
|
|
802
821
|
</div>
|
|
803
822
|
`;
|
|
804
823
|
}
|
|
805
|
-
renderHero(e, t, s,
|
|
806
|
-
const i = e.records[
|
|
824
|
+
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%)`;
|
|
807
826
|
return l`
|
|
808
827
|
<div class="hero1" style="background:${c}">
|
|
809
828
|
<div class="bigrank">#1</div>
|
|
810
|
-
${I(
|
|
829
|
+
${I(o, 64)}
|
|
811
830
|
<div>
|
|
812
|
-
<h2><a href=${v(e.hrefs.school, { id:
|
|
831
|
+
<h2><a href=${v(e.hrefs.school, { id: o.id })}>${o.name} ${o.mascot || ""}</a></h2>
|
|
813
832
|
<div class="facts">
|
|
814
|
-
${w(i)} overall${
|
|
815
|
-
· streak ${
|
|
816
|
-
${m ? l` · last: ${m.mark} ${m.my}-${m.their} vs ${
|
|
817
|
-
${this.movement(t, s,
|
|
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}
|
|
836
|
+
${this.movement(t, s, r)}
|
|
818
837
|
</div>
|
|
819
838
|
</div>
|
|
820
839
|
</div>
|
|
821
840
|
`;
|
|
822
841
|
}
|
|
823
|
-
renderRow(e, t, s,
|
|
824
|
-
const
|
|
825
|
-
if (!
|
|
826
|
-
const c = e.records[i],
|
|
827
|
-
location.href = v(e.hrefs.school, { id:
|
|
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 = M(this.data.games, i), u = n[e.teamsById[i]?.conferenceId], x = () => {
|
|
846
|
+
location.href = v(e.hrefs.school, { id: d.id });
|
|
828
847
|
};
|
|
829
848
|
return l`
|
|
830
|
-
<tr class="rowlink" @click=${(
|
|
831
|
-
|
|
849
|
+
<tr class="rowlink" @click=${(L) => {
|
|
850
|
+
L.target.closest("a") || x();
|
|
832
851
|
}}>
|
|
833
852
|
<td class="num" style="font-weight:700">${m}</td>
|
|
834
853
|
<td>${this.movement(t, s, i)}</td>
|
|
835
|
-
<td class="teamcell">${I(
|
|
836
|
-
<span class="mut" style="font-size:0.78rem">${
|
|
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>
|
|
837
856
|
<td class="num">${w(c)}</td>
|
|
838
857
|
<td class="mut">${u?.name || "Independent"}</td>
|
|
839
|
-
<td>${
|
|
840
|
-
<b style="color:${
|
|
841
|
-
${
|
|
842
|
-
<td>${
|
|
843
|
-
<td>${this.sparkline(i,
|
|
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>${J(e, f, i)}</td>
|
|
862
|
+
<td>${this.sparkline(i, r, o)}</td>
|
|
844
863
|
</tr>
|
|
845
864
|
`;
|
|
846
865
|
}
|
|
847
866
|
}
|
|
848
|
-
globalThis?.customElements && !globalThis.customElements.get("hsot-rankings") && globalThis.customElements.define("hsot-rankings",
|
|
849
|
-
const
|
|
867
|
+
globalThis?.customElements && !globalThis.customElements.get("hsot-rankings") && globalThis.customElements.define("hsot-rankings", be);
|
|
868
|
+
const ye = $`
|
|
850
869
|
.schoolhero { color: var(--hsot-white); padding: 1.6rem 1.25rem 1.3rem; }
|
|
851
870
|
.schoolhero .inner { max-width: 1366px; margin: 0 auto; display: flex; gap: 1.2rem; align-items: center; flex-wrap: wrap; }
|
|
852
871
|
.schoolhero .crest {
|
|
@@ -855,6 +874,10 @@ const ve = b`
|
|
|
855
874
|
font-family: var(--hsot-heading-font); font-weight: 700; font-size: 1.5rem;
|
|
856
875
|
border: 3px solid rgba(255,255,255,0.6);
|
|
857
876
|
}
|
|
877
|
+
.schoolhero .crest.logo {
|
|
878
|
+
object-fit: contain; background: var(--hsot-white);
|
|
879
|
+
padding: 6px; box-sizing: border-box;
|
|
880
|
+
}
|
|
858
881
|
.schoolhero h1 { margin: 0; font-family: var(--hsot-heading-font); font-size: 2.6rem; font-weight: 700; line-height: 1.05; letter-spacing: -0.02em; }
|
|
859
882
|
.schoolhero .mascot { font-size: 1.05rem; opacity: 0.85; font-family: var(--hsot-heading-font); text-transform: uppercase; letter-spacing: 0.06em; }
|
|
860
883
|
.schoolhero .facts { display: flex; flex-wrap: wrap; gap: 0.3rem 1.4rem; margin-top: 0.55rem; font-size: 0.85rem; opacity: 0.95; }
|
|
@@ -868,7 +891,7 @@ const ve = b`
|
|
|
868
891
|
@media (max-width: 900px) { .cols { grid-template-columns: 1fr; } .schoolhero h1 { font-size: 1.9rem; } }
|
|
869
892
|
`;
|
|
870
893
|
class $e extends y {
|
|
871
|
-
static styles = [...S,
|
|
894
|
+
static styles = [...S, ye];
|
|
872
895
|
static properties = {
|
|
873
896
|
...y.properties,
|
|
874
897
|
schoolId: { type: String, attribute: "school-id" },
|
|
@@ -885,7 +908,7 @@ class $e extends y {
|
|
|
885
908
|
e && !this.sport && (this.sport = e);
|
|
886
909
|
}
|
|
887
910
|
async fetchData(e) {
|
|
888
|
-
const t = this.season || A(), s = await e.getSchool(this.schoolId),
|
|
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([
|
|
889
912
|
n ? e.listGames({ sport: n.sport, season: t }) : Promise.resolve({ items: [] }),
|
|
890
913
|
n ? e.listTeams({ sport: n.sport }) : Promise.resolve({ items: [] }),
|
|
891
914
|
e.listSchools(),
|
|
@@ -899,14 +922,14 @@ class $e extends y {
|
|
|
899
922
|
return {
|
|
900
923
|
season: t,
|
|
901
924
|
school: s,
|
|
902
|
-
teams:
|
|
925
|
+
teams: o,
|
|
903
926
|
active: n,
|
|
904
927
|
games: i.items,
|
|
905
928
|
allTeams: m.items,
|
|
906
|
-
schools:
|
|
929
|
+
schools: d.items,
|
|
907
930
|
conferences: c.items,
|
|
908
|
-
rankings:
|
|
909
|
-
roster: f.items.find((
|
|
931
|
+
rankings: h.items,
|
|
932
|
+
roster: f.items.find((x) => x.season === t) || null,
|
|
910
933
|
players: u.items
|
|
911
934
|
};
|
|
912
935
|
}
|
|
@@ -914,9 +937,9 @@ class $e extends y {
|
|
|
914
937
|
return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
|
|
915
938
|
teamsById: g(this.data.allTeams.length ? this.data.allTeams : this.data.teams),
|
|
916
939
|
schoolsById: g(this.data.schools),
|
|
917
|
-
records:
|
|
940
|
+
records: D(this.data.games),
|
|
918
941
|
rankings: this.data.rankings,
|
|
919
|
-
hrefs:
|
|
942
|
+
hrefs: C(this),
|
|
920
943
|
sport: this.data.active?.sport || "football"
|
|
921
944
|
}, this._ctxData = this.data), this._ctx;
|
|
922
945
|
}
|
|
@@ -924,19 +947,19 @@ class $e extends y {
|
|
|
924
947
|
this.sport = e, this.load();
|
|
925
948
|
}
|
|
926
949
|
renderView() {
|
|
927
|
-
const { school: e, teams: t, active: s, season:
|
|
950
|
+
const { school: e, teams: t, active: s, season: r } = this.data;
|
|
928
951
|
if (!e) return l`<div class="view"><p class="empty">School not found.</p></div>`;
|
|
929
|
-
const
|
|
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;
|
|
930
953
|
return l`
|
|
931
954
|
<div class="schoolhero" style="background:linear-gradient(115deg, ${e.colorPrimary || "#030711"} 0%, ${e.colorPrimary || "#030711"} 55%, var(--hsot-black) 100%);color:${n}">
|
|
932
955
|
<div class="inner">
|
|
933
|
-
|
|
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")}">${j(e)}</div>`}
|
|
934
957
|
<div style="min-width:260px">
|
|
935
958
|
<h1>${e.name} <span class="mascot">${e.mascot || ""}</span></h1>
|
|
936
959
|
<div class="facts">
|
|
937
960
|
${e.location ? l`<span><b>Location</b>${e.location}${e.county ? l` · ${e.county} County` : p}</span>` : p}
|
|
938
961
|
${e.association ? l`<span><b>League</b>${e.association}${e.classification ? l` · ${e.classification}` : p}</span>` : p}
|
|
939
|
-
${
|
|
962
|
+
${d ? l`<span><b>Conference</b>${d.name}</span>` : p}
|
|
940
963
|
${i ? l`<span><b>Enrollment</b>${i.value.toLocaleString()} (${i.season} ADM)</span>` : p}
|
|
941
964
|
${e.openingYear ? l`<span><b>Opened</b>${e.openingYear}</span>` : p}
|
|
942
965
|
${e.areaCode ? l`<span><b>Area</b>${e.areaCode}</span>` : p}
|
|
@@ -947,63 +970,63 @@ class $e extends y {
|
|
|
947
970
|
</div>
|
|
948
971
|
<div class="band">
|
|
949
972
|
<nav class="tabs" aria-label="Teams">
|
|
950
|
-
${t.map((c) => c.id === s?.id ? l`<a class="on" href="#" @click=${(
|
|
951
|
-
|
|
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);
|
|
952
975
|
}}>${c.name}</a>`)}
|
|
953
976
|
</nav>
|
|
954
977
|
</div>
|
|
955
978
|
<div class="view">
|
|
956
|
-
${s ? this.renderTeam(
|
|
979
|
+
${s ? this.renderTeam(o, s, d, r) : l`<p class="empty">No teams recorded for this school yet.</p>`}
|
|
957
980
|
</div>
|
|
958
981
|
`;
|
|
959
982
|
}
|
|
960
|
-
renderTeam(e, t, s,
|
|
961
|
-
const
|
|
983
|
+
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)));
|
|
962
985
|
return l`
|
|
963
986
|
<div class="tiles">
|
|
964
|
-
<div class="tile"><div class="k">Overall</div><div class="v">${w(
|
|
965
|
-
<div class="tile"><div class="k">${s?.name || "Conference"}</div><div class="v">${w(
|
|
966
|
-
<div class="s">${m ? `${
|
|
967
|
-
<div class="tile"><div class="k">Points</div><div class="v">${n ? (
|
|
968
|
-
<div class="s">scored per game · ${n ? (
|
|
969
|
-
<div class="tile"><div class="k">Streak</div><div class="v">${
|
|
970
|
-
<div class="s">last 5: ${
|
|
971
|
-
<div class="tile"><div class="k">HSOT Top 25</div><div class="v">${
|
|
987
|
+
<div class="tile"><div class="k">Overall</div><div class="v">${w(o)}</div><div class="s">${n} games played</div></div>
|
|
988
|
+
<div class="tile"><div class="k">${s?.name || "Conference"}</div><div class="v">${w(o, !0)}</div>
|
|
989
|
+
<div class="s">${m ? `${he(m)} of ${i.length}` : "·"}</div></div>
|
|
990
|
+
<div class="tile"><div class="k">Points</div><div class="v">${n ? (o.pf / n).toFixed(1) : "0.0"}</div>
|
|
991
|
+
<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>
|
|
972
995
|
<div class="s"><a href=${v(e.hrefs.section, { sport: t.sport, view: "rankings" })}>full poll</a></div></div>
|
|
973
996
|
</div>
|
|
974
997
|
${(t.championships || []).length ? l`
|
|
975
998
|
<div style="margin:-0.2rem 0 1rem;display:flex;gap:0.4rem;flex-wrap:wrap">
|
|
976
|
-
${t.championships.map((
|
|
999
|
+
${t.championships.map((h) => l`<span class="pill champ">★ ${h.season} ${h.title} champion${h.classification ? ` · ${h.classification}` : ""}${h.region ? ` · ${h.region}` : ""}</span>`)}
|
|
977
1000
|
</div>` : p}
|
|
978
1001
|
<div class="cols">
|
|
979
1002
|
<div>
|
|
980
1003
|
<div class="section-title">Schedule & results</div>
|
|
981
1004
|
<div class="card">
|
|
982
|
-
${c.length ? l`<ul class="gamelist">${c.map((
|
|
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>`}
|
|
983
1006
|
</div>
|
|
984
1007
|
</div>
|
|
985
1008
|
<div>
|
|
986
|
-
<div class="section-title">Roster · ${
|
|
987
|
-
<div class="card">${this.renderRoster(
|
|
1009
|
+
<div class="section-title">Roster · ${r}</div>
|
|
1010
|
+
<div class="card">${this.renderRoster(r)}</div>
|
|
988
1011
|
</div>
|
|
989
1012
|
</div>
|
|
990
1013
|
`;
|
|
991
1014
|
}
|
|
992
1015
|
renderGameRow(e, t, s) {
|
|
993
|
-
const
|
|
994
|
-
let m = l`<span class="mut">${
|
|
1016
|
+
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>`;
|
|
995
1018
|
if (s.state === "final") {
|
|
996
|
-
const c =
|
|
997
|
-
m = l`<span class=${
|
|
1019
|
+
const c = H(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}`;
|
|
998
1021
|
} else s.state === "live" && (m = l`<span style="color:var(--hsot-red)">${n}-${i}</span>`);
|
|
999
|
-
const
|
|
1022
|
+
const d = s.gameType === "conference" ? "Conf" : s.gameType === "nonconference" ? "Non-conf" : s.gameType === "playoff" ? `Playoff${s.label ? ` · ${s.label}` : ""}` : "Scrimmage";
|
|
1000
1023
|
return l`
|
|
1001
1024
|
<li>
|
|
1002
|
-
<span class="d">${
|
|
1003
|
-
${
|
|
1025
|
+
<span class="d">${b(s.date)}</span>
|
|
1026
|
+
${B(s)}
|
|
1004
1027
|
<span class="res">${m}</span>
|
|
1005
|
-
<span class="opp">${
|
|
1006
|
-
<span class="pill type">${
|
|
1028
|
+
<span class="opp">${r ? "vs" : "at"} ${U(e, o, s.date)}
|
|
1029
|
+
<span class="pill type">${d}</span>
|
|
1007
1030
|
${s.broadcast ? l`<span class="pill class">${s.broadcast}</span>` : p}
|
|
1008
1031
|
</span>
|
|
1009
1032
|
<span class="where">${s.venue || ""}</span>
|
|
@@ -1015,19 +1038,19 @@ class $e extends y {
|
|
|
1015
1038
|
const t = this.data.roster;
|
|
1016
1039
|
if (!t)
|
|
1017
1040
|
return l`<p class="empty">Roster not published for ${e}.</p>`;
|
|
1018
|
-
const s = g(this.data.players),
|
|
1041
|
+
const s = g(this.data.players), r = t.entries.slice().sort((o, n) => (o.number || 0) - (n.number || 0));
|
|
1019
1042
|
return l`
|
|
1020
1043
|
<div class="tablewrap"><table class="data">
|
|
1021
1044
|
<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>
|
|
1022
1045
|
<tbody>
|
|
1023
|
-
${
|
|
1024
|
-
const n = s[
|
|
1046
|
+
${r.map((o) => {
|
|
1047
|
+
const n = s[o.playerId];
|
|
1025
1048
|
return n ? l`<tr>
|
|
1026
|
-
<td class="num mut">${
|
|
1049
|
+
<td class="num mut">${o.number ?? "·"}</td>
|
|
1027
1050
|
<td style="font-weight:500">${n.firstName} ${n.lastName}</td>
|
|
1028
|
-
<td>${
|
|
1051
|
+
<td>${o.position || "·"}</td>
|
|
1029
1052
|
<td class="mut">${n.classOf || "·"}</td>
|
|
1030
|
-
<td class="num">${
|
|
1053
|
+
<td class="num">${de(n.heightIn)}</td>
|
|
1031
1054
|
<td class="num">${n.weightLb || "·"}</td>
|
|
1032
1055
|
</tr>` : p;
|
|
1033
1056
|
})}
|
|
@@ -1037,7 +1060,21 @@ class $e extends y {
|
|
|
1037
1060
|
}
|
|
1038
1061
|
}
|
|
1039
1062
|
globalThis?.customElements && !globalThis.customElements.get("hsot-school") && globalThis.customElements.define("hsot-school", $e);
|
|
1040
|
-
const
|
|
1063
|
+
const we = "https://api.wral.com/search";
|
|
1064
|
+
function xe(a) {
|
|
1065
|
+
return a.map((e) => `uri:"${e}"`).join(" OR ");
|
|
1066
|
+
}
|
|
1067
|
+
function ke(a, e) {
|
|
1068
|
+
const t = String(a || we).replace(/\/+$/, ""), s = new URLSearchParams({ query: xe(e), sort: "score", lang: "en" });
|
|
1069
|
+
return `${t}/v1/query?${s}`;
|
|
1070
|
+
}
|
|
1071
|
+
async function Te(a, e, t) {
|
|
1072
|
+
const r = await ((...i) => fetch(...i))(ke(a, e));
|
|
1073
|
+
if (!r.ok) throw new Error(`search answered ${r.status}`);
|
|
1074
|
+
const o = await r.json(), n = new Map((o.items || []).map((i) => [i.uri, i]));
|
|
1075
|
+
return e.map((i) => n.get(i) || { uri: i, title: i });
|
|
1076
|
+
}
|
|
1077
|
+
const Ie = $`
|
|
1041
1078
|
.breadcrumbs { font-size: 0.8125rem; margin: 0.9rem 0 0; color: var(--hsot-gray-5); }
|
|
1042
1079
|
.breadcrumbs a { text-decoration: none; }
|
|
1043
1080
|
.scorehead { display: grid; grid-template-columns: 1fr auto 1fr; gap: 1rem; align-items: center; padding: 1.4rem 1rem; }
|
|
@@ -1048,12 +1085,24 @@ const ye = b`
|
|
|
1048
1085
|
display: flex; align-items: center; justify-content: center;
|
|
1049
1086
|
font-family: var(--hsot-heading-font); font-weight: 700; color: var(--hsot-white);
|
|
1050
1087
|
}
|
|
1088
|
+
.scorehead .crest.logo {
|
|
1089
|
+
object-fit: contain; background: var(--hsot-white);
|
|
1090
|
+
border: 1px solid var(--hsot-gray-2); padding: 4px; box-sizing: border-box;
|
|
1091
|
+
}
|
|
1051
1092
|
.scorehead .tname { font-family: var(--hsot-heading-font); font-weight: 700; font-size: 1.15rem; line-height: 1.15; }
|
|
1052
1093
|
.scorehead .tname a { color: inherit; text-decoration: none; }
|
|
1053
1094
|
.scorehead .trec { font-size: 0.8rem; color: var(--hsot-gray-5); }
|
|
1054
1095
|
.scorehead .mid { text-align: center; }
|
|
1055
1096
|
.scorehead .bigscore { font-family: var(--hsot-heading-font); font-weight: 700; font-size: 3rem; line-height: 1; color: var(--hsot-black); white-space: nowrap; }
|
|
1056
1097
|
.scorehead .status { margin-top: 0.3rem; font-size: 0.8rem; color: var(--hsot-gray-5); }
|
|
1098
|
+
.covgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1rem; margin-bottom: 1.25rem; }
|
|
1099
|
+
.covcard { display: flex; flex-direction: column; text-decoration: none; color: inherit; margin-bottom: 0; }
|
|
1100
|
+
.covcard:hover .covtitle { color: var(--hsot-red-deep); }
|
|
1101
|
+
.covimg { width: 100%; aspect-ratio: 1.91; object-fit: cover; display: block; background: var(--hsot-gray-1); }
|
|
1102
|
+
.covbody { padding: 0.75rem 0.9rem 0.85rem; }
|
|
1103
|
+
.covtitle { font-family: var(--hsot-heading-font); font-weight: 700; font-size: 1.05rem; line-height: 1.25; overflow-wrap: anywhere; }
|
|
1104
|
+
.covdesc { margin: 0.35rem 0 0; font-size: 0.85rem; color: var(--hsot-gray-5); line-height: 1.4; }
|
|
1105
|
+
.covmeta { margin-top: 0.45rem; font-size: 0.78rem; color: var(--hsot-gray-5); }
|
|
1057
1106
|
.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
|
|
1058
1107
|
.ctxcard { padding: 0.85rem 1rem; }
|
|
1059
1108
|
.ctxcard .who { font-family: var(--hsot-heading-font); font-weight: 700; margin-bottom: 0.4rem; }
|
|
@@ -1064,64 +1113,73 @@ const ye = b`
|
|
|
1064
1113
|
.cols { grid-template-columns: 1fr; }
|
|
1065
1114
|
}
|
|
1066
1115
|
`;
|
|
1067
|
-
class
|
|
1068
|
-
static styles = [...S,
|
|
1116
|
+
class Se extends y {
|
|
1117
|
+
static styles = [...S, Ie];
|
|
1069
1118
|
static properties = {
|
|
1070
1119
|
...y.properties,
|
|
1071
|
-
gameId: { type: String, attribute: "game-id" }
|
|
1120
|
+
gameId: { type: String, attribute: "game-id" },
|
|
1121
|
+
// The public site search that resolves Game.coverageUrls into cards
|
|
1122
|
+
// (DEV-1236). Shared cross-stage by design — see the studio host's
|
|
1123
|
+
// registry — so the prod default is right everywhere; the attribute
|
|
1124
|
+
// exists for the same reason the href templates do.
|
|
1125
|
+
searchApi: { type: String, attribute: "search-api" }
|
|
1072
1126
|
};
|
|
1073
1127
|
constructor() {
|
|
1074
|
-
super(), this.gameId = "";
|
|
1128
|
+
super(), this.gameId = "", this.searchApi = "";
|
|
1075
1129
|
}
|
|
1076
1130
|
async fetchData(e) {
|
|
1077
|
-
const t = await e.getGame(this.gameId),
|
|
1131
|
+
const t = await e.getGame(this.gameId), s = Array.isArray(t.coverageUrls) ? t.coverageUrls : [], [r, o, n, i, m, d] = await Promise.all([
|
|
1078
1132
|
e.listSchools(),
|
|
1079
1133
|
e.listTeams({ sport: t.sport }),
|
|
1080
1134
|
e.listConferences(),
|
|
1081
1135
|
e.listRankings({ sport: t.sport }),
|
|
1082
|
-
e.listGames({ sport: t.sport, season: t.season })
|
|
1136
|
+
e.listGames({ sport: t.sport, season: t.season }),
|
|
1137
|
+
// A search outage must not blank the box score — degrade to bare
|
|
1138
|
+
// links (fetchCoverage already degrades per-URL index misses).
|
|
1139
|
+
s.length ? Te(this.searchApi, s).catch(() => s.map((c) => ({ uri: c, title: c }))) : Promise.resolve([])
|
|
1083
1140
|
]);
|
|
1084
1141
|
return {
|
|
1085
1142
|
game: t,
|
|
1086
|
-
schools:
|
|
1143
|
+
schools: r.items,
|
|
1087
1144
|
teams: o.items,
|
|
1088
|
-
conferences:
|
|
1089
|
-
rankings:
|
|
1090
|
-
games:
|
|
1145
|
+
conferences: n.items,
|
|
1146
|
+
rankings: i.items,
|
|
1147
|
+
games: m.items,
|
|
1148
|
+
coverage: d
|
|
1091
1149
|
};
|
|
1092
1150
|
}
|
|
1093
1151
|
get ctx() {
|
|
1094
1152
|
return (!this._ctx || this._ctxData !== this.data) && (this._ctx = {
|
|
1095
1153
|
teamsById: g(this.data.teams),
|
|
1096
1154
|
schoolsById: g(this.data.schools),
|
|
1097
|
-
records:
|
|
1155
|
+
records: D(this.data.games),
|
|
1098
1156
|
rankings: this.data.rankings,
|
|
1099
|
-
hrefs:
|
|
1157
|
+
hrefs: C(this),
|
|
1100
1158
|
sport: this.data.game.sport
|
|
1101
1159
|
}, this._ctxData = this.data), this._ctx;
|
|
1102
1160
|
}
|
|
1103
1161
|
renderView() {
|
|
1104
1162
|
const e = this.data.game;
|
|
1105
1163
|
if (!e) return l`<div class="view"><p class="empty">Game not found.</p></div>`;
|
|
1106
|
-
const t = this.ctx, s = g(this.data.conferences),
|
|
1164
|
+
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 = H(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));
|
|
1107
1165
|
return l`
|
|
1108
1166
|
<div class="view">
|
|
1109
1167
|
<p class="breadcrumbs">
|
|
1110
|
-
<a href=${v(t.hrefs.section, { sport: e.sport, view: "scores" })}>${
|
|
1168
|
+
<a href=${v(t.hrefs.section, { sport: e.sport, view: "scores" })}>${R(e.sport)}</a> /
|
|
1111
1169
|
<a href=${v(t.hrefs.section, { sport: e.sport, view: "scores" })}>Scores/Schedules</a> /
|
|
1112
|
-
${
|
|
1170
|
+
${k(t, e.awayTeamId)} at ${k(t, e.homeTeamId)}
|
|
1113
1171
|
</p>
|
|
1114
1172
|
<div class="card">
|
|
1115
1173
|
<div class="scorehead">
|
|
1116
|
-
${this.teamBlock(t, e, e.awayTeamId,
|
|
1174
|
+
${this.teamBlock(t, e, e.awayTeamId, r, !1)}
|
|
1117
1175
|
<div class="mid">
|
|
1118
1176
|
<div class="bigscore">
|
|
1119
1177
|
<span style=${i("away")}>${e.awayScore}</span>
|
|
1120
1178
|
<span class="mut" style="font-size:1.6rem">–</span>
|
|
1121
1179
|
<span style=${i("home")}>${e.homeScore}</span>
|
|
1122
1180
|
</div>
|
|
1123
|
-
<div class="status">${
|
|
1124
|
-
<div class="status">${
|
|
1181
|
+
<div class="status">${B(e)}</div>
|
|
1182
|
+
<div class="status">${b(e.date, { weekday: "short", month: "short", day: "numeric", year: "numeric" })}${e.state === "scheduled" && e.time ? l` · ${E(e.time)}` : p} · ${e.venue || "Venue TBD"}
|
|
1125
1183
|
${e.broadcast ? l` · <span class="pill class">${e.broadcast}</span>` : p}</div>
|
|
1126
1184
|
<div class="status">
|
|
1127
1185
|
<span class="pill type">${e.gameType === "conference" ? `${m?.name || "Conference"} game` : e.gameType}</span>
|
|
@@ -1129,64 +1187,73 @@ class be extends y {
|
|
|
1129
1187
|
${(e.tags || []).map((c) => l`<span class="pill type">${c}</span>`)}
|
|
1130
1188
|
</div>
|
|
1131
1189
|
</div>
|
|
1132
|
-
${this.teamBlock(t, e, e.homeTeamId,
|
|
1190
|
+
${this.teamBlock(t, e, e.homeTeamId, o, !0)}
|
|
1133
1191
|
</div>
|
|
1134
|
-
${this.renderLineScore(e,
|
|
1192
|
+
${this.renderLineScore(e, r, o)}
|
|
1135
1193
|
${e.notes ? l`<p class="note" style="padding:0 1rem 0.9rem;text-align:center">${e.notes}</p>` : p}
|
|
1136
1194
|
</div>
|
|
1137
|
-
${
|
|
1195
|
+
${(this.data.coverage || []).length ? l`
|
|
1138
1196
|
<div class="section-title">Coverage</div>
|
|
1139
|
-
<div class="
|
|
1140
|
-
${
|
|
1141
|
-
|
|
1142
|
-
|
|
1197
|
+
<div class="covgrid">
|
|
1198
|
+
${this.data.coverage.map((c) => l`
|
|
1199
|
+
<a class="card covcard" href=${c.uri}>
|
|
1200
|
+
${c.image ? l`<img class="covimg" src=${c.image} alt="" loading="lazy" />` : p}
|
|
1201
|
+
<div class="covbody">
|
|
1202
|
+
<div class="covtitle">${c.videoDuration ? l`<span class="pill live" style="animation:none">Video</span> ` : p}${c.title || c.uri}</div>
|
|
1203
|
+
${c.description ? l`<p class="covdesc">${c.description}</p>` : p}
|
|
1204
|
+
${c.author || c.publishedTime ? l`
|
|
1205
|
+
<div class="covmeta">${[c.author, c.publishedTime ? new Date(c.publishedTime).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }) : ""].filter(Boolean).join(" · ")}</div>
|
|
1206
|
+
` : p}
|
|
1207
|
+
</div>
|
|
1208
|
+
</a>
|
|
1209
|
+
`)}
|
|
1143
1210
|
</div>` : p}
|
|
1144
1211
|
<div class="section-title">Season context</div>
|
|
1145
1212
|
<div class="cols">
|
|
1146
|
-
${[[e.awayTeamId,
|
|
1213
|
+
${[[e.awayTeamId, r], [e.homeTeamId, o]].map(([c, h]) => this.renderContext(t, c, h))}
|
|
1147
1214
|
</div>
|
|
1148
|
-
${
|
|
1215
|
+
${d.length ? l`
|
|
1149
1216
|
<div class="section-title">Head to head this season</div>
|
|
1150
1217
|
<div class="card"><ul class="gamelist">
|
|
1151
|
-
${
|
|
1152
|
-
<span class="d">${
|
|
1153
|
-
<span class="opp">${
|
|
1218
|
+
${d.map((c) => l`<li>
|
|
1219
|
+
<span class="d">${b(c.date)}</span>${B(c)}
|
|
1220
|
+
<span class="opp">${k(t, c.awayTeamId)} ${c.awayScore}, ${k(t, c.homeTeamId)} ${c.homeScore}</span>
|
|
1154
1221
|
<a class="box" href=${v(t.hrefs.game, { sport: e.sport, id: c.id })}>Box score →</a>
|
|
1155
1222
|
</li>`)}
|
|
1156
1223
|
</ul></div>` : p}
|
|
1157
1224
|
</div>
|
|
1158
1225
|
`;
|
|
1159
1226
|
}
|
|
1160
|
-
teamBlock(e, t, s,
|
|
1161
|
-
if (!
|
|
1162
|
-
const n = e.teamsById[s], i = e.records[s];
|
|
1227
|
+
teamBlock(e, t, s, r, o) {
|
|
1228
|
+
if (!r) return l`<div class="teamblock ${o ? "right" : ""}"><div class="tname">TBD</div></div>`;
|
|
1229
|
+
const n = e.teamsById[s], i = e.records[s], m = P(r, 58);
|
|
1163
1230
|
return l`
|
|
1164
|
-
<div class="teamblock ${
|
|
1165
|
-
|
|
1231
|
+
<div class="teamblock ${o ? "right" : ""}">
|
|
1232
|
+
${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")}">${j(r)}</span>`}
|
|
1166
1233
|
<div>
|
|
1167
|
-
<div class="tname">${
|
|
1168
|
-
<div class="trec">${
|
|
1234
|
+
<div class="tname">${G(e, s, t.date)}<a href=${v(e.hrefs.school, { id: r.id })}>${r.name}</a></div>
|
|
1235
|
+
<div class="trec">${r.mascot || ""} · ${w(i)}${n?.conferenceId ? l` · ${w(i, !0)} conf` : p}</div>
|
|
1169
1236
|
</div>
|
|
1170
1237
|
</div>
|
|
1171
1238
|
`;
|
|
1172
1239
|
}
|
|
1173
1240
|
renderLineScore(e, t, s) {
|
|
1174
|
-
const
|
|
1175
|
-
if (!
|
|
1241
|
+
const r = e.periodScores || [];
|
|
1242
|
+
if (!r.length)
|
|
1176
1243
|
return l`<p class="empty" style="text-align:center">Period scoring will appear once the game starts.</p>`;
|
|
1177
|
-
const
|
|
1178
|
-
const
|
|
1179
|
-
return
|
|
1180
|
-
}, m = (
|
|
1244
|
+
const o = Math.max(4, ...r.map((d) => d.period)), n = (d) => d <= 4 ? String(d) : `OT${d > 5 ? d - 4 : ""}`, i = (d, c) => {
|
|
1245
|
+
const h = r.find((f) => f.period === c);
|
|
1246
|
+
return h ? h[d] : e.state === "final" ? 0 : "·";
|
|
1247
|
+
}, m = (d, c, h) => l`
|
|
1181
1248
|
<tr>
|
|
1182
|
-
<td class="teamcell">${I(
|
|
1183
|
-
${Array.from({ length:
|
|
1184
|
-
<td class="num" style="font-weight:700">${
|
|
1249
|
+
<td class="teamcell">${I(d, 20)}${d?.abbr || "TBD"}</td>
|
|
1250
|
+
${Array.from({ length: o }, (f, u) => l`<td class="num">${i(c, u + 1)}</td>`)}
|
|
1251
|
+
<td class="num" style="font-weight:700">${h}</td>
|
|
1185
1252
|
</tr>`;
|
|
1186
1253
|
return l`
|
|
1187
1254
|
<div class="tablewrap" style="border-top:1px solid var(--hsot-gray-2)">
|
|
1188
1255
|
<table class="data" style="max-width:560px;margin:0.6rem auto 0.9rem">
|
|
1189
|
-
<thead><tr><th>Team</th>${Array.from({ length:
|
|
1256
|
+
<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>
|
|
1190
1257
|
<tbody>
|
|
1191
1258
|
${m(t, "away", e.awayScore)}
|
|
1192
1259
|
${m(s, "home", e.homeScore)}
|
|
@@ -1197,37 +1264,37 @@ class be extends y {
|
|
|
1197
1264
|
}
|
|
1198
1265
|
renderContext(e, t, s) {
|
|
1199
1266
|
if (!s) return p;
|
|
1200
|
-
const
|
|
1267
|
+
const r = e.records[t], o = M(this.data.games, t);
|
|
1201
1268
|
return l`
|
|
1202
1269
|
<div class="card ctxcard">
|
|
1203
1270
|
<div class="who">${I(s)}${s.name}</div>
|
|
1204
1271
|
<div class="row">
|
|
1205
|
-
<span>Last 5: ${
|
|
1206
|
-
<span>Streak: <b>${
|
|
1207
|
-
<span>PF/PA: <b>${
|
|
1208
|
-
<span>Next: ${
|
|
1209
|
-
${
|
|
1272
|
+
<span>Last 5: ${W(e, t)}</span>
|
|
1273
|
+
<span>Streak: <b>${r ? _(r.results) : "·"}</b></span>
|
|
1274
|
+
<span>PF/PA: <b>${r ? `${r.pf} / ${r.pa}` : "·"}</b></span>
|
|
1275
|
+
<span>Next: ${o ? l`${b(o.date, { month: "numeric", day: "numeric" })}
|
|
1276
|
+
${o.homeTeamId === t ? "vs" : "at"} ${z(e, o.homeTeamId === t ? o.awayTeamId : o.homeTeamId)}` : "·"}</span>
|
|
1210
1277
|
</div>
|
|
1211
1278
|
</div>
|
|
1212
1279
|
`;
|
|
1213
1280
|
}
|
|
1214
1281
|
}
|
|
1215
|
-
globalThis?.customElements && !globalThis.customElements.get("hsot-boxscore") && globalThis.customElements.define("hsot-boxscore",
|
|
1282
|
+
globalThis?.customElements && !globalThis.customElements.get("hsot-boxscore") && globalThis.customElements.define("hsot-boxscore", Se);
|
|
1216
1283
|
export {
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1284
|
+
N as D,
|
|
1285
|
+
Se as H,
|
|
1286
|
+
be as a,
|
|
1220
1287
|
$e as b,
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1288
|
+
ue as c,
|
|
1289
|
+
ge as d,
|
|
1290
|
+
D as e,
|
|
1291
|
+
se as f,
|
|
1225
1292
|
v as g,
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1293
|
+
H as h,
|
|
1294
|
+
Ce as i,
|
|
1295
|
+
_ as j,
|
|
1296
|
+
pe as p,
|
|
1230
1297
|
w as r,
|
|
1231
1298
|
K as s,
|
|
1232
|
-
|
|
1299
|
+
X as t
|
|
1233
1300
|
};
|