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