@sensiblestats/widget-react 0.85.0 → 0.86.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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/StatsWidget.tsx
2
- import { useCallback as useCallback23, useEffect as useEffect34, useMemo as useMemo6, useRef as useRef31, useState as useState53 } from "react";
2
+ import { useCallback as useCallback23, useEffect as useEffect34, useMemo as useMemo6, useRef as useRef31, useState as useState55 } from "react";
3
3
  import { StatsWidgetClient } from "@sensiblestats/widget-sdk";
4
4
 
5
5
  // src/kickoff.ts
@@ -15,8 +15,13 @@ function formatBettingKickoff(kickoffUtc, ui, locale, now = /* @__PURE__ */ new
15
15
  }
16
16
 
17
17
  // src/i18n.ts
18
+ var GROUP_NOUN_EN = { G: "goalkeepers", D: "defenders", M: "midfielders", F: "forwards" };
19
+ var GROUP_NOUN_TR = { G: "kalecileri", D: "defans oyuncular\u0131", M: "orta saha oyuncular\u0131", F: "forvetleri" };
18
20
  var formatPtsEn = (n) => new Intl.NumberFormat("en-GB").format(n);
19
21
  var formatPtsTr = (n) => new Intl.NumberFormat("tr-TR").format(n);
22
+ var nbsp = (s) => s.replace(/\s/g, "\xA0");
23
+ var pdDateEn = (ms, opts) => nbsp(new Intl.DateTimeFormat("en-GB", opts).format(new Date(ms)).replace("Sept", "Sep"));
24
+ var pdDateTr = (ms, opts) => nbsp(new Intl.DateTimeFormat("tr-TR", opts).format(new Date(ms)));
20
25
  var STRINGS = {
21
26
  en: {
22
27
  launcherLabel: "Chat with SensibleStats",
@@ -152,6 +157,60 @@ var STRINGS = {
152
157
  recordsMostAssists: "Most assists",
153
158
  recordsSince: "Since {season}",
154
159
  standingsColClub: "Club",
160
+ statHeadPos: "Pos",
161
+ statHeadMins: "Mins",
162
+ statHeadGoals: "G",
163
+ statHeadAssists: "A",
164
+ statHeadYellow: "Y",
165
+ statHeadRed: "R",
166
+ statHeadRating: "Rtg",
167
+ squadStatsEyebrow: (season, competition, n) => `${season} ${competition} \xB7 after ${n} game${n === 1 ? "" : "s"}`,
168
+ squadTopScorer: (name, n) => `Top scorer: ${name} (${n})`,
169
+ squadTopAssists: (name, n) => `Most assists: ${name} (${n})`,
170
+ detailStarted: "Started",
171
+ detailMatches: "Matches",
172
+ detailNatShort: "Nat.",
173
+ detailYellows: "Yellows",
174
+ detailReds: "Reds",
175
+ availabilityNext: (opponent, isHome, kickoffMs) => `Next: ${isHome ? "vs" : "at"} ${opponent} (${isHome ? "H" : "A"})` + (kickoffMs !== null && kickoffMs > 0 ? ` \xB7 ${pdDateEn(kickoffMs, { weekday: "short", day: "numeric", month: "short" })}` : ""),
176
+ availabilityAvailable: "Available",
177
+ availabilityInjured: "Injured",
178
+ availabilitySuspended: "Suspended",
179
+ availabilityUnavailable: "Unavailable",
180
+ availabilityNoConcerns: "No fitness concerns reported",
181
+ availabilityBack: (ms) => `Expected back ${pdDateEn(ms, { day: "numeric", month: "short" })}`,
182
+ perfTitle: "Season performance",
183
+ perfTotal: "Total",
184
+ perfPer90: "Per 90",
185
+ perfRankedAgainst: (competition, group) => `Ranked against ${competition} ${GROUP_NOUN_EN[group] ?? group}`,
186
+ perfUnranked: "Not enough minutes to rank",
187
+ perfUnrankedCohort: "Not enough players in this position to rank",
188
+ perfUnrankedNoLeague: "Not ranked \u2014 no league data",
189
+ perfGroupShooting: "Shooting",
190
+ perfGroupPassing: "Passing",
191
+ perfGroupPossession: "Possession",
192
+ perfGroupDefending: "Defending",
193
+ perfMetric: {
194
+ goals: "Goals",
195
+ xg: "Expected goals (xG)",
196
+ shots: "Shots",
197
+ shotsOnTarget: "Shots on target",
198
+ assists: "Assists",
199
+ successfulPasses: "Successful passes",
200
+ passAccuracy: "Pass accuracy",
201
+ chancesCreated: "Chances created",
202
+ successfulDribbles: "Successful dribbles",
203
+ dribbleSuccess: "Dribble success",
204
+ touches: "Touches",
205
+ tacklesWon: "Tackles won",
206
+ interceptions: "Interceptions",
207
+ duelsWon: "Duels won"
208
+ },
209
+ perfGroupNoun: GROUP_NOUN_EN,
210
+ matchLogTitle: "Match log",
211
+ matchLogOpponent: (name, isHome) => isHome ? `vs ${name}` : `at ${name}`,
212
+ resultLetter: { W: "W", D: "D", L: "L" },
213
+ logShortDate: (ms) => pdDateEn(ms, { day: "numeric", month: "short" }),
155
214
  standingsColPlayed: "P",
156
215
  standingsColWon: "W",
157
216
  standingsColDrawn: "D",
@@ -565,6 +624,60 @@ var STRINGS = {
565
624
  recordsMostAssists: "En \xE7ok asist yapanlar",
566
625
  recordsSince: "{season} sezonundan beri",
567
626
  standingsColClub: "Tak\u0131m",
627
+ statHeadPos: "Mvk",
628
+ statHeadMins: "Dk",
629
+ statHeadGoals: "G",
630
+ statHeadAssists: "A",
631
+ statHeadYellow: "S",
632
+ statHeadRed: "K",
633
+ statHeadRating: "Puan",
634
+ squadStatsEyebrow: (season, competition, n) => `${season} ${competition} \xB7 ${n} ma\xE7 sonra`,
635
+ squadTopScorer: (name, n) => `Gol kral\u0131: ${name} (${n})`,
636
+ squadTopAssists: (name, n) => `Asist lideri: ${name} (${n})`,
637
+ detailStarted: "\u0130lk 11",
638
+ detailMatches: "Ma\xE7",
639
+ detailNatShort: "Uyruk",
640
+ detailYellows: "Sar\u0131",
641
+ detailReds: "K\u0131rm\u0131z\u0131",
642
+ availabilityNext: (opponent, isHome, kickoffMs) => `Sonraki: ${opponent} (${isHome ? "\u0130\xE7\xA0saha" : "Deplasman"})` + (kickoffMs !== null && kickoffMs > 0 ? ` \xB7 ${pdDateTr(kickoffMs, { day: "numeric", month: "short", weekday: "short" })}` : ""),
643
+ availabilityAvailable: "Haz\u0131r",
644
+ availabilityInjured: "Sakat",
645
+ availabilitySuspended: "Cezal\u0131",
646
+ availabilityUnavailable: "Haz\u0131r de\u011Fil",
647
+ availabilityNoConcerns: "Sakatl\u0131k bildirimi yok",
648
+ availabilityBack: (ms) => `D\xF6n\xFC\u015F: ${pdDateTr(ms, { day: "numeric", month: "short" })}`,
649
+ perfTitle: "Sezon performans\u0131",
650
+ perfTotal: "Toplam",
651
+ perfPer90: "90 dk",
652
+ perfRankedAgainst: (competition, group) => `${competition} ${GROUP_NOUN_TR[group] ?? group} aras\u0131nda`,
653
+ perfUnranked: "S\u0131ralama i\xE7in yeterli s\xFCre yok",
654
+ perfUnrankedCohort: "Bu mevkide s\u0131ralama i\xE7in yeterli oyuncu yok",
655
+ perfUnrankedNoLeague: "S\u0131ralanmad\u0131 \u2014 lig verisi yok",
656
+ perfGroupShooting: "\u015Eut",
657
+ perfGroupPassing: "Pas",
658
+ perfGroupPossession: "Top hakimiyeti",
659
+ perfGroupDefending: "Savunma",
660
+ perfMetric: {
661
+ goals: "Gol",
662
+ xg: "Gol beklentisi (xG)",
663
+ shots: "\u015Eut",
664
+ shotsOnTarget: "\u0130sabetli \u015Fut",
665
+ assists: "Asist",
666
+ successfulPasses: "Ba\u015Far\u0131l\u0131 pas",
667
+ passAccuracy: "Pas isabeti",
668
+ chancesCreated: "Yarat\u0131lan f\u0131rsat",
669
+ successfulDribbles: "Ba\u015Far\u0131l\u0131 \xE7al\u0131m",
670
+ dribbleSuccess: "\xC7al\u0131m ba\u015Far\u0131s\u0131",
671
+ touches: "Topla bulu\u015Fma",
672
+ tacklesWon: "Kazan\u0131lan m\xFCdahale",
673
+ interceptions: "Top kapma",
674
+ duelsWon: "Kazan\u0131lan ikili m\xFCcadele"
675
+ },
676
+ perfGroupNoun: GROUP_NOUN_TR,
677
+ matchLogTitle: "Ma\xE7 ge\xE7mi\u015Fi",
678
+ matchLogOpponent: (name, isHome) => isHome ? `${name} (\u0130)` : `${name} (D)`,
679
+ resultLetter: { W: "G", D: "B", L: "M" },
680
+ logShortDate: (ms) => pdDateTr(ms, { day: "numeric", month: "short" }),
568
681
  standingsColPlayed: "O",
569
682
  standingsColWon: "G",
570
683
  standingsColDrawn: "B",
@@ -975,6 +1088,45 @@ function normalizeUi(cfg) {
975
1088
  recordsMostAssists: strings.recordsMostAssists,
976
1089
  recordsSince: strings.recordsSince,
977
1090
  standingsColClub: strings.standingsColClub,
1091
+ statHeadPos: strings.statHeadPos,
1092
+ statHeadMins: strings.statHeadMins,
1093
+ statHeadGoals: strings.statHeadGoals,
1094
+ statHeadAssists: strings.statHeadAssists,
1095
+ statHeadYellow: strings.statHeadYellow,
1096
+ statHeadRed: strings.statHeadRed,
1097
+ statHeadRating: strings.statHeadRating,
1098
+ squadStatsEyebrow: strings.squadStatsEyebrow,
1099
+ squadTopScorer: strings.squadTopScorer,
1100
+ squadTopAssists: strings.squadTopAssists,
1101
+ detailStarted: strings.detailStarted,
1102
+ detailMatches: strings.detailMatches,
1103
+ detailNatShort: strings.detailNatShort,
1104
+ detailYellows: strings.detailYellows,
1105
+ detailReds: strings.detailReds,
1106
+ availabilityNext: strings.availabilityNext,
1107
+ availabilityAvailable: strings.availabilityAvailable,
1108
+ availabilityInjured: strings.availabilityInjured,
1109
+ availabilitySuspended: strings.availabilitySuspended,
1110
+ availabilityUnavailable: strings.availabilityUnavailable,
1111
+ availabilityNoConcerns: strings.availabilityNoConcerns,
1112
+ availabilityBack: strings.availabilityBack,
1113
+ perfTitle: strings.perfTitle,
1114
+ perfTotal: strings.perfTotal,
1115
+ perfPer90: strings.perfPer90,
1116
+ perfRankedAgainst: strings.perfRankedAgainst,
1117
+ perfUnranked: strings.perfUnranked,
1118
+ perfUnrankedCohort: strings.perfUnrankedCohort,
1119
+ perfUnrankedNoLeague: strings.perfUnrankedNoLeague,
1120
+ perfGroupShooting: strings.perfGroupShooting,
1121
+ perfGroupPassing: strings.perfGroupPassing,
1122
+ perfGroupPossession: strings.perfGroupPossession,
1123
+ perfGroupDefending: strings.perfGroupDefending,
1124
+ perfMetric: strings.perfMetric,
1125
+ perfGroupNoun: strings.perfGroupNoun,
1126
+ matchLogTitle: strings.matchLogTitle,
1127
+ matchLogOpponent: strings.matchLogOpponent,
1128
+ resultLetter: strings.resultLetter,
1129
+ logShortDate: strings.logShortDate,
978
1130
  standingsColPlayed: strings.standingsColPlayed,
979
1131
  standingsColWon: strings.standingsColWon,
980
1132
  standingsColDrawn: strings.standingsColDrawn,
@@ -3344,6 +3496,8 @@ import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRe
3344
3496
  function useClubSquadStats(conversation, { activeTab, enabled }) {
3345
3497
  const [data, setData] = useState10(null);
3346
3498
  const [seasonName, setSeasonName] = useState10(null);
3499
+ const [competitionName, setCompetitionName] = useState10(null);
3500
+ const [matchesPlayed, setMatchesPlayed] = useState10(null);
3347
3501
  const [loading, setLoading] = useState10(false);
3348
3502
  const [refreshCount, setRefreshCount] = useState10(0);
3349
3503
  const inFlightRef = useRef11(false);
@@ -3362,6 +3516,8 @@ function useClubSquadStats(conversation, { activeTab, enabled }) {
3362
3516
  if (active) {
3363
3517
  setData(result?.players ?? null);
3364
3518
  setSeasonName(result?.seasonName ?? null);
3519
+ setCompetitionName(result?.competitionName ?? null);
3520
+ setMatchesPlayed(result?.clubMatchesPlayed ?? null);
3365
3521
  }
3366
3522
  } catch {
3367
3523
  } finally {
@@ -3379,7 +3535,7 @@ function useClubSquadStats(conversation, { activeTab, enabled }) {
3379
3535
  setRefreshCount((c) => c + 1);
3380
3536
  }, []);
3381
3537
  const effectiveLoading = loading || activeTab === "squad" && enabled && data === null;
3382
- return { data, seasonName, loading: effectiveLoading, refresh };
3538
+ return { data, seasonName, competitionName, matchesPlayed, loading: effectiveLoading, refresh };
3383
3539
  }
3384
3540
 
3385
3541
  // src/useClubPlayerDetail.ts
@@ -3779,7 +3935,7 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
3779
3935
  }
3780
3936
 
3781
3937
  // src/components/ChatPanel.tsx
3782
- import { useCallback as useCallback22, useEffect as useEffect33, useLayoutEffect, useMemo as useMemo5, useRef as useRef30, useState as useState52 } from "react";
3938
+ import { useCallback as useCallback22, useEffect as useEffect33, useLayoutEffect, useMemo as useMemo5, useRef as useRef30, useState as useState54 } from "react";
3783
3939
 
3784
3940
  // src/components/ChatHeader.tsx
3785
3941
  import { useEffect as useEffect16, useRef as useRef17, useState as useState15 } from "react";
@@ -9967,51 +10123,92 @@ function footLabel(ui, foot) {
9967
10123
  return v;
9968
10124
  }
9969
10125
  }
10126
+ var GROUP_CODE = { Goalkeeper: "GK", Defender: "DF", Midfielder: "MF", Attacker: "FW" };
10127
+ function positionShort(code, positionName) {
10128
+ const c = code?.trim().toUpperCase() ?? "";
10129
+ if (c !== "") return c === "CF" || c === "SS" ? "ST" : c;
10130
+ return positionName !== null && GROUP_CODE[positionName] || "\u2013";
10131
+ }
10132
+ function statsEyebrow(ui, season, competition, matches) {
10133
+ if (season === null || competition === null || matches === null || matches <= 0) return null;
10134
+ return ui.squadStatsEyebrow(season, competition, matches);
10135
+ }
9970
10136
 
9971
10137
  // src/components/SquadStats.tsx
9972
10138
  import { jsx as jsx97, jsxs as jsxs83 } from "react/jsx-runtime";
10139
+ function leader(stats, pick) {
10140
+ let best = null;
10141
+ for (const p of stats) {
10142
+ if (pick(p) <= 0) continue;
10143
+ if (best === null || pick(p) > pick(best) || pick(p) === pick(best) && p.minutesPlayed < best.minutesPlayed) best = p;
10144
+ }
10145
+ return best;
10146
+ }
10147
+ function ratingClass(rating) {
10148
+ if (rating === null) return "ss-w-sq-c36 ss-w-sq-rtg-none";
10149
+ return Number(rating.toFixed(1)) >= 7 ? "ss-w-sq-c36 ss-w-sq-rtg ss-w-pos-ink" : "ss-w-sq-c36 ss-w-sq-rtg";
10150
+ }
9973
10151
  function SquadStats({ stats, loading, ui, onSelectPlayer }) {
9974
10152
  if (stats === null && loading) return /* @__PURE__ */ jsx97("div", { className: "ss-w-mon-list" });
9975
10153
  if (stats === null || stats.length === 0) return /* @__PURE__ */ jsx97("div", { className: "ss-w-mon-empty", children: ui.clubSquadStatsEmpty });
9976
- return /* @__PURE__ */ jsxs83("div", { className: "ss-w-mon-list", children: [
9977
- /* @__PURE__ */ jsxs83("div", { className: "ss-w-sq-row ss-w-sq-head", "aria-hidden": "true", children: [
9978
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-num" }),
9979
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-name" }),
9980
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-col", children: ui.statColApps }),
9981
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-col", children: ui.statColGoals }),
9982
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-col", children: ui.statColAssists }),
9983
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-col", children: ui.statColRating })
9984
- ] }),
9985
- groupByPosition(stats).map((group, gi) => /* @__PURE__ */ jsxs83("div", { children: [
9986
- group.positionName && /* @__PURE__ */ jsx97("div", { className: "ss-w-club-eyebrow", children: positionLabel(ui, group.positionName) }),
9987
- group.items.map((p) => /* @__PURE__ */ jsxs83("button", { type: "button", className: "ss-w-sq-row ss-w-sq-tap", onClick: () => onSelectPlayer(p.playerId), children: [
9988
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-num", children: p.jerseyNumber ?? "" }),
9989
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-name ss-w-sq-name-1", children: p.playerName }),
9990
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-col", children: p.appearances }),
9991
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-col", children: p.goals }),
9992
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-col", children: p.assists }),
9993
- /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-col", children: p.averageRating === null ? "\u2014" : p.averageRating.toFixed(1) })
10154
+ const scorer = leader(stats, (p) => p.goals);
10155
+ const assister = leader(stats, (p) => p.assists);
10156
+ const footer = [
10157
+ scorer && ui.squadTopScorer(scorer.playerName, scorer.goals),
10158
+ assister && ui.squadTopAssists(assister.playerName, assister.assists)
10159
+ ].filter((part) => !!part).join(" \xB7 ");
10160
+ return /* @__PURE__ */ jsxs83("div", { className: "ss-w-mon-list ss-w-sq-stats", children: [
10161
+ /* @__PURE__ */ jsxs83("div", { className: "ss-w-sq-card", children: [
10162
+ /* @__PURE__ */ jsxs83("div", { className: "ss-w-sq-row ss-w-sq-head", "aria-hidden": "true", children: [
10163
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-name" }),
10164
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-pos", children: ui.statHeadPos }),
10165
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c30", children: ui.statColApps }),
10166
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c36", children: ui.statHeadMins }),
10167
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20", children: ui.statHeadGoals }),
10168
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20", children: ui.statHeadAssists }),
10169
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20 ss-w-sq-yr", children: ui.statHeadYellow }),
10170
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20 ss-w-sq-yr", children: ui.statHeadRed }),
10171
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c36", children: ui.statHeadRating })
10172
+ ] }),
10173
+ stats.map((p) => /* @__PURE__ */ jsxs83("button", { type: "button", className: "ss-w-sq-row ss-w-sq-tap", onClick: () => onSelectPlayer(p.playerId), children: [
10174
+ /* @__PURE__ */ jsxs83("span", { className: "ss-w-sq-player", children: [
10175
+ p.jerseyNumber !== null && /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-badge", children: p.jerseyNumber }),
10176
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-name ss-w-sq-name-1", children: p.playerName })
10177
+ ] }),
10178
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-pos", children: positionShort(p.positionCode, p.positionName) }),
10179
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c30", children: p.appearances }),
10180
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c36", children: p.minutesPlayed }),
10181
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20", children: p.goals }),
10182
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20", children: p.assists }),
10183
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20 ss-w-sq-yr", children: p.yellowCards }),
10184
+ /* @__PURE__ */ jsx97("span", { className: "ss-w-sq-c20 ss-w-sq-yr", children: p.redCards }),
10185
+ /* @__PURE__ */ jsx97("span", { className: ratingClass(p.averageRating), children: p.averageRating === null ? "\u2013" : p.averageRating.toFixed(1) })
9994
10186
  ] }, p.playerId))
9995
- ] }, `${gi}-${group.positionName ?? "none"}`))
10187
+ ] }),
10188
+ footer !== "" && /* @__PURE__ */ jsx97("div", { className: "ss-w-sq-foot", children: footer })
9996
10189
  ] });
9997
10190
  }
9998
10191
 
9999
10192
  // src/components/Squad.tsx
10000
10193
  import { Fragment as Fragment21, jsx as jsx98, jsxs as jsxs84 } from "react/jsx-runtime";
10001
- function Squad({ squad, loading, ui, view, onToggleView, stats, statsLoading, onSelectPlayer }) {
10002
- const toggle = /* @__PURE__ */ jsx98("div", { className: "ss-w-sq-seg", role: "group", children: ["roster", "stats"].map((v) => /* @__PURE__ */ jsx98(
10003
- "button",
10004
- {
10005
- type: "button",
10006
- className: "ss-w-sq-seg-btn",
10007
- "aria-pressed": view === v,
10008
- onClick: () => {
10009
- if (view !== v) onToggleView();
10194
+ function Squad({ squad, loading, ui, view, onToggleView, stats, statsLoading, seasonName = null, competitionName = null, matchesPlayed = null, onSelectPlayer }) {
10195
+ const eyebrow = view === "stats" ? statsEyebrow(ui, seasonName, competitionName, matchesPlayed) : null;
10196
+ const toggle = /* @__PURE__ */ jsxs84("div", { className: "ss-w-sq-bar", children: [
10197
+ eyebrow !== null && /* @__PURE__ */ jsx98("div", { className: "ss-w-sq-eyebrow", children: eyebrow }),
10198
+ /* @__PURE__ */ jsx98("div", { className: "ss-w-sq-seg", role: "group", children: ["roster", "stats"].map((v) => /* @__PURE__ */ jsx98(
10199
+ "button",
10200
+ {
10201
+ type: "button",
10202
+ className: "ss-w-sq-seg-btn",
10203
+ "aria-pressed": view === v,
10204
+ onClick: () => {
10205
+ if (view !== v) onToggleView();
10206
+ },
10207
+ children: v === "roster" ? ui.squadViewRoster : ui.squadViewStats
10010
10208
  },
10011
- children: v === "roster" ? ui.squadViewRoster : ui.squadViewStats
10012
- },
10013
- v
10014
- )) });
10209
+ v
10210
+ )) })
10211
+ ] });
10015
10212
  if (view === "stats") {
10016
10213
  return /* @__PURE__ */ jsxs84(Fragment21, { children: [
10017
10214
  toggle,
@@ -10038,8 +10235,125 @@ function Squad({ squad, loading, ui, view, onToggleView, stats, statsLoading, on
10038
10235
  ] });
10039
10236
  }
10040
10237
 
10238
+ // src/components/PlayerPhoto.tsx
10239
+ import { useState as useState50 } from "react";
10240
+ import { jsx as jsx99 } from "react/jsx-runtime";
10241
+ function PlayerPhoto({ photoUrl, jerseyNumber, size }) {
10242
+ const [failed, setFailed] = useState50(false);
10243
+ const box = { width: size, height: size };
10244
+ if (photoUrl && !failed) {
10245
+ return /* @__PURE__ */ jsx99("img", { className: "ss-w-pd-photo", style: box, src: photoUrl, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
10246
+ }
10247
+ return /* @__PURE__ */ jsx99("span", { className: "ss-w-pd-photo ss-w-pd-avatar", style: { ...box, fontSize: Math.round(size * 0.35) }, "aria-hidden": "true", children: jerseyNumber ?? "" });
10248
+ }
10249
+
10250
+ // src/components/MiniPitch.tsx
10251
+ import { jsx as jsx100 } from "react/jsx-runtime";
10252
+ var SPOT = {
10253
+ GK: [50, 90],
10254
+ CB: [50, 75],
10255
+ LB: [18, 70],
10256
+ RB: [82, 70],
10257
+ LWB: [15, 58],
10258
+ RWB: [85, 58],
10259
+ DM: [50, 60],
10260
+ CM: [50, 48],
10261
+ LM: [18, 45],
10262
+ RM: [82, 45],
10263
+ AM: [50, 32],
10264
+ LW: [20, 25],
10265
+ RW: [80, 25],
10266
+ CF: [50, 14],
10267
+ SS: [50, 14],
10268
+ ST: [50, 14]
10269
+ };
10270
+ function MiniPitch({ positionCode }) {
10271
+ const spot = SPOT[positionCode?.trim().toUpperCase() ?? ""];
10272
+ if (spot === void 0) return null;
10273
+ return /* @__PURE__ */ jsx100("div", { className: "ss-w-pd-pitch", "aria-hidden": "true", children: /* @__PURE__ */ jsx100("div", { className: "ss-w-pd-pitch-dot", style: { left: `${spot[0]}%`, top: `${spot[1]}%` } }) });
10274
+ }
10275
+
10276
+ // src/components/PerformanceBars.tsx
10277
+ import { useState as useState51 } from "react";
10278
+ import { jsx as jsx101, jsxs as jsxs85 } from "react/jsx-runtime";
10279
+ var GROUPS = ["shooting", "passing", "possession", "defending"];
10280
+ function finite3(v) {
10281
+ return typeof v === "number" && Number.isFinite(v) ? v : null;
10282
+ }
10283
+ function valueOf(m, mode) {
10284
+ return finite3(mode === "total" ? m.total : m.per90);
10285
+ }
10286
+ function rankOf(m, mode) {
10287
+ const r = finite3(mode === "total" ? m.totalRank : m.per90Rank);
10288
+ return r === null ? null : Math.min(100, Math.max(0, Math.round(r)));
10289
+ }
10290
+ function format(m, v, mode) {
10291
+ if (m.isPercent) return `${v.toFixed(1)}%`;
10292
+ if (mode === "per90" || m.key === "xg") return v.toFixed(2);
10293
+ return String(Math.round(v));
10294
+ }
10295
+ function band(rank) {
10296
+ if (rank >= 67) return "pos";
10297
+ if (rank >= 34) return "warn";
10298
+ return "neg";
10299
+ }
10300
+ function groupTitle(ui, g) {
10301
+ switch (g) {
10302
+ case "shooting":
10303
+ return ui.perfGroupShooting;
10304
+ case "passing":
10305
+ return ui.perfGroupPassing;
10306
+ case "possession":
10307
+ return ui.perfGroupPossession;
10308
+ case "defending":
10309
+ return ui.perfGroupDefending;
10310
+ }
10311
+ }
10312
+ function unrankedLine(ui, reason) {
10313
+ switch (reason) {
10314
+ case "cohort":
10315
+ return ui.perfUnrankedCohort;
10316
+ case "noLeague":
10317
+ return ui.perfUnrankedNoLeague;
10318
+ default:
10319
+ return ui.perfUnranked;
10320
+ }
10321
+ }
10322
+ function PerformanceBars({ performance, competitionName, strings }) {
10323
+ const [mode, setMode] = useState51("total");
10324
+ const labelled = performance.metrics.filter((m) => Object.prototype.hasOwnProperty.call(strings.perfMetric, m.key));
10325
+ if (!labelled.some((m) => valueOf(m, "total") !== null || valueOf(m, "per90") !== null)) return null;
10326
+ const subtitle = !performance.ranked ? unrankedLine(strings, performance.unrankedReason) : competitionName ? strings.perfRankedAgainst(competitionName, performance.positionGroup) : null;
10327
+ const cards = GROUPS.map((g) => {
10328
+ const rows = labelled.filter((m) => m.group === g && valueOf(m, mode) !== null);
10329
+ if (rows.length === 0) return null;
10330
+ return /* @__PURE__ */ jsxs85("div", { className: "ss-w-pd-card ss-w-pd-perf-card", children: [
10331
+ /* @__PURE__ */ jsx101("div", { className: "ss-w-pd-perf-group", children: groupTitle(strings, g) }),
10332
+ rows.map((m) => {
10333
+ const v = valueOf(m, mode);
10334
+ const rank = performance.ranked ? rankOf(m, mode) : null;
10335
+ return /* @__PURE__ */ jsxs85("div", { className: "ss-w-pd-bar-row", children: [
10336
+ /* @__PURE__ */ jsxs85("div", { className: "ss-w-pd-bar-top", children: [
10337
+ /* @__PURE__ */ jsx101("span", { className: "ss-w-pd-bar-label", children: strings.perfMetric[m.key] }),
10338
+ /* @__PURE__ */ jsx101("span", { className: "ss-w-pd-bar-value", children: format(m, v, mode) })
10339
+ ] }),
10340
+ rank !== null && /* @__PURE__ */ jsx101("div", { className: "ss-w-pd-track", children: /* @__PURE__ */ jsx101("div", { className: `ss-w-pd-fill ss-w-pd-fill--${band(rank)}`, style: { width: `${rank}%` } }) })
10341
+ ] }, m.key);
10342
+ })
10343
+ ] }, g);
10344
+ });
10345
+ return /* @__PURE__ */ jsxs85("div", { children: [
10346
+ /* @__PURE__ */ jsxs85("div", { className: "ss-w-pd-perf-head", children: [
10347
+ /* @__PURE__ */ jsx101("div", { className: "ss-w-pd-eyebrow", children: strings.perfTitle }),
10348
+ /* @__PURE__ */ jsx101("div", { className: "ss-w-pd-seg", role: "group", children: ["total", "per90"].map((m) => /* @__PURE__ */ jsx101("button", { type: "button", className: "ss-w-pd-seg-btn", "aria-pressed": mode === m, onClick: () => setMode(m), children: m === "total" ? strings.perfTotal : strings.perfPer90 }, m)) })
10349
+ ] }),
10350
+ subtitle !== null && /* @__PURE__ */ jsx101("div", { className: "ss-w-pd-perf-sub", children: subtitle }),
10351
+ /* @__PURE__ */ jsx101("div", { className: "ss-w-pd-perf-cards", children: cards })
10352
+ ] });
10353
+ }
10354
+
10041
10355
  // src/components/PlayerDetail.tsx
10042
- import { Fragment as Fragment22, jsx as jsx99, jsxs as jsxs85 } from "react/jsx-runtime";
10356
+ import { Fragment as Fragment22, jsx as jsx102, jsxs as jsxs86 } from "react/jsx-runtime";
10043
10357
  var DASH = "\u2014";
10044
10358
  function ageFrom(dobMs) {
10045
10359
  if (dobMs === null) return DASH;
@@ -10050,55 +10364,128 @@ function ageFrom(dobMs) {
10050
10364
  if (beforeBirthday) age--;
10051
10365
  return String(age);
10052
10366
  }
10053
- function Field({ label, value }) {
10054
- return /* @__PURE__ */ jsxs85("div", { className: "ss-w-pd-field", children: [
10055
- /* @__PURE__ */ jsx99("span", { className: "ss-w-pd-label", children: label }),
10056
- /* @__PURE__ */ jsx99("span", { className: "ss-w-pd-value", children: value })
10367
+ function validMs(ms) {
10368
+ return typeof ms === "number" && Number.isFinite(ms) && ms > 0 ? ms : null;
10369
+ }
10370
+ function ratingTone(rounded) {
10371
+ if (rounded >= 7) return "pos";
10372
+ if (rounded >= 6) return "warn";
10373
+ return "neg";
10374
+ }
10375
+ function Bio({ label, value }) {
10376
+ return /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-bio-item", children: [
10377
+ /* @__PURE__ */ jsx102("span", { className: "ss-w-pd-faint", children: label }),
10378
+ " ",
10379
+ /* @__PURE__ */ jsx102("span", { children: value })
10380
+ ] });
10381
+ }
10382
+ function Tile({ label, value, pos }) {
10383
+ return /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-tile", children: [
10384
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-tile-label", children: label }),
10385
+ /* @__PURE__ */ jsx102("div", { className: pos ? "ss-w-pd-tile-value ss-w-pd-pos-ink" : "ss-w-pd-tile-value", children: value })
10386
+ ] });
10387
+ }
10388
+ function AvailabilityCard({ ui, next, availability }) {
10389
+ let note = null;
10390
+ let pill = null;
10391
+ if (availability !== null) {
10392
+ if (availability.status === "available") {
10393
+ note = ui.availabilityNoConcerns;
10394
+ pill = { text: ui.availabilityAvailable, tone: "pos" };
10395
+ } else {
10396
+ const back = validMs(availability.expectedReturnUnixMs);
10397
+ note = [availability.detail?.trim() || null, back === null ? null : ui.availabilityBack(back)].filter(Boolean).join(" \xB7 ") || null;
10398
+ pill = availability.status === "injured" ? { text: ui.availabilityInjured, tone: "neg" } : availability.status === "suspended" ? { text: ui.availabilitySuspended, tone: "warn" } : { text: ui.availabilityUnavailable, tone: "warn" };
10399
+ }
10400
+ }
10401
+ return /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-card ss-w-pd-avail", children: [
10402
+ /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-avail-text", children: [
10403
+ next !== null && /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-avail-next", children: ui.availabilityNext(next.opponentName, next.isHome, validMs(next.kickoffUnixMs)) }),
10404
+ note !== null && /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-avail-note", children: note })
10405
+ ] }),
10406
+ pill !== null && /* @__PURE__ */ jsx102("div", { className: `ss-w-pd-pill ss-w-pd-pill--${pill.tone}`, children: pill.text })
10407
+ ] });
10408
+ }
10409
+ function MatchRow({ ui, row }) {
10410
+ const date = validMs(row.kickoffUnixMs);
10411
+ const extras = [
10412
+ row.goals > 0 ? `${row.goals}${ui.statHeadGoals}` : null,
10413
+ row.assists > 0 ? `${row.assists}${ui.statHeadAssists}` : null,
10414
+ row.yellowCards > 0 ? `${row.yellowCards}${ui.statHeadYellow}` : null,
10415
+ row.sentOff ? ui.statHeadRed : null
10416
+ ].filter((x) => x !== null);
10417
+ const sub = [`${ui.resultLetter[row.result]} ${row.goalsFor}\u2013${row.goalsAgainst}`, `${row.minutes}\u2032`, ...extras].join(" \xB7 ");
10418
+ const rating = typeof row.rating === "number" && Number.isFinite(row.rating) ? Math.round(row.rating * 10) / 10 : null;
10419
+ const pillTone = row.result === "W" ? "pos" : row.result === "L" ? "neg" : "draw";
10420
+ return /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-match", children: [
10421
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-match-date", children: date === null ? "" : ui.logShortDate(date) }),
10422
+ /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-match-main", children: [
10423
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-match-opp", children: ui.matchLogOpponent(row.opponentName, row.isHome) }),
10424
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-match-sub", children: sub })
10425
+ ] }),
10426
+ /* @__PURE__ */ jsx102("div", { className: `ss-w-pd-pill ss-w-pd-pill--${pillTone}`, children: ui.resultLetter[row.result] }),
10427
+ rating === null ? /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-chip-empty" }) : /* @__PURE__ */ jsx102("div", { className: `ss-w-pd-chip ss-w-pd-chip--${ratingTone(rating)}`, children: rating.toFixed(1) })
10057
10428
  ] });
10058
10429
  }
10059
10430
  function PlayerDetail({ detail, loading, ui, seasonName, onClose }) {
10060
- const back = /* @__PURE__ */ jsxs85("button", { type: "button", className: "ss-w-pd-back", onClick: onClose, children: [
10061
- /* @__PURE__ */ jsx99("span", { "aria-hidden": "true", children: "\u2039" }),
10062
- " ",
10431
+ const back = /* @__PURE__ */ jsxs86("button", { type: "button", className: "ss-w-pd-back", onClick: onClose, children: [
10432
+ /* @__PURE__ */ jsx102("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx102("path", { d: "M15 18l-6-6 6-6" }) }),
10063
10433
  ui.clubPlayerBack
10064
10434
  ] });
10065
10435
  if (detail === null) {
10066
- return loading ? /* @__PURE__ */ jsxs85(Fragment22, { children: [
10067
- /* @__PURE__ */ jsx99("div", { className: "ss-w-pd-bar", children: back }),
10068
- /* @__PURE__ */ jsx99("div", { className: "ss-w-mon-list" })
10069
- ] }) : /* @__PURE__ */ jsxs85(Fragment22, { children: [
10070
- /* @__PURE__ */ jsx99("div", { className: "ss-w-pd-bar", children: back }),
10071
- /* @__PURE__ */ jsx99("div", { className: "ss-w-mon-empty", children: ui.clubPlayerDetailEmpty })
10436
+ return loading ? /* @__PURE__ */ jsxs86(Fragment22, { children: [
10437
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-bar", children: back }),
10438
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-mon-list" })
10439
+ ] }) : /* @__PURE__ */ jsxs86(Fragment22, { children: [
10440
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-bar", children: back }),
10441
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-mon-empty", children: ui.clubPlayerDetailEmpty })
10072
10442
  ] });
10073
10443
  }
10074
10444
  const s = detail.seasonStats;
10075
- const opt = (v, digits) => v === null ? DASH : digits === void 0 ? String(v) : v.toFixed(digits);
10076
- return /* @__PURE__ */ jsxs85(Fragment22, { children: [
10077
- /* @__PURE__ */ jsx99("div", { className: "ss-w-pd-bar", children: back }),
10078
- /* @__PURE__ */ jsxs85("div", { className: "ss-w-mon-list", children: [
10079
- /* @__PURE__ */ jsxs85("div", { children: [
10080
- /* @__PURE__ */ jsx99("div", { className: "ss-w-pd-name", children: detail.playerName }),
10081
- /* @__PURE__ */ jsx99("div", { className: "ss-w-pd-sub", children: [detail.jerseyNumber === null ? null : `#${detail.jerseyNumber}`, positionLabel(ui, detail.positionName)].filter(Boolean).join(" \xB7 ") })
10082
- ] }),
10083
- /* @__PURE__ */ jsxs85("div", { className: "ss-w-pd-grid ss-w-pd-bio", children: [
10084
- /* @__PURE__ */ jsx99(Field, { label: ui.detailNationality, value: detail.nationality ?? DASH }),
10085
- /* @__PURE__ */ jsx99(Field, { label: ui.detailAge, value: ageFrom(detail.dateOfBirthUnixMs) }),
10086
- /* @__PURE__ */ jsx99(Field, { label: ui.detailHeight, value: detail.heightCm === null ? DASH : `${detail.heightCm} cm` }),
10087
- /* @__PURE__ */ jsx99(Field, { label: ui.detailFoot, value: footLabel(ui, detail.foot) ?? DASH })
10445
+ const foot = footLabel(ui, detail.foot);
10446
+ const position = positionLabel(ui, detail.positionName);
10447
+ const subLine = [detail.teamName?.trim() || null, position].filter(Boolean).join(" \xB7 ");
10448
+ const competition = detail.competitionName?.trim() || null;
10449
+ const eyebrow = seasonName === null ? null : competition === null ? ui.detailSeason.replace("{season}", seasonName) : `${seasonName} ${competition}`;
10450
+ const rating = typeof s.averageRating === "number" && Number.isFinite(s.averageRating) ? s.averageRating : null;
10451
+ const next = detail.nextFixture ?? null;
10452
+ const availability = detail.availability ?? null;
10453
+ const log = detail.matchLog ?? [];
10454
+ return /* @__PURE__ */ jsxs86(Fragment22, { children: [
10455
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-bar", children: back }),
10456
+ /* @__PURE__ */ jsxs86("div", { className: "ss-w-mon-list ss-w-pd-list", children: [
10457
+ /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-card ss-w-pd-profile", children: [
10458
+ /* @__PURE__ */ jsx102(PlayerPhoto, { photoUrl: detail.photoUrl, jerseyNumber: detail.jerseyNumber, size: 52 }, detail.photoUrl ?? ""),
10459
+ /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-profile-main", children: [
10460
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-name", children: detail.playerName }),
10461
+ subLine !== "" && /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-sub", children: subLine }),
10462
+ /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-bio", children: [
10463
+ /* @__PURE__ */ jsx102(Bio, { label: ui.detailAge, value: ageFrom(detail.dateOfBirthUnixMs) }),
10464
+ /* @__PURE__ */ jsx102(Bio, { label: ui.detailHeight, value: detail.heightCm === null ? DASH : `${detail.heightCm} cm` }),
10465
+ foot !== null && /* @__PURE__ */ jsx102(Bio, { label: ui.detailFoot, value: foot }),
10466
+ /* @__PURE__ */ jsx102(Bio, { label: ui.detailNatShort, value: detail.nationality ?? DASH })
10467
+ ] })
10468
+ ] }),
10469
+ /* @__PURE__ */ jsx102(MiniPitch, { positionCode: detail.positionCode })
10088
10470
  ] }),
10089
- /* @__PURE__ */ jsxs85("div", { children: [
10090
- seasonName !== null && /* @__PURE__ */ jsx99("div", { className: "ss-w-club-eyebrow", children: ui.detailSeason.replace("{season}", seasonName) }),
10091
- /* @__PURE__ */ jsxs85("div", { className: "ss-w-pd-grid", children: [
10092
- /* @__PURE__ */ jsx99(Field, { label: ui.statColApps, value: String(s.appearances) }),
10093
- /* @__PURE__ */ jsx99(Field, { label: ui.statColMinutes, value: String(s.minutesPlayed) }),
10094
- /* @__PURE__ */ jsx99(Field, { label: ui.statColGoals, value: String(s.goals) }),
10095
- /* @__PURE__ */ jsx99(Field, { label: ui.statColAssists, value: String(s.assists) }),
10096
- /* @__PURE__ */ jsx99(Field, { label: ui.statColYellow, value: String(s.yellowCards) }),
10097
- /* @__PURE__ */ jsx99(Field, { label: ui.statColRed, value: String(s.redCards) }),
10098
- /* @__PURE__ */ jsx99(Field, { label: ui.statColRating, value: opt(s.averageRating, 1) }),
10099
- /* @__PURE__ */ jsx99(Field, { label: ui.statColXg, value: opt(s.expectedGoals, 2) }),
10100
- /* @__PURE__ */ jsx99(Field, { label: ui.statColShots, value: opt(s.totalShots) })
10471
+ (next !== null || availability !== null) && /* @__PURE__ */ jsx102(AvailabilityCard, { ui, next, availability }),
10472
+ /* @__PURE__ */ jsxs86("div", { children: [
10473
+ eyebrow !== null && /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-eyebrow ss-w-pd-eyebrow--block", children: eyebrow }),
10474
+ /* @__PURE__ */ jsxs86("div", { className: "ss-w-pd-tiles", children: [
10475
+ /* @__PURE__ */ jsx102(Tile, { label: ui.statColGoals, value: String(s.goals) }),
10476
+ /* @__PURE__ */ jsx102(Tile, { label: ui.statColAssists, value: String(s.assists) }),
10477
+ typeof s.starts === "number" && /* @__PURE__ */ jsx102(Tile, { label: ui.detailStarted, value: String(s.starts) }),
10478
+ /* @__PURE__ */ jsx102(Tile, { label: ui.detailMatches, value: String(s.appearances) }),
10479
+ /* @__PURE__ */ jsx102(Tile, { label: ui.statColMinutes, value: String(s.minutesPlayed) }),
10480
+ rating !== null && /* @__PURE__ */ jsx102(Tile, { label: ui.statColRating, value: rating.toFixed(2), pos: Math.round(rating * 100) / 100 >= 7 }),
10481
+ /* @__PURE__ */ jsx102(Tile, { label: ui.detailYellows, value: String(s.yellowCards) }),
10482
+ /* @__PURE__ */ jsx102(Tile, { label: ui.detailReds, value: String(s.redCards) })
10101
10483
  ] })
10484
+ ] }),
10485
+ detail.performance != null && /* @__PURE__ */ jsx102(PerformanceBars, { performance: detail.performance, competitionName: competition, strings: ui }),
10486
+ log.length > 0 && /* @__PURE__ */ jsxs86("div", { children: [
10487
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-eyebrow ss-w-pd-eyebrow--block", children: ui.matchLogTitle }),
10488
+ /* @__PURE__ */ jsx102("div", { className: "ss-w-pd-card ss-w-pd-log", children: log.map((row) => /* @__PURE__ */ jsx102(MatchRow, { ui, row }, row.matchId)) })
10102
10489
  ] })
10103
10490
  ] })
10104
10491
  ] });
@@ -10106,12 +10493,12 @@ function PlayerDetail({ detail, loading, ui, seasonName, onClose }) {
10106
10493
 
10107
10494
  // src/components/PresetSpeedDial.tsx
10108
10495
  import { useId as useId10 } from "react";
10109
- import { jsx as jsx100, jsxs as jsxs86 } from "react/jsx-runtime";
10496
+ import { jsx as jsx103, jsxs as jsxs87 } from "react/jsx-runtime";
10110
10497
  function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef, buttonRef }) {
10111
10498
  const pillsId = useId10();
10112
10499
  const tabIndex = expanded ? 0 : -1;
10113
- return /* @__PURE__ */ jsxs86("div", { ref: rootRef, className: "ss-w-dial", children: [
10114
- /* @__PURE__ */ jsxs86(
10500
+ return /* @__PURE__ */ jsxs87("div", { ref: rootRef, className: "ss-w-dial", children: [
10501
+ /* @__PURE__ */ jsxs87(
10115
10502
  "button",
10116
10503
  {
10117
10504
  ref: buttonRef,
@@ -10122,28 +10509,28 @@ function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef
10122
10509
  "aria-label": strings.dialName,
10123
10510
  onClick: onToggle,
10124
10511
  children: [
10125
- /* @__PURE__ */ jsx100("span", { className: "ss-w-dial-icon ss-w-dial-icon--open", children: /* @__PURE__ */ jsx100(SlidersIcon, {}) }),
10126
- /* @__PURE__ */ jsx100("span", { className: "ss-w-dial-icon ss-w-dial-icon--close", children: /* @__PURE__ */ jsx100(CloseIcon, {}) }),
10127
- showDot && !expanded ? /* @__PURE__ */ jsx100("span", { className: "ss-w-dial-dot", "aria-hidden": "true" }) : null
10512
+ /* @__PURE__ */ jsx103("span", { className: "ss-w-dial-icon ss-w-dial-icon--open", children: /* @__PURE__ */ jsx103(SlidersIcon, {}) }),
10513
+ /* @__PURE__ */ jsx103("span", { className: "ss-w-dial-icon ss-w-dial-icon--close", children: /* @__PURE__ */ jsx103(CloseIcon, {}) }),
10514
+ showDot && !expanded ? /* @__PURE__ */ jsx103("span", { className: "ss-w-dial-dot", "aria-hidden": "true" }) : null
10128
10515
  ]
10129
10516
  }
10130
10517
  ),
10131
- /* @__PURE__ */ jsxs86("div", { id: pillsId, className: "ss-w-dial-pills", "data-open": expanded ? "" : void 0, children: [
10132
- /* @__PURE__ */ jsxs86("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("numbers"), children: [
10133
- /* @__PURE__ */ jsx100(SlidersIcon, {}),
10134
- /* @__PURE__ */ jsx100("span", { className: "ss-w-dial-pill-label", children: strings.setNumbers })
10518
+ /* @__PURE__ */ jsxs87("div", { id: pillsId, className: "ss-w-dial-pills", "data-open": expanded ? "" : void 0, children: [
10519
+ /* @__PURE__ */ jsxs87("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("numbers"), children: [
10520
+ /* @__PURE__ */ jsx103(SlidersIcon, {}),
10521
+ /* @__PURE__ */ jsx103("span", { className: "ss-w-dial-pill-label", children: strings.setNumbers })
10135
10522
  ] }),
10136
- /* @__PURE__ */ jsxs86("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("combo"), children: [
10137
- /* @__PURE__ */ jsx100(ComboIcon, {}),
10138
- /* @__PURE__ */ jsx100("span", { className: "ss-w-dial-pill-label", children: strings.buildCombo })
10523
+ /* @__PURE__ */ jsxs87("button", { type: "button", className: "ss-w-dial-pill", tabIndex, onClick: () => onOpen("combo"), children: [
10524
+ /* @__PURE__ */ jsx103(ComboIcon, {}),
10525
+ /* @__PURE__ */ jsx103("span", { className: "ss-w-dial-pill-label", children: strings.buildCombo })
10139
10526
  ] })
10140
10527
  ] })
10141
10528
  ] });
10142
10529
  }
10143
10530
 
10144
10531
  // src/components/PresetTools.tsx
10145
- import { Fragment as Fragment23, useEffect as useEffect31, useId as useId11, useRef as useRef28, useState as useState50 } from "react";
10146
- import { Fragment as Fragment24, jsx as jsx101, jsxs as jsxs87 } from "react/jsx-runtime";
10532
+ import { Fragment as Fragment23, useEffect as useEffect31, useId as useId11, useRef as useRef28, useState as useState52 } from "react";
10533
+ import { Fragment as Fragment24, jsx as jsx104, jsxs as jsxs88 } from "react/jsx-runtime";
10147
10534
  var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
10148
10535
  function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
10149
10536
  const dialogRef = useRef28(null);
@@ -10181,79 +10568,79 @@ function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
10181
10568
  first.focus();
10182
10569
  }
10183
10570
  };
10184
- return /* @__PURE__ */ jsx101("div", { className: "ss-w-tool-backdrop", children: /* @__PURE__ */ jsxs87("div", { ref: dialogRef, className: "ss-w-tool", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, onKeyDown: trapTab, children: [
10185
- /* @__PURE__ */ jsxs87("div", { className: "ss-w-tool-head", children: [
10186
- /* @__PURE__ */ jsx101("h2", { id: titleId, className: "ss-w-tool-title", children: title }),
10187
- /* @__PURE__ */ jsx101("button", { type: "button", className: "ss-w-tool-close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ jsx101(CloseIcon, {}) })
10571
+ return /* @__PURE__ */ jsx104("div", { className: "ss-w-tool-backdrop", children: /* @__PURE__ */ jsxs88("div", { ref: dialogRef, className: "ss-w-tool", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, onKeyDown: trapTab, children: [
10572
+ /* @__PURE__ */ jsxs88("div", { className: "ss-w-tool-head", children: [
10573
+ /* @__PURE__ */ jsx104("h2", { id: titleId, className: "ss-w-tool-title", children: title }),
10574
+ /* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-close", "aria-label": closeLabel, onClick: onClose, children: /* @__PURE__ */ jsx104(CloseIcon, {}) })
10188
10575
  ] }),
10189
- /* @__PURE__ */ jsx101("div", { className: "ss-w-tool-body", children }),
10190
- footer ? /* @__PURE__ */ jsx101("div", { className: "ss-w-tool-foot", children: footer }) : null
10576
+ /* @__PURE__ */ jsx104("div", { className: "ss-w-tool-body", children }),
10577
+ footer ? /* @__PURE__ */ jsx104("div", { className: "ss-w-tool-foot", children: footer }) : null
10191
10578
  ] }) });
10192
10579
  }
10193
10580
  function fillTemplate(template, slots) {
10194
10581
  return template.split(/(\{[a-z]+\})/).filter((part) => part !== "").map((part, i) => {
10195
10582
  const key = /^\{([a-z]+)\}$/.exec(part)?.[1];
10196
- return /* @__PURE__ */ jsx101(Fragment23, { children: key !== void 0 && key in slots ? slots[key] : part }, i);
10583
+ return /* @__PURE__ */ jsx104(Fragment23, { children: key !== void 0 && key in slots ? slots[key] : part }, i);
10197
10584
  });
10198
10585
  }
10199
10586
  function NumberSelect({ current, choices: choices2, label, notToday, lockEmpty = true, onChoose }) {
10200
10587
  const selected = Math.max(0, choices2.findIndex((c) => c.text === current));
10201
- return /* @__PURE__ */ jsxs87("span", { className: "ss-w-tool-num", children: [
10202
- /* @__PURE__ */ jsx101("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: current }),
10203
- /* @__PURE__ */ jsx101("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(selected), onChange: (e) => {
10588
+ return /* @__PURE__ */ jsxs88("span", { className: "ss-w-tool-num", children: [
10589
+ /* @__PURE__ */ jsx104("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: current }),
10590
+ /* @__PURE__ */ jsx104("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(selected), onChange: (e) => {
10204
10591
  const c = choices2[Number(e.target.value)];
10205
10592
  if (c) onChoose(c.value);
10206
- }, children: choices2.map((c, i) => /* @__PURE__ */ jsx101("option", { value: String(i), disabled: lockEmpty && !c.available && i !== selected, children: c.available ? c.text : `${c.text}${notToday}` }, i)) })
10593
+ }, children: choices2.map((c, i) => /* @__PURE__ */ jsx104("option", { value: String(i), disabled: lockEmpty && !c.available && i !== selected, children: c.available ? c.text : `${c.text}${notToday}` }, i)) })
10207
10594
  ] });
10208
10595
  }
10209
10596
  function ChoiceSelect({ currentIdx, sizeLabels, optionLabels, label, onChoose }) {
10210
10597
  const sizeText = sizeLabels[currentIdx] ?? "";
10211
- return /* @__PURE__ */ jsxs87("span", { className: "ss-w-tool-num", children: [
10212
- /* @__PURE__ */ jsx101("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: sizeText }),
10213
- /* @__PURE__ */ jsx101("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(currentIdx), onChange: (e) => onChoose(Number(e.target.value)), children: optionLabels.map((opt, i) => /* @__PURE__ */ jsx101("option", { value: String(i), children: opt }, i)) })
10598
+ return /* @__PURE__ */ jsxs88("span", { className: "ss-w-tool-num", children: [
10599
+ /* @__PURE__ */ jsx104("span", { className: "ss-w-tool-num-size", "aria-hidden": "true", children: sizeText }),
10600
+ /* @__PURE__ */ jsx104("select", { className: "ss-w-tool-num-select", "aria-label": label, value: String(currentIdx), onChange: (e) => onChoose(Number(e.target.value)), children: optionLabels.map((opt, i) => /* @__PURE__ */ jsx104("option", { value: String(i), children: opt }, i)) })
10214
10601
  ] });
10215
10602
  }
10216
10603
  function SendButton({ label, display, disabled, onClick }) {
10217
- return /* @__PURE__ */ jsx101("button", { type: "button", className: "ss-w-tool-send", "aria-label": `${label}: ${display}`, disabled, onClick, children: label });
10604
+ return /* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-send", "aria-label": `${label}: ${display}`, disabled, onClick, children: label });
10218
10605
  }
10219
10606
  function PickList({ picks, formatKickoff }) {
10220
- return /* @__PURE__ */ jsx101("ul", { className: "ss-w-tool-picks", role: "list", children: picks.map((p) => /* @__PURE__ */ jsxs87("li", { className: "ss-w-tool-pick", children: [
10221
- /* @__PURE__ */ jsxs87("span", { className: "ss-w-tool-pick-match", children: [
10607
+ return /* @__PURE__ */ jsx104("ul", { className: "ss-w-tool-picks", role: "list", children: picks.map((p) => /* @__PURE__ */ jsxs88("li", { className: "ss-w-tool-pick", children: [
10608
+ /* @__PURE__ */ jsxs88("span", { className: "ss-w-tool-pick-match", children: [
10222
10609
  p.homeTeamName,
10223
10610
  " \u2013 ",
10224
10611
  p.awayTeamName
10225
10612
  ] }),
10226
- /* @__PURE__ */ jsxs87("span", { className: "ss-w-tool-pick-sel", children: [
10613
+ /* @__PURE__ */ jsxs88("span", { className: "ss-w-tool-pick-sel", children: [
10227
10614
  p.marketLabel,
10228
10615
  ": ",
10229
10616
  p.selectionLabel,
10230
10617
  p.line ? ` ${p.line}` : ""
10231
10618
  ] }),
10232
- /* @__PURE__ */ jsx101("span", { className: "ss-w-tool-pick-kick", children: formatKickoff(p.kickoffUtc) }),
10233
- /* @__PURE__ */ jsx101("span", { className: "ss-w-tool-pick-price", children: p.price.toFixed(2) })
10619
+ /* @__PURE__ */ jsx104("span", { className: "ss-w-tool-pick-kick", children: formatKickoff(p.kickoffUtc) }),
10620
+ /* @__PURE__ */ jsx104("span", { className: "ss-w-tool-pick-price", children: p.price.toFixed(2) })
10234
10621
  ] }, p.matchOddsId)) });
10235
10622
  }
10236
10623
  function ComboPreview({ cell, formatKickoff }) {
10237
- return /* @__PURE__ */ jsxs87(Fragment24, { children: [
10238
- /* @__PURE__ */ jsx101(PickList, { picks: cell.combo.legs, formatKickoff }),
10239
- /* @__PURE__ */ jsx101("div", { className: "ss-w-tool-math", children: cell.combo.multiplication })
10624
+ return /* @__PURE__ */ jsxs88(Fragment24, { children: [
10625
+ /* @__PURE__ */ jsx104(PickList, { picks: cell.combo.legs, formatKickoff }),
10626
+ /* @__PURE__ */ jsx104("div", { className: "ss-w-tool-math", children: cell.combo.multiplication })
10240
10627
  ] });
10241
10628
  }
10242
10629
  function Unavailable({ text }) {
10243
- return /* @__PURE__ */ jsx101("p", { className: "ss-w-tool-unavailable", children: text });
10630
+ return /* @__PURE__ */ jsx104("p", { className: "ss-w-tool-unavailable", children: text });
10244
10631
  }
10245
10632
  function AskRow({ icon, ask, ready, send }) {
10246
- return /* @__PURE__ */ jsxs87("section", { className: "ss-w-tool-row ss-w-tool-row--ask", children: [
10247
- /* @__PURE__ */ jsx101("span", { className: "ss-w-tool-icon", "aria-hidden": "true", children: icon }),
10248
- /* @__PURE__ */ jsxs87("div", { className: "ss-w-tool-main", children: [
10249
- /* @__PURE__ */ jsx101("p", { className: "ss-w-tool-ask", children: ask }),
10250
- ready ? /* @__PURE__ */ jsx101("span", { className: "ss-w-tool-ready", children: ready }) : null
10633
+ return /* @__PURE__ */ jsxs88("section", { className: "ss-w-tool-row ss-w-tool-row--ask", children: [
10634
+ /* @__PURE__ */ jsx104("span", { className: "ss-w-tool-icon", "aria-hidden": "true", children: icon }),
10635
+ /* @__PURE__ */ jsxs88("div", { className: "ss-w-tool-main", children: [
10636
+ /* @__PURE__ */ jsx104("p", { className: "ss-w-tool-ask", children: ask }),
10637
+ ready ? /* @__PURE__ */ jsx104("span", { className: "ss-w-tool-ready", children: ready }) : null
10251
10638
  ] }),
10252
10639
  send
10253
10640
  ] });
10254
10641
  }
10255
10642
  function RoundSend({ label, display, disabled, onClick }) {
10256
- return /* @__PURE__ */ jsx101("button", { type: "button", className: "ss-w-tool-go", "aria-label": `${label}: ${display}`, disabled, onClick, children: /* @__PURE__ */ jsx101(SendIcon, {}) });
10643
+ return /* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-go", "aria-label": `${label}: ${display}`, disabled, onClick, children: /* @__PURE__ */ jsx104(SendIcon, {}) });
10257
10644
  }
10258
10645
  var BIG_COMBO = { total: 50, legs: 6 };
10259
10646
  function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
@@ -10262,15 +10649,15 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
10262
10649
  const totals = comboTotals(grid);
10263
10650
  const legChoices = comboLegChoices(grid);
10264
10651
  const count = FIXED_SINGLES_COUNT;
10265
- const [maxPrice, setMaxPrice] = useState50(() => startSingles(grid.singles, limits, START.maxPrice, count));
10266
- const [minPrice, setMinPrice] = useState50(() => startSingles(grid.singlesFrom, floors, START.minPrice, count));
10267
- const [start] = useState50(() => startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs));
10268
- const [total, setTotal] = useState50(start.total);
10269
- const [legs, setLegs] = useState50(start.legs);
10270
- const [bigStart] = useState50(() => startCombo(grid, totals, legChoices, BIG_COMBO.total, BIG_COMBO.legs));
10271
- const [bigTotal, setBigTotal] = useState50(bigStart.total);
10272
- const [bigLegs, setBigLegs] = useState50(bigStart.legs);
10273
- const [announcement, setAnnouncement] = useState50("");
10652
+ const [maxPrice, setMaxPrice] = useState52(() => startSingles(grid.singles, limits, START.maxPrice, count));
10653
+ const [minPrice, setMinPrice] = useState52(() => startSingles(grid.singlesFrom, floors, START.minPrice, count));
10654
+ const [start] = useState52(() => startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs));
10655
+ const [total, setTotal] = useState52(start.total);
10656
+ const [legs, setLegs] = useState52(start.legs);
10657
+ const [bigStart] = useState52(() => startCombo(grid, totals, legChoices, BIG_COMBO.total, BIG_COMBO.legs));
10658
+ const [bigTotal, setBigTotal] = useState52(bigStart.total);
10659
+ const [bigLegs, setBigLegs] = useState52(bigStart.legs);
10660
+ const [announcement, setAnnouncement] = useState52("");
10274
10661
  const maxCell = findSingles(grid.singles, maxPrice, count);
10275
10662
  const minCell = findSingles(grid.singlesFrom, minPrice, count);
10276
10663
  const comboCell = findCombo(grid, total, legs);
@@ -10314,95 +10701,95 @@ function SetNumbersTool({ grid, strings, streaming, onSend, onClose }) {
10314
10701
  const totalChoices = totals.map((v) => ({ value: v, text: v.toFixed(1), available: legChoices.some((n) => !!findCombo(grid, v, n)) }));
10315
10702
  const legChoicesFor = (t) => legChoices.map((n) => ({ value: n, text: String(n), available: !!findCombo(grid, t, n) }));
10316
10703
  const markets = grid.markets ?? [];
10317
- const [marketIdx, setMarketIdx] = useState50(0);
10704
+ const [marketIdx, setMarketIdx] = useState52(0);
10318
10705
  const marketCell = markets[marketIdx] ?? null;
10319
10706
  const marketLabels = markets.map((c) => strings.marketShort(c.marketDeveloperName, c.marketLabel, c.selectionLabel ?? null));
10320
10707
  const singlesReady = (cell) => cell ? strings.readyCount(cell.picks.length) : strings.unavailable;
10321
10708
  const comboReady = (cell) => cell ? strings.readyAt(cell.combo.total) : strings.unavailable;
10322
- return /* @__PURE__ */ jsxs87(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
10323
- /* @__PURE__ */ jsx101(
10709
+ return /* @__PURE__ */ jsxs88(PresetToolModal, { title: strings.setNumbers, closeLabel: strings.close, onClose, children: [
10710
+ /* @__PURE__ */ jsx104(
10324
10711
  AskRow,
10325
10712
  {
10326
10713
  icon: "\u{1F3AF}",
10327
10714
  ask: fillTemplate(strings.maxPriceRow, {
10328
10715
  count: String(count),
10329
- price: /* @__PURE__ */ jsx101(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
10716
+ price: /* @__PURE__ */ jsx104(NumberSelect, { current: maxPrice.toFixed(2), choices: maxChoices, label: strings.maxPriceName, notToday: strings.notToday, onChoose: chooseMax })
10330
10717
  }),
10331
10718
  ready: singlesReady(maxCell),
10332
- send: /* @__PURE__ */ jsx101(RoundSend, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
10719
+ send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.maxPriceDisplay(count, maxPrice), disabled: !maxCell || streaming, onClick: () => {
10333
10720
  if (maxCell) onSend(maxPriceAsk(maxCell, strings));
10334
10721
  } })
10335
10722
  }
10336
10723
  ),
10337
- /* @__PURE__ */ jsx101(
10724
+ /* @__PURE__ */ jsx104(
10338
10725
  AskRow,
10339
10726
  {
10340
10727
  icon: "\u{1F4C8}",
10341
10728
  ask: fillTemplate(strings.minPriceRow, {
10342
10729
  count: String(count),
10343
- price: /* @__PURE__ */ jsx101(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
10730
+ price: /* @__PURE__ */ jsx104(NumberSelect, { current: minPrice.toFixed(2), choices: minChoices, label: strings.minPriceName, notToday: strings.notToday, onChoose: chooseMin })
10344
10731
  }),
10345
10732
  ready: singlesReady(minCell),
10346
- send: /* @__PURE__ */ jsx101(RoundSend, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
10733
+ send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.minPriceDisplay(count, minPrice), disabled: !minCell || streaming, onClick: () => {
10347
10734
  if (minCell) onSend(minPriceAsk(minCell, strings));
10348
10735
  } })
10349
10736
  }
10350
10737
  ),
10351
- /* @__PURE__ */ jsx101(
10738
+ /* @__PURE__ */ jsx104(
10352
10739
  AskRow,
10353
10740
  {
10354
10741
  icon: "\u2728",
10355
10742
  ask: fillTemplate(strings.comboRow, {
10356
- legs: /* @__PURE__ */ jsx101(NumberSelect, { current: String(legs), choices: legChoicesFor(total), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseLegs }),
10357
- total: /* @__PURE__ */ jsx101(NumberSelect, { current: total.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseTotal })
10743
+ legs: /* @__PURE__ */ jsx104(NumberSelect, { current: String(legs), choices: legChoicesFor(total), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseLegs }),
10744
+ total: /* @__PURE__ */ jsx104(NumberSelect, { current: total.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseTotal })
10358
10745
  }),
10359
10746
  ready: comboReady(comboCell),
10360
- send: /* @__PURE__ */ jsx101(RoundSend, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
10747
+ send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.comboDisplay(legs, total), disabled: !comboCell || streaming, onClick: () => {
10361
10748
  if (comboCell) onSend(comboAsk(comboCell, strings));
10362
10749
  } })
10363
10750
  }
10364
10751
  ),
10365
- /* @__PURE__ */ jsx101(
10752
+ /* @__PURE__ */ jsx104(
10366
10753
  AskRow,
10367
10754
  {
10368
10755
  icon: "\u{1F3C6}",
10369
10756
  ask: fillTemplate(strings.bigComboRow, {
10370
- legs: /* @__PURE__ */ jsx101(NumberSelect, { current: String(bigLegs), choices: legChoicesFor(bigTotal), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseBigLegs }),
10371
- total: /* @__PURE__ */ jsx101(NumberSelect, { current: bigTotal.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseBigTotal })
10757
+ legs: /* @__PURE__ */ jsx104(NumberSelect, { current: String(bigLegs), choices: legChoicesFor(bigTotal), label: strings.matchesLabel, notToday: strings.notToday, lockEmpty: false, onChoose: chooseBigLegs }),
10758
+ total: /* @__PURE__ */ jsx104(NumberSelect, { current: bigTotal.toFixed(1), choices: totalChoices, label: strings.totalLabel, notToday: strings.notToday, onChoose: chooseBigTotal })
10372
10759
  }),
10373
10760
  ready: comboReady(bigCell),
10374
- send: /* @__PURE__ */ jsx101(RoundSend, { label: strings.send, display: strings.comboDisplay(bigLegs, bigTotal), disabled: !bigCell || streaming, onClick: () => {
10761
+ send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: strings.comboDisplay(bigLegs, bigTotal), disabled: !bigCell || streaming, onClick: () => {
10375
10762
  if (bigCell) onSend(comboAsk(bigCell, strings));
10376
10763
  } })
10377
10764
  }
10378
10765
  ),
10379
- markets.length > 0 && /* @__PURE__ */ jsx101(
10766
+ markets.length > 0 && /* @__PURE__ */ jsx104(
10380
10767
  AskRow,
10381
10768
  {
10382
10769
  icon: "\u26BD",
10383
10770
  ask: fillTemplate(strings.marketRow, {
10384
- market: /* @__PURE__ */ jsx101(ChoiceSelect, { currentIdx: marketIdx, sizeLabels: marketLabels, optionLabels: marketLabels, label: strings.marketName, onChoose: chooseMarket })
10771
+ market: /* @__PURE__ */ jsx104(ChoiceSelect, { currentIdx: marketIdx, sizeLabels: marketLabels, optionLabels: marketLabels, label: strings.marketName, onChoose: chooseMarket })
10385
10772
  }),
10386
10773
  ready: marketCell ? strings.readyCount(marketCell.count) : null,
10387
- send: /* @__PURE__ */ jsx101(RoundSend, { label: strings.send, display: marketCell ? marketDisplay(marketCell, strings) : "", disabled: !marketCell || streaming, onClick: () => {
10774
+ send: /* @__PURE__ */ jsx104(RoundSend, { label: strings.send, display: marketCell ? marketDisplay(marketCell, strings) : "", disabled: !marketCell || streaming, onClick: () => {
10388
10775
  if (marketCell) onSend(marketAsk(marketCell, strings));
10389
10776
  } })
10390
10777
  }
10391
10778
  ),
10392
- /* @__PURE__ */ jsx101("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
10779
+ /* @__PURE__ */ jsx104("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
10393
10780
  ] });
10394
10781
  }
10395
10782
  function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal, initialLegs, onSend, onClose }) {
10396
10783
  const totals = comboTotals(grid);
10397
10784
  const legChoices = comboLegChoices(grid);
10398
- const [start] = useState50(() => initialTotal === void 0 ? startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs) : null);
10399
- const [total, setTotal] = useState50(() => initialTotal !== void 0 ? nearest(totals, initialTotal) : start.total);
10400
- const [legs, setLegs] = useState50(() => {
10785
+ const [start] = useState52(() => initialTotal === void 0 ? startCombo(grid, totals, legChoices, START.comboTotal, START.comboLegs) : null);
10786
+ const [total, setTotal] = useState52(() => initialTotal !== void 0 ? nearest(totals, initialTotal) : start.total);
10787
+ const [legs, setLegs] = useState52(() => {
10401
10788
  if (initialTotal === void 0) return initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : start.legs;
10402
10789
  const from = initialLegs !== void 0 ? clampLegs(legChoices, initialLegs) : startValue(legChoices, START.comboLegs);
10403
10790
  return legsForTotal(grid, nearest(totals, initialTotal), from);
10404
10791
  });
10405
- const [announcement, setAnnouncement] = useState50("");
10792
+ const [announcement, setAnnouncement] = useState52("");
10406
10793
  const cell = findCombo(grid, total, legs);
10407
10794
  const minLegs = legChoices[0] ?? legs;
10408
10795
  const maxLegs = legChoices[legChoices.length - 1] ?? legs;
@@ -10413,29 +10800,29 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
10413
10800
  const d = strings.comboDisplay(nextLegs, nextTotal);
10414
10801
  setAnnouncement(findCombo(grid, nextTotal, nextLegs) ? d : `${d}. ${strings.unavailable}`);
10415
10802
  };
10416
- const footer = /* @__PURE__ */ jsx101(SendButton, { label: strings.send, display, disabled: !cell || streaming, onClick: () => {
10803
+ const footer = /* @__PURE__ */ jsx104(SendButton, { label: strings.send, display, disabled: !cell || streaming, onClick: () => {
10417
10804
  if (cell) onSend(comboAsk(cell, strings));
10418
10805
  } });
10419
- return /* @__PURE__ */ jsxs87(PresetToolModal, { title: strings.buildCombo, closeLabel: strings.close, onClose, footer, children: [
10420
- /* @__PURE__ */ jsxs87("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.totalLabel, children: [
10421
- /* @__PURE__ */ jsx101("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.totalLabel }),
10422
- /* @__PURE__ */ jsx101("div", { className: "ss-w-tool-chips", children: totals.map((t) => /* @__PURE__ */ jsx101("button", { type: "button", className: "ss-w-tool-chip", "aria-pressed": samePrice(t, total), onClick: () => choose(t, samePrice(t, total) ? legs : legsForTotal(grid, t, legs)), children: t.toFixed(1) }, t)) })
10806
+ return /* @__PURE__ */ jsxs88(PresetToolModal, { title: strings.buildCombo, closeLabel: strings.close, onClose, footer, children: [
10807
+ /* @__PURE__ */ jsxs88("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.totalLabel, children: [
10808
+ /* @__PURE__ */ jsx104("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.totalLabel }),
10809
+ /* @__PURE__ */ jsx104("div", { className: "ss-w-tool-chips", children: totals.map((t) => /* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-chip", "aria-pressed": samePrice(t, total), onClick: () => choose(t, samePrice(t, total) ? legs : legsForTotal(grid, t, legs)), children: t.toFixed(1) }, t)) })
10423
10810
  ] }),
10424
- /* @__PURE__ */ jsxs87("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.matchesLabel, children: [
10425
- /* @__PURE__ */ jsx101("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.matchesLabel }),
10426
- /* @__PURE__ */ jsxs87("div", { className: "ss-w-tool-stepper", children: [
10427
- /* @__PURE__ */ jsx101("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.fewerMatches, disabled: legs <= minLegs, onClick: () => choose(total, legs - 1), children: "\u2212" }),
10428
- /* @__PURE__ */ jsx101("span", { className: "ss-w-tool-count", children: legs }),
10429
- /* @__PURE__ */ jsx101("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.moreMatches, disabled: legs >= maxLegs, onClick: () => choose(total, legs + 1), children: "+" })
10811
+ /* @__PURE__ */ jsxs88("div", { className: "ss-w-tool-section", role: "group", "aria-label": strings.matchesLabel, children: [
10812
+ /* @__PURE__ */ jsx104("span", { className: "ss-w-tool-label", "aria-hidden": "true", children: strings.matchesLabel }),
10813
+ /* @__PURE__ */ jsxs88("div", { className: "ss-w-tool-stepper", children: [
10814
+ /* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.fewerMatches, disabled: legs <= minLegs, onClick: () => choose(total, legs - 1), children: "\u2212" }),
10815
+ /* @__PURE__ */ jsx104("span", { className: "ss-w-tool-count", children: legs }),
10816
+ /* @__PURE__ */ jsx104("button", { type: "button", className: "ss-w-tool-step", "aria-label": strings.moreMatches, disabled: legs >= maxLegs, onClick: () => choose(total, legs + 1), children: "+" })
10430
10817
  ] })
10431
10818
  ] }),
10432
- cell ? /* @__PURE__ */ jsx101(ComboPreview, { cell, formatKickoff }) : /* @__PURE__ */ jsx101(Unavailable, { text: strings.unavailable }),
10433
- /* @__PURE__ */ jsx101("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
10819
+ cell ? /* @__PURE__ */ jsx104(ComboPreview, { cell, formatKickoff }) : /* @__PURE__ */ jsx104(Unavailable, { text: strings.unavailable }),
10820
+ /* @__PURE__ */ jsx104("p", { className: "ss-w-vh", "aria-live": "polite", children: announcement })
10434
10821
  ] });
10435
10822
  }
10436
10823
 
10437
10824
  // src/usePresetDial.ts
10438
- import { useCallback as useCallback21, useEffect as useEffect32, useRef as useRef29, useState as useState51 } from "react";
10825
+ import { useCallback as useCallback21, useEffect as useEffect32, useRef as useRef29, useState as useState53 } from "react";
10439
10826
  function sendInFlight(messages, isStreaming) {
10440
10827
  const last = messages[messages.length - 1];
10441
10828
  return isStreaming && !!last && last.role === "assistant" && !last.done && !last.isGreeting;
@@ -10449,7 +10836,7 @@ function lastUserId(messages) {
10449
10836
  }
10450
10837
  var SCROLL_KEYS = /* @__PURE__ */ new Set(["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Home", "End", " "]);
10451
10838
  function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming, activeTab }) {
10452
- const [expanded, setExpanded] = useState51(() => !sendInFlight(messages, isStreaming));
10839
+ const [expanded, setExpanded] = useState53(() => !sendInFlight(messages, isStreaming));
10453
10840
  const fold = useCallback21(() => setExpanded(false), []);
10454
10841
  const toggle = useCallback21(() => setExpanded((e) => !e), []);
10455
10842
  const currentUserId = lastUserId(messages);
@@ -10532,10 +10919,10 @@ function markToolSeen() {
10532
10919
  }
10533
10920
 
10534
10921
  // src/components/ChatPanel.tsx
10535
- import { Fragment as Fragment25, jsx as jsx102, jsxs as jsxs88 } from "react/jsx-runtime";
10922
+ import { Fragment as Fragment25, jsx as jsx105, jsxs as jsxs89 } from "react/jsx-runtime";
10536
10923
  var FULLSCREEN_QUERY = "(max-width: 639px)";
10537
10924
  function useIsModal() {
10538
- const [modal, setModal] = useState52(false);
10925
+ const [modal, setModal] = useState54(false);
10539
10926
  useEffect33(() => {
10540
10927
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
10541
10928
  const mql = window.matchMedia(FULLSCREEN_QUERY);
@@ -10550,8 +10937,8 @@ var HIDDEN_LAYER_STYLE = { position: "absolute", inset: 0, visibility: "hidden",
10550
10937
  var SQUAD_LAYER_STYLE = { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 };
10551
10938
  function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, gamesResult, leaderboardResult, clubFixturesResult, clubStandingsResult, clubSquadResult, clubSquadStatsResult, clubPlayerDetailResult, loggedIn, conversation, presetGrid }) {
10552
10939
  const { state, close, stop, send, reset } = controller;
10553
- const [squadView, setSquadView] = useState52("roster");
10554
- const [selectedPlayerId, setSelectedPlayerId] = useState52(null);
10940
+ const [squadView, setSquadView] = useState54("roster");
10941
+ const [selectedPlayerId, setSelectedPlayerId] = useState54(null);
10555
10942
  const clearPlayerDetail = clubPlayerDetailResult?.clear;
10556
10943
  const fetchPlayerDetail = clubPlayerDetailResult?.fetch;
10557
10944
  const squadLayerRef = useRef30(null);
@@ -10605,8 +10992,8 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
10605
10992
  const limitRef = useRef30(null);
10606
10993
  const typedSendRef = useRef30(false);
10607
10994
  const focusAfterCloseRef = useRef30(null);
10608
- const [tool, setTool] = useState52(null);
10609
- const [toolSeen, setToolSeen] = useState52(readToolSeen);
10995
+ const [tool, setTool] = useState54(null);
10996
+ const [toolSeen, setToolSeen] = useState54(readToolSeen);
10610
10997
  const dial = usePresetDial({
10611
10998
  layerRef,
10612
10999
  dialRef,
@@ -10663,8 +11050,8 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
10663
11050
  focusAfterCloseRef.current = "composer";
10664
11051
  setTool(null);
10665
11052
  }, [tool, onChatTab, presetGrid]);
10666
- return /* @__PURE__ */ jsxs88("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
10667
- /* @__PURE__ */ jsx102(
11053
+ return /* @__PURE__ */ jsxs89("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
11054
+ /* @__PURE__ */ jsx105(
10668
11055
  ChatHeader,
10669
11056
  {
10670
11057
  onClose: close,
@@ -10677,7 +11064,7 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
10677
11064
  moreOptionsLabel: ui.moreOptions
10678
11065
  }
10679
11066
  ),
10680
- monitor && /* @__PURE__ */ jsx102(
11067
+ monitor && /* @__PURE__ */ jsx105(
10681
11068
  TabBar,
10682
11069
  {
10683
11070
  monitor,
@@ -10690,9 +11077,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
10690
11077
  clubEnabled: clubFixturesResult?.enabled ?? false
10691
11078
  }
10692
11079
  ),
10693
- /* @__PURE__ */ jsxs88("div", { ref: layerRef, className: "ss-w-chat-layer", "data-dial": presetGrid ? "" : void 0, style: onChatTab ? void 0 : HIDDEN_LAYER_STYLE, children: [
10694
- /* @__PURE__ */ jsx102(PresetToolsContext.Provider, { value: toolsValue, children: /* @__PURE__ */ jsx102(MessageList, { controller, ui, slip, onDashboardTap, monitor }) }),
10695
- showDial ? /* @__PURE__ */ jsx102(
11080
+ /* @__PURE__ */ jsxs89("div", { ref: layerRef, className: "ss-w-chat-layer", "data-dial": presetGrid ? "" : void 0, style: onChatTab ? void 0 : HIDDEN_LAYER_STYLE, children: [
11081
+ /* @__PURE__ */ jsx105(PresetToolsContext.Provider, { value: toolsValue, children: /* @__PURE__ */ jsx105(MessageList, { controller, ui, slip, onDashboardTap, monitor }) }),
11082
+ showDial ? /* @__PURE__ */ jsx105(
10696
11083
  PresetSpeedDial,
10697
11084
  {
10698
11085
  expanded: dial.expanded,
@@ -10704,21 +11091,21 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
10704
11091
  buttonRef: dialButtonRef
10705
11092
  }
10706
11093
  ) : null,
10707
- tool && presetGrid && onChatTab && !paused ? tool.kind === "numbers" ? /* @__PURE__ */ jsx102(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ jsx102(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
11094
+ tool && presetGrid && onChatTab && !paused ? tool.kind === "numbers" ? /* @__PURE__ */ jsx105(SetNumbersTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, onSend: sendAsk, onClose: closeTool }) : /* @__PURE__ */ jsx105(BuildComboTool, { grid: presetGrid, strings: ui.presets, streaming: state.isStreaming, formatKickoff, initialTotal: tool.total, initialLegs: tool.legs, onSend: sendAsk, onClose: closeTool }) : null
10708
11095
  ] }),
10709
- monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ jsx102(TodayPanel, { discovery, ui, monitor }),
10710
- monitor && monitor.activeTab === "following" && /* @__PURE__ */ jsx102(MatchesPanel, { monitor, ui, slip, onAsk: paused ? void 0 : handleAsk }),
10711
- monitor && monitor.activeTab === "odds" && /* @__PURE__ */ jsx102(OddsPanel, { monitor, ui, slip }),
10712
- monitor && monitor.activeTab === "fixtures" && /* @__PURE__ */ jsx102(Fixtures, { fixtures: clubFixturesResult?.fixtures ?? [], loading: clubFixturesResult?.loading ?? false, ui }),
10713
- monitor && monitor.activeTab === "standings" && /* @__PURE__ */ jsx102(Standings, { standings: clubStandingsResult?.data ?? null, loading: clubStandingsResult?.loading ?? false, ui }),
10714
- monitor && monitor.activeTab === "squad" && /* @__PURE__ */ jsxs88(Fragment25, { children: [
10715
- /* @__PURE__ */ jsx102(
11096
+ monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ jsx105(TodayPanel, { discovery, ui, monitor }),
11097
+ monitor && monitor.activeTab === "following" && /* @__PURE__ */ jsx105(MatchesPanel, { monitor, ui, slip, onAsk: paused ? void 0 : handleAsk }),
11098
+ monitor && monitor.activeTab === "odds" && /* @__PURE__ */ jsx105(OddsPanel, { monitor, ui, slip }),
11099
+ monitor && monitor.activeTab === "fixtures" && /* @__PURE__ */ jsx105(Fixtures, { fixtures: clubFixturesResult?.fixtures ?? [], loading: clubFixturesResult?.loading ?? false, ui }),
11100
+ monitor && monitor.activeTab === "standings" && /* @__PURE__ */ jsx105(Standings, { standings: clubStandingsResult?.data ?? null, loading: clubStandingsResult?.loading ?? false, ui }),
11101
+ monitor && monitor.activeTab === "squad" && /* @__PURE__ */ jsxs89(Fragment25, { children: [
11102
+ /* @__PURE__ */ jsx105(
10716
11103
  "div",
10717
11104
  {
10718
11105
  ref: squadLayerRef,
10719
11106
  style: selectedPlayerId === null ? SQUAD_LAYER_STYLE : HIDDEN_LAYER_STYLE,
10720
11107
  "aria-hidden": selectedPlayerId !== null ? true : void 0,
10721
- children: /* @__PURE__ */ jsx102(
11108
+ children: /* @__PURE__ */ jsx105(
10722
11109
  Squad,
10723
11110
  {
10724
11111
  squad: clubSquadResult?.data ?? null,
@@ -10728,14 +11115,17 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
10728
11115
  onToggleView: () => setSquadView((v) => v === "roster" ? "stats" : "roster"),
10729
11116
  stats: clubSquadStatsResult?.data ?? null,
10730
11117
  statsLoading: clubSquadStatsResult?.loading ?? false,
11118
+ seasonName: clubSquadStatsResult?.seasonName ?? null,
11119
+ competitionName: clubSquadStatsResult?.competitionName ?? null,
11120
+ matchesPlayed: clubSquadStatsResult?.matchesPlayed ?? null,
10731
11121
  onSelectPlayer: selectPlayer
10732
11122
  }
10733
11123
  )
10734
11124
  }
10735
11125
  ),
10736
- selectedPlayerId !== null && /* @__PURE__ */ jsx102(PlayerDetail, { detail: clubPlayerDetailResult?.data ?? null, loading: clubPlayerDetailResult?.loading ?? false, ui, seasonName: clubSquadStatsResult?.seasonName ?? null, onClose: closePlayer })
11126
+ selectedPlayerId !== null && /* @__PURE__ */ jsx105(PlayerDetail, { detail: clubPlayerDetailResult?.data ?? null, loading: clubPlayerDetailResult?.loading ?? false, ui, seasonName: clubSquadStatsResult?.seasonName ?? null, onClose: closePlayer })
10737
11127
  ] }),
10738
- monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ jsx102(
11128
+ monitor && monitor.activeTab === "games" && gamesResult && /* @__PURE__ */ jsx105(
10739
11129
  GamesPanel,
10740
11130
  {
10741
11131
  loggedIn: !!loggedIn,
@@ -10750,9 +11140,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
10750
11140
  }
10751
11141
  }
10752
11142
  ),
10753
- (!monitor || monitor.activeTab !== "games") && /* @__PURE__ */ jsxs88(Fragment25, { children: [
10754
- /* @__PURE__ */ jsx102("div", { ref: limitRef, className: "ss-w-limit", role: "status", tabIndex: -1, children: state.limit ? limitText(state.limit, ui) : null }),
10755
- paused ? null : /* @__PURE__ */ jsx102(
11143
+ (!monitor || monitor.activeTab !== "games") && /* @__PURE__ */ jsxs89(Fragment25, { children: [
11144
+ /* @__PURE__ */ jsx105("div", { ref: limitRef, className: "ss-w-limit", role: "status", tabIndex: -1, children: state.limit ? limitText(state.limit, ui) : null }),
11145
+ paused ? null : /* @__PURE__ */ jsx105(
10756
11146
  ChatInput,
10757
11147
  {
10758
11148
  ref: inputRef,
@@ -10771,9 +11161,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
10771
11161
  }
10772
11162
 
10773
11163
  // src/components/HostEventsProvider.tsx
10774
- import { jsx as jsx103 } from "react/jsx-runtime";
11164
+ import { jsx as jsx106 } from "react/jsx-runtime";
10775
11165
  function HostEventsProvider({ value, children }) {
10776
- return /* @__PURE__ */ jsx103(SlipStateContext.Provider, { value: value.slipState, children });
11166
+ return /* @__PURE__ */ jsx106(SlipStateContext.Provider, { value: value.slipState, children });
10777
11167
  }
10778
11168
 
10779
11169
  // src/styles/css.generated.ts
@@ -10784,7 +11174,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
10784
11174
  --ss-w-cta: #f5a623; --ss-w-cta-ink: #1b1300;
10785
11175
  --ss-w-ink: #14181d; --ss-w-faint: #6b7580; --ss-w-line: #e4e8ec;
10786
11176
  --ss-w-panel: #ffffff; --ss-w-bubble: #f3f5f7; --ss-w-nav: #0e1622;
10787
- --ss-w-pos: #1aa563; --ss-w-neg: #e0524b;
11177
+ --ss-w-pos: #1aa563; --ss-w-neg: #e0524b; --ss-w-warn: #c07a00;
10788
11178
  --ss-w-home: #3a63a8; --ss-w-away: #c8102e; --ss-w-track: #e9edf1;
10789
11179
  --ss-w-correct: #1f9d55; --ss-w-wrong: #b9bbc2;
10790
11180
  --ss-w-radius: 16px; --ss-w-offset-x: 20px; --ss-w-offset-y: 20px;
@@ -10796,7 +11186,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
10796
11186
  --ss-w-accent: #37c891; --ss-w-cta: #ffb638; --ss-w-cta-ink: #1b1300;
10797
11187
  --ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;
10798
11188
  --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;
10799
- --ss-w-pos: #37c891; --ss-w-neg: #f0655d;
11189
+ --ss-w-pos: #37c891; --ss-w-neg: #f0655d; --ss-w-warn: #e0a030;
10800
11190
  --ss-w-home: #5b83c8; --ss-w-away: #e8384f; --ss-w-track: #232d3a;
10801
11191
  --ss-w-correct: #37c86b; --ss-w-wrong: #3a3a41;
10802
11192
  }
@@ -10805,7 +11195,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
10805
11195
  --ss-w-accent: #37c891; --ss-w-cta: #ffb638; --ss-w-cta-ink: #1b1300;
10806
11196
  --ss-w-ink: #e8edf2; --ss-w-faint: #8b95a1;
10807
11197
  --ss-w-line: #2a3441; --ss-w-panel: #141b24; --ss-w-bubble: #1e2732; --ss-w-nav: #0a0f16;
10808
- --ss-w-pos: #37c891; --ss-w-neg: #f0655d;
11198
+ --ss-w-pos: #37c891; --ss-w-neg: #f0655d; --ss-w-warn: #e0a030;
10809
11199
  --ss-w-home: #5b83c8; --ss-w-away: #e8384f; --ss-w-track: #232d3a;
10810
11200
  --ss-w-correct: #37c86b; --ss-w-wrong: #3a3a41;
10811
11201
  }
@@ -11936,7 +12326,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
11936
12326
  .ss-w-sq-name { font-size: 13px; font-weight: 600; color: var(--ss-w-ink); }
11937
12327
  .ss-w-sq-name { flex: 1; min-width: 0; }
11938
12328
  .ss-w-sq-name-1 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
11939
- .ss-w-sq-seg { display: flex; flex: none; gap: 2px; margin: 10px 14px 0; padding: 2px; border-radius: var(--ss-w-radius); background: var(--ss-w-track); }
12329
+ .ss-w-sq-seg { display: flex; gap: 2px; padding: 2px; border-radius: var(--ss-w-radius); background: var(--ss-w-track); }
11940
12330
  .ss-w-sq-seg-btn { flex: 1; padding: 5px 8px; border: 0; border-radius: calc(var(--ss-w-radius) - 2px); background: transparent; font: inherit; font-size: 12px; font-weight: 600; color: var(--ss-w-faint); cursor: pointer; }
11941
12331
  .ss-w-sq-seg-btn[aria-pressed="true"] { background: var(--ss-w-panel); color: var(--ss-w-ink); }
11942
12332
  .ss-w-sq-seg-btn:focus-visible, .ss-w-sq-tap:focus-visible, .ss-w-pd-back:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: 1px; }
@@ -11944,15 +12334,95 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
11944
12334
  .ss-w-sq-col { flex: none; width: 40px; text-align: center; font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
11945
12335
  .ss-w-sq-head { border-bottom: 0; padding-bottom: 0; }
11946
12336
  .ss-w-sq-head .ss-w-sq-col { font-size: 10px; font-weight: 700; color: var(--ss-w-faint); }
11947
- .ss-w-pd-bar { flex: none; padding: 8px 14px 0; }
11948
- .ss-w-pd-back { padding: 4px 0; border: 0; background: transparent; font: inherit; font-size: 12px; font-weight: 600; color: var(--ss-w-accent); cursor: pointer; }
11949
- .ss-w-pd-name { font-size: 16px; font-weight: 700; color: var(--ss-w-ink); }
11950
- .ss-w-pd-sub { margin-top: 2px; font-size: 12px; color: var(--ss-w-faint); }
11951
- .ss-w-pd-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
11952
- .ss-w-pd-bio { grid-template-columns: repeat(2, 1fr); }
11953
- .ss-w-pd-field { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border: 1px solid var(--ss-w-line); border-radius: var(--ss-w-radius); }
11954
- .ss-w-pd-label { font-size: 10px; font-weight: 700; letter-spacing: .04em; color: var(--ss-w-faint); }
11955
- .ss-w-pd-value { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
12337
+ .ss-w-sq-stats { padding-top: 10px; gap: 10px; }
12338
+ .ss-w-sq-card { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; overflow: hidden; }
12339
+ .ss-w-sq-stats .ss-w-sq-row { display: grid; grid-template-columns: 1fr 26px 30px 36px 20px 20px 20px 20px 36px; gap: 0; padding: 7px 10px; font-size: 11px; }
12340
+ .ss-w-sq-card > :last-child { border-bottom: 0; }
12341
+ .ss-w-sq-pos, .ss-w-sq-c20, .ss-w-sq-c30, .ss-w-sq-c36 { text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 11px; font-weight: 400; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
12342
+ .ss-w-sq-stats .ss-w-sq-head { padding-bottom: 7px; border-bottom: 1px solid var(--ss-w-line); font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; color: var(--ss-w-faint); }
12343
+ .ss-w-sq-stats .ss-w-sq-head > span { font-size: 9px; font-weight: 700; color: var(--ss-w-faint); }
12344
+ .ss-w-sq-player { display: flex; align-items: center; gap: 6px; min-width: 0; }
12345
+ .ss-w-sq-badge { flex: none; width: 18px; height: 18px; border-radius: 6px; background: var(--ss-w-track); color: var(--ss-w-faint); font-size: 9px; font-weight: 700; display: flex; align-items: center; justify-content: center; }
12346
+ .ss-w-sq-stats .ss-w-sq-name { font-size: 11px; }
12347
+ .ss-w-sq-rtg { font-weight: 700; }
12348
+ .ss-w-sq-rtg-none { color: var(--ss-w-faint); font-weight: 400; }
12349
+ .ss-w-sq-stats .ss-w-pos-ink { color: var(--ss-w-pos); font-weight: 700; }
12350
+ .ss-w-sq-foot { padding: 0 2px; font-size: 10.5px; color: var(--ss-w-faint); }
12351
+ .ss-w-sq-bar { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 10px 14px 0; }
12352
+ .ss-w-sq-bar .ss-w-sq-seg { margin: 0; }
12353
+ .ss-w-sq-bar .ss-w-sq-seg:only-child { flex: 1; }
12354
+ .ss-w-sq-bar .ss-w-sq-seg:not(:only-child) { flex: none; }
12355
+ .ss-w-sq-eyebrow { flex: 1; min-width: 0; font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ss-w-faint); }
12356
+ @media (max-width: 429px) { .ss-w-sq-badge { display: none; } }
12357
+ @media (max-width: 359px) {
12358
+ .ss-w-sq-yr { display: none; }
12359
+ .ss-w-sq-stats .ss-w-sq-row { grid-template-columns: 1fr 26px 30px 36px 20px 20px 36px; }
12360
+ }
12361
+ .ss-w-pd-bar { flex: none; display: flex; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--ss-w-line); line-height: normal; }
12362
+ .ss-w-pd-back { display: flex; align-items: center; gap: 2px; min-height: 32px; padding: 8px 8px 8px 0; margin: -8px 0; border: 0; background: transparent; font: inherit; font-size: 12.5px; font-weight: 600; color: var(--ss-w-faint); cursor: pointer; }
12363
+ .ss-w-pd-back:hover { color: var(--ss-w-ink); }
12364
+ .ss-w-mon-list.ss-w-pd-list { padding: 16px; gap: 14px; line-height: normal; }
12365
+ .ss-w-pd-card { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; }
12366
+ .ss-w-pd-faint { color: var(--ss-w-faint); }
12367
+ .ss-w-pd-profile { display: flex; gap: 12px; padding: 14px; }
12368
+ .ss-w-pd-photo { flex: none; border-radius: 50%; border: 1px solid var(--ss-w-line); background: var(--ss-w-bubble); object-fit: cover; }
12369
+ .ss-w-pd-avatar { display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--ss-w-ink); }
12370
+ .ss-w-pd-profile-main { flex: 1; min-width: 0; }
12371
+ .ss-w-pd-name { font-size: 16px; font-weight: 800; color: var(--ss-w-ink); overflow-wrap: break-word; }
12372
+ .ss-w-pd-sub { margin-top: 1px; font-size: 12px; color: var(--ss-w-faint); }
12373
+ /* Two columns as on the board, collapsing to one when a column would drop under 80px (narrow phones). */
12374
+ .ss-w-pd-bio { display: grid; grid-template-columns: repeat(auto-fill, minmax(max(80px, calc((100% - 10px) / 2)), 1fr)); gap: 4px 10px; margin-top: 10px; font-size: 11.5px; }
12375
+ .ss-w-pd-bio-item { min-width: 0; overflow-wrap: break-word; }
12376
+ .ss-w-pd-pitch { position: relative; flex: none; width: 56px; height: 76px; border: 1px solid var(--ss-w-line); border-radius: 6px; background: var(--ss-w-track); }
12377
+ .ss-w-pd-pitch-dot { position: absolute; width: 11px; height: 11px; border-radius: 50%; background: var(--ss-w-accent); border: 2px solid var(--ss-w-nav); transform: translate(-50%, -50%); }
12378
+ .ss-w-pd-avail { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px; }
12379
+ .ss-w-pd-avail-text { min-width: 0; }
12380
+ .ss-w-pd-avail-next { font-size: 12.5px; font-weight: 700; }
12381
+ .ss-w-pd-avail-note { margin-top: 1px; font-size: 11px; color: var(--ss-w-faint); }
12382
+ .ss-w-pd-pill { flex: none; padding: 4px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; white-space: nowrap; }
12383
+ .ss-w-pd-pill--pos, .ss-w-pd-chip--pos { background: color-mix(in srgb, var(--ss-w-pos) 14%, transparent); color: var(--ss-w-pos); }
12384
+ .ss-w-pd-pill--warn, .ss-w-pd-chip--warn { background: color-mix(in srgb, var(--ss-w-warn) 14%, transparent); color: var(--ss-w-warn); }
12385
+ .ss-w-pd-pill--neg, .ss-w-pd-chip--neg { background: color-mix(in srgb, var(--ss-w-neg) 14%, transparent); color: var(--ss-w-neg); }
12386
+ .ss-w-pd-pill--draw { background: var(--ss-w-track); color: var(--ss-w-faint); }
12387
+ .ss-w-pd-eyebrow { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ss-w-faint); padding: 0 2px; }
12388
+ .ss-w-pd-eyebrow--block { margin-bottom: 8px; }
12389
+ .ss-w-pd-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
12390
+ .ss-w-pd-tile { min-width: 0; padding: 10px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; }
12391
+ .ss-w-pd-tile-label { font-size: 10.5px; color: var(--ss-w-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
12392
+ .ss-w-pd-tile-value { margin-top: 2px; font-size: 18px; font-weight: 800; font-variant-numeric: tabular-nums; }
12393
+ .ss-w-pd-pos-ink { color: var(--ss-w-pos); }
12394
+ /* Below 360px the board's 10px tile padding clips "Matches"/"Minutes" (43px) in a ~34px label box. */
12395
+ @media (max-width: 359px) {
12396
+ .ss-w-pd-tiles { gap: 6px; }
12397
+ .ss-w-pd-tile { padding: 10px 6px; }
12398
+ }
12399
+ .ss-w-pd-perf-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 2px; }
12400
+ .ss-w-pd-perf-head .ss-w-pd-eyebrow { flex: 1; min-width: 0; }
12401
+ .ss-w-pd-seg { flex: none; display: flex; gap: 2px; padding: 3px; border-radius: 999px; background: var(--ss-w-track); }
12402
+ .ss-w-pd-seg-btn { padding: 5px 12px; border: 0; border-radius: 999px; background: transparent; font: inherit; font-size: 11.5px; font-weight: 700; line-height: normal; white-space: nowrap; color: var(--ss-w-faint); cursor: pointer; }
12403
+ .ss-w-pd-seg-btn[aria-pressed="true"] { background: var(--ss-w-nav); color: #fff; }
12404
+ .ss-w-pd-seg-btn:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: 1px; }
12405
+ .ss-w-pd-perf-sub { margin-bottom: 10px; font-size: 11px; color: var(--ss-w-faint); }
12406
+ .ss-w-pd-perf-head + .ss-w-pd-perf-cards { margin-top: 10px; }
12407
+ .ss-w-pd-perf-cards { display: flex; flex-direction: column; gap: 8px; }
12408
+ .ss-w-pd-perf-card { padding: 14px; }
12409
+ .ss-w-pd-perf-group { margin-bottom: 10px; font-size: 12.5px; font-weight: 700; }
12410
+ .ss-w-pd-bar-row + .ss-w-pd-bar-row { margin-top: 12px; }
12411
+ .ss-w-pd-bar-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 5px; font-size: 12.5px; }
12412
+ .ss-w-pd-bar-label { min-width: 0; overflow-wrap: break-word; }
12413
+ .ss-w-pd-bar-value { flex: none; font-weight: 700; font-variant-numeric: tabular-nums; }
12414
+ .ss-w-pd-track { height: 6px; border-radius: 999px; background: var(--ss-w-track); overflow: hidden; }
12415
+ .ss-w-pd-fill { height: 100%; border-radius: 999px; }
12416
+ .ss-w-pd-fill--pos { background: var(--ss-w-pos); }
12417
+ .ss-w-pd-fill--warn { background: var(--ss-w-warn); }
12418
+ .ss-w-pd-fill--neg { background: var(--ss-w-neg); }
12419
+ .ss-w-pd-match { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto auto; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid var(--ss-w-line); }
12420
+ .ss-w-pd-match:last-child { border-bottom: none; }
12421
+ .ss-w-pd-match-date { font-size: 10.5px; color: var(--ss-w-faint); }
12422
+ .ss-w-pd-match-opp { font-size: 12.5px; font-weight: 600; overflow-wrap: break-word; }
12423
+ .ss-w-pd-match-sub { margin-top: 1px; font-size: 10.5px; color: var(--ss-w-faint); }
12424
+ .ss-w-pd-chip-empty { min-width: 30px; }
12425
+ .ss-w-pd-chip { min-width: 30px; padding: 3px 0; border-radius: 6px; text-align: center; font-size: 11.5px; font-weight: 800; font-variant-numeric: tabular-nums; }
11956
12426
  .ss-w-rec-list { margin: 0; padding: 0; list-style: none; }
11957
12427
  .ss-w-rec-value { flex: none; font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
11958
12428
  .ss-w-rec-since { font-size: 12px; color: var(--ss-w-faint); }
@@ -12559,7 +13029,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
12559
13029
  `;
12560
13030
 
12561
13031
  // src/StatsWidget.tsx
12562
- import { jsx as jsx104 } from "react/jsx-runtime";
13032
+ import { jsx as jsx107 } from "react/jsx-runtime";
12563
13033
  function buildClient(props) {
12564
13034
  try {
12565
13035
  if ("client" in props && props.client) {
@@ -12600,7 +13070,7 @@ function StatsWidget(props) {
12600
13070
  }, []);
12601
13071
  const convStorageKey = `ss-w-conv:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`;
12602
13072
  const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0, convStorageKey);
12603
- const [hasToday, setHasToday] = useState53(false);
13073
+ const [hasToday, setHasToday] = useState55(false);
12604
13074
  const liveCardWatches = useMemo6(() => {
12605
13075
  const seen = /* @__PURE__ */ new Set();
12606
13076
  const out = [];
@@ -12784,7 +13254,7 @@ function StatsWidget(props) {
12784
13254
  }, [built, ui.injectStyles]);
12785
13255
  if (!built) return null;
12786
13256
  const attrs = themeAttrs(ui);
12787
- return /* @__PURE__ */ jsx104(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ jsx104(HostEventsProvider, { value: hostEvents, children: /* @__PURE__ */ jsx104("div", { ref: rootRef, className: "ss-w-root", "data-ss-w-theme": attrs["data-ss-w-theme"], "data-ss-w-pos": attrs["data-ss-w-pos"], style: attrs.style, children: controller.state.isOpen ? /* @__PURE__ */ jsx104(
13257
+ return /* @__PURE__ */ jsx107(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ jsx107(HostEventsProvider, { value: hostEvents, children: /* @__PURE__ */ jsx107("div", { ref: rootRef, className: "ss-w-root", "data-ss-w-theme": attrs["data-ss-w-theme"], "data-ss-w-pos": attrs["data-ss-w-pos"], style: attrs.style, children: controller.state.isOpen ? /* @__PURE__ */ jsx107(
12788
13258
  ChatPanel,
12789
13259
  {
12790
13260
  controller,
@@ -12804,7 +13274,7 @@ function StatsWidget(props) {
12804
13274
  conversation: built?.conversation ?? null,
12805
13275
  presetGrid
12806
13276
  }
12807
- ) : /* @__PURE__ */ jsx104(
13277
+ ) : /* @__PURE__ */ jsx107(
12808
13278
  ChatFab,
12809
13279
  {
12810
13280
  label: ui.launcherLabel,