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