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