@sensiblestats/widget-react 0.17.0 → 0.19.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/CHANGELOG.md +17 -0
- package/dist/index.cjs +347 -277
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +294 -224
- package/dist/index.js.map +1 -1
- package/dist/styles.css +29 -24
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -435,7 +435,13 @@ function toMarketOddsVM(card) {
|
|
|
435
435
|
id: `${typeof card.matchId === "number" ? card.matchId : 0}:${str(card.marketDeveloperName) ?? ""}`,
|
|
436
436
|
market: str(card.marketLabel) ?? str(card.marketDeveloperName) ?? "",
|
|
437
437
|
fixture: home && away ? `${home} vs ${away}` : void 0,
|
|
438
|
+
homeTeamName: home,
|
|
439
|
+
awayTeamName: away,
|
|
440
|
+
homeCrest: str(card.homeTeamImagePath),
|
|
441
|
+
awayCrest: str(card.awayTeamImagePath),
|
|
442
|
+
competitionCrest: str(card.competitionImagePath),
|
|
438
443
|
competition: str(card.competitionName),
|
|
444
|
+
kickoffUtc: str(card.kickoffUtc),
|
|
439
445
|
bookmaker: rows.map((r) => str(r.bookmakerName)).find(Boolean),
|
|
440
446
|
updatedAt: updated.length > 0 ? updated[updated.length - 1] : void 0,
|
|
441
447
|
isLive: rows.some((r) => r.isLive === true),
|
|
@@ -615,7 +621,7 @@ function useChatStream(conversation, starterTexts, greetingMessage) {
|
|
|
615
621
|
const send = useCallback((text, opts) => {
|
|
616
622
|
const trimmed = text.trim();
|
|
617
623
|
if (!trimmed) return;
|
|
618
|
-
run({ message: trimmed, actionId: opts?.actionId }, opts?.displayText);
|
|
624
|
+
run({ message: trimmed, actionId: opts?.actionId, grounding: opts?.grounding }, opts?.displayText);
|
|
619
625
|
}, [run]);
|
|
620
626
|
const retry = useCallback(() => {
|
|
621
627
|
const last = stateRef.current.lastUserInput;
|
|
@@ -711,7 +717,7 @@ function ChatFab({ label, greeting, popupText, onOpen, onDismissPopup, dismissLa
|
|
|
711
717
|
}
|
|
712
718
|
|
|
713
719
|
// src/components/ChatPanel.tsx
|
|
714
|
-
import { useEffect as useEffect5, useState as
|
|
720
|
+
import { useEffect as useEffect5, useState as useState9 } from "react";
|
|
715
721
|
|
|
716
722
|
// src/components/ChatHeader.tsx
|
|
717
723
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
@@ -844,7 +850,7 @@ function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMore
|
|
|
844
850
|
}
|
|
845
851
|
|
|
846
852
|
// src/components/BettingInsightList.tsx
|
|
847
|
-
import { useState as
|
|
853
|
+
import { useState as useState4 } from "react";
|
|
848
854
|
|
|
849
855
|
// src/components/AddToSlipButton.tsx
|
|
850
856
|
import { useCallback as useCallback2, useState as useState2 } from "react";
|
|
@@ -967,53 +973,64 @@ function OddsMovementBadge({
|
|
|
967
973
|
);
|
|
968
974
|
}
|
|
969
975
|
|
|
976
|
+
// src/components/Crest.tsx
|
|
977
|
+
import { useState as useState3 } from "react";
|
|
978
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
979
|
+
function initials2(name) {
|
|
980
|
+
return (name ?? "").trim().slice(0, 1).toUpperCase() || "?";
|
|
981
|
+
}
|
|
982
|
+
function Crest2({ url, name, kind }) {
|
|
983
|
+
const cls = kind === "comp" ? "ss-w-bi-comp-logo" : "ss-w-bi-crest";
|
|
984
|
+
const [failed, setFailed] = useState3(false);
|
|
985
|
+
if (url && !failed) {
|
|
986
|
+
return /* @__PURE__ */ jsx10("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
987
|
+
}
|
|
988
|
+
return /* @__PURE__ */ jsx10("span", { className: `${cls} ss-w-bi-crest-mono`, "aria-hidden": "true", children: initials2(name) });
|
|
989
|
+
}
|
|
990
|
+
|
|
970
991
|
// src/components/BettingInsightList.tsx
|
|
971
|
-
import { Fragment, jsx as
|
|
992
|
+
import { Fragment, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
972
993
|
function StatRows2({ stats }) {
|
|
973
|
-
return /* @__PURE__ */
|
|
974
|
-
/* @__PURE__ */
|
|
975
|
-
/* @__PURE__ */
|
|
994
|
+
return /* @__PURE__ */ jsx11("div", { className: "ss-w-bi-rows", children: stats.map((s) => /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-row", children: [
|
|
995
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-bi-row-lbl", children: s.label }),
|
|
996
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-bi-row-num", children: s.value })
|
|
976
997
|
] }, `${s.label}:${s.value}`)) });
|
|
977
998
|
}
|
|
978
999
|
function ScopedStats({ scopes }) {
|
|
979
|
-
const [active, setActive] =
|
|
1000
|
+
const [active, setActive] = useState4(0);
|
|
980
1001
|
const current = scopes[active] ?? scopes[0] ?? { key: "", label: "", stats: [] };
|
|
981
1002
|
return /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-scoped", children: [
|
|
982
|
-
/* @__PURE__ */
|
|
983
|
-
/* @__PURE__ */
|
|
1003
|
+
/* @__PURE__ */ jsx11("div", { className: "ss-w-bi-scopes", role: "group", children: scopes.map((s, i) => /* @__PURE__ */ jsx11("button", { type: "button", className: "ss-w-bi-chip", "aria-pressed": i === active, onClick: () => setActive(i), children: s.label }, s.key)) }),
|
|
1004
|
+
/* @__PURE__ */ jsx11(StatRows2, { stats: current.stats }, current.key)
|
|
984
1005
|
] });
|
|
985
1006
|
}
|
|
986
1007
|
function hasStatsContent(it) {
|
|
987
1008
|
return !!it.scopes && it.scopes.length >= 2 || it.stats.length > 0;
|
|
988
1009
|
}
|
|
989
|
-
function
|
|
990
|
-
|
|
991
|
-
}
|
|
992
|
-
function Crest2({ url, name, kind }) {
|
|
993
|
-
const cls = kind === "comp" ? "ss-w-bi-comp-logo" : "ss-w-bi-crest";
|
|
994
|
-
if (url) return /* @__PURE__ */ jsx10("span", { className: cls, style: { backgroundImage: `url(${url})` }, "aria-hidden": "true" });
|
|
995
|
-
return /* @__PURE__ */ jsx10("span", { className: `${cls} ss-w-bi-crest-mono`, "aria-hidden": "true", children: initials2(name) });
|
|
996
|
-
}
|
|
997
|
-
function StatsDisclosure({ it, ui }) {
|
|
998
|
-
const [open, setOpen] = useState3(false);
|
|
1010
|
+
function ReasonStrip({ it, ui }) {
|
|
1011
|
+
const [open, setOpen] = useState4(false);
|
|
999
1012
|
const hasScopes = !!it.scopes && it.scopes.length >= 2;
|
|
1000
1013
|
const hasStats = hasStatsContent(it);
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1014
|
+
const hasText = !!it.text;
|
|
1015
|
+
if (!hasText && !hasStats) return null;
|
|
1016
|
+
const expandable = hasStats || (it.text?.length ?? 0) > 90;
|
|
1017
|
+
return /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-reason", children: [
|
|
1018
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-bi-chart", "aria-hidden": "true" }),
|
|
1019
|
+
/* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-reason-body", children: [
|
|
1020
|
+
hasText ? /* @__PURE__ */ jsx11("p", { className: `ss-w-bi-text${open ? "" : " ss-w-bi-text-clamp"}`, children: it.text }) : null,
|
|
1021
|
+
open && hasStats ? hasScopes ? /* @__PURE__ */ jsx11(ScopedStats, { scopes: it.scopes }) : /* @__PURE__ */ jsx11(StatRows2, { stats: it.stats }) : null
|
|
1022
|
+
] }),
|
|
1023
|
+
expandable ? /* @__PURE__ */ jsx11(
|
|
1004
1024
|
"button",
|
|
1005
1025
|
{
|
|
1006
1026
|
type: "button",
|
|
1007
|
-
className: "ss-w-bi-
|
|
1027
|
+
className: "ss-w-bi-expand",
|
|
1008
1028
|
"aria-expanded": open,
|
|
1029
|
+
"aria-label": open ? ui?.hideStats ?? "Hide stats" : ui?.showStats ?? "Show stats",
|
|
1009
1030
|
onClick: () => setOpen((v) => !v),
|
|
1010
|
-
children:
|
|
1011
|
-
/* @__PURE__ */ jsx10("span", { children: open ? ui?.hideStats ?? "Hide stats" : ui?.showStats ?? "Show stats" }),
|
|
1012
|
-
/* @__PURE__ */ jsx10("span", { className: `ss-w-bi-chev${open ? " ss-w-bi-chev-up" : ""}`, "aria-hidden": "true" })
|
|
1013
|
-
]
|
|
1031
|
+
children: /* @__PURE__ */ jsx11("span", { className: `ss-w-bi-arrow${open ? " ss-w-bi-arrow-open" : ""}`, "aria-hidden": "true" })
|
|
1014
1032
|
}
|
|
1015
|
-
)
|
|
1016
|
-
open ? hasScopes ? /* @__PURE__ */ jsx10(ScopedStats, { scopes: it.scopes }) : /* @__PURE__ */ jsx10(StatRows2, { stats: it.stats }) : null
|
|
1033
|
+
) : null
|
|
1017
1034
|
] });
|
|
1018
1035
|
}
|
|
1019
1036
|
function InsightCard({ it, ui, slip }) {
|
|
@@ -1021,16 +1038,15 @@ function InsightCard({ it, ui, slip }) {
|
|
|
1021
1038
|
const kickoff = it.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(it.kickoffUtc) : void 0;
|
|
1022
1039
|
const hasNamedTeams = !!it.homeTeamName && !!it.awayTeamName;
|
|
1023
1040
|
const showHeader = !!it.competition || live || !!kickoff;
|
|
1024
|
-
const showReason = !!it.text || hasStatsContent(it);
|
|
1025
1041
|
return /* @__PURE__ */ jsxs7("div", { className: "ss-w-binsight", children: [
|
|
1026
1042
|
showHeader ? /* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-header", children: [
|
|
1027
|
-
/* @__PURE__ */
|
|
1028
|
-
/* @__PURE__ */
|
|
1029
|
-
/* @__PURE__ */
|
|
1043
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-bi-header-left", children: it.competition ? /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
1044
|
+
/* @__PURE__ */ jsx11(Crest2, { kind: "comp", url: it.competitionCrest, name: it.competition }),
|
|
1045
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-bi-comp", children: it.competition })
|
|
1030
1046
|
] }) : null }),
|
|
1031
1047
|
/* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-header-right", children: [
|
|
1032
1048
|
live ? /* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-live", children: [
|
|
1033
|
-
/* @__PURE__ */
|
|
1049
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-bi-live-dot", "aria-hidden": "true" }),
|
|
1034
1050
|
ui?.liveLabel ?? "Live"
|
|
1035
1051
|
] }) : null,
|
|
1036
1052
|
kickoff ? /* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-kick", children: [
|
|
@@ -1041,85 +1057,100 @@ function InsightCard({ it, ui, slip }) {
|
|
|
1041
1057
|
] })
|
|
1042
1058
|
] }) : null,
|
|
1043
1059
|
/* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-body", children: [
|
|
1044
|
-
/* @__PURE__ */
|
|
1045
|
-
/* @__PURE__ */
|
|
1046
|
-
/* @__PURE__ */
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1049
|
-
/* @__PURE__ */
|
|
1050
|
-
] }) : it.fixture ? /* @__PURE__ */
|
|
1060
|
+
/* @__PURE__ */ jsx11("div", { className: "ss-w-bi-fixture", children: hasNamedTeams ? /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
1061
|
+
/* @__PURE__ */ jsx11(Crest2, { kind: "team", url: it.homeCrest, name: it.homeTeamName }),
|
|
1062
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-bi-team", children: it.homeTeamName }),
|
|
1063
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-bi-vs", "aria-hidden": "true", children: "vs" }),
|
|
1064
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-bi-team", children: it.awayTeamName }),
|
|
1065
|
+
/* @__PURE__ */ jsx11(Crest2, { kind: "team", url: it.awayCrest, name: it.awayTeamName })
|
|
1066
|
+
] }) : it.fixture ? /* @__PURE__ */ jsx11("span", { className: "ss-w-bi-fixture-txt", children: it.fixture }) : null }),
|
|
1051
1067
|
/* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-action", children: [
|
|
1052
1068
|
/* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-mkt", children: [
|
|
1053
|
-
/* @__PURE__ */
|
|
1054
|
-
it.selection ? /* @__PURE__ */
|
|
1069
|
+
/* @__PURE__ */ jsx11("span", { className: "ss-w-bi-market", children: it.market }),
|
|
1070
|
+
it.selection ? /* @__PURE__ */ jsx11("span", { className: "ss-w-bi-sel", children: it.selection }) : null
|
|
1055
1071
|
] }),
|
|
1056
|
-
it.isMarketFloor ? /* @__PURE__ */
|
|
1072
|
+
it.isMarketFloor ? /* @__PURE__ */ jsx11("span", { className: "ss-w-bi-floor", children: ui?.marketFloorLabel ?? "Market price \xB7 not a value pick" }) : null,
|
|
1057
1073
|
it.odds ? /* @__PURE__ */ jsxs7("span", { className: "ss-w-bi-odds", children: [
|
|
1058
|
-
/* @__PURE__ */
|
|
1059
|
-
/* @__PURE__ */
|
|
1060
|
-
/* @__PURE__ */
|
|
1061
|
-
it.bookmaker ? /* @__PURE__ */ jsx10("span", { className: "ss-w-bi-book", children: it.bookmaker }) : null
|
|
1074
|
+
/* @__PURE__ */ jsx11("b", { children: it.odds }),
|
|
1075
|
+
/* @__PURE__ */ jsx11(OddsMovementBadge, { previous: it.previousOdds, current: it.odds, direction: it.movementDirection, ui }),
|
|
1076
|
+
it.bookmaker ? /* @__PURE__ */ jsx11("span", { className: "ss-w-bi-book", children: it.bookmaker }) : null
|
|
1062
1077
|
] }) : null,
|
|
1063
|
-
/* @__PURE__ */
|
|
1078
|
+
/* @__PURE__ */ jsx11(AddToSlipButton, { it, slip, ui })
|
|
1064
1079
|
] })
|
|
1065
1080
|
] }),
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
/* @__PURE__ */ jsxs7("div", { className: "ss-w-bi-reason-body", children: [
|
|
1069
|
-
it.text ? /* @__PURE__ */ jsx10("p", { className: "ss-w-bi-text", children: it.text }) : null,
|
|
1070
|
-
/* @__PURE__ */ jsx10(StatsDisclosure, { it, ui })
|
|
1071
|
-
] })
|
|
1072
|
-
] }) : null,
|
|
1073
|
-
it.disclaimer ? /* @__PURE__ */ jsx10("p", { className: "ss-w-bi-disc", children: it.disclaimer }) : null
|
|
1081
|
+
/* @__PURE__ */ jsx11(ReasonStrip, { it, ui }),
|
|
1082
|
+
it.disclaimer ? /* @__PURE__ */ jsx11("p", { className: "ss-w-bi-disc", children: it.disclaimer }) : null
|
|
1074
1083
|
] });
|
|
1075
1084
|
}
|
|
1076
1085
|
function BettingInsightList({ insights, ui, slip }) {
|
|
1077
1086
|
if (!insights || insights.length === 0) return null;
|
|
1078
|
-
return /* @__PURE__ */
|
|
1087
|
+
return /* @__PURE__ */ jsx11("div", { className: "ss-w-binsights", children: insights.map((it) => /* @__PURE__ */ jsx11(InsightCard, { it, ui, slip }, it.id)) });
|
|
1079
1088
|
}
|
|
1080
1089
|
|
|
1081
1090
|
// src/components/MarketOddsCardList.tsx
|
|
1082
|
-
import { useState as
|
|
1083
|
-
import { jsx as
|
|
1091
|
+
import { useState as useState5 } from "react";
|
|
1092
|
+
import { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1084
1093
|
function OddsRow({ vm, row, ui, slip }) {
|
|
1085
1094
|
const selection = vm.addToSlipEnabled ? marketOddsRowToSlipSelection(vm, row, slip.conversationId) : null;
|
|
1086
1095
|
return /* @__PURE__ */ jsxs8("div", { className: "ss-w-mo-row", children: [
|
|
1087
|
-
/* @__PURE__ */
|
|
1088
|
-
/* @__PURE__ */
|
|
1089
|
-
/* @__PURE__ */
|
|
1090
|
-
/* @__PURE__ */
|
|
1096
|
+
/* @__PURE__ */ jsx12("span", { className: "ss-w-mo-sel", children: row.selection }),
|
|
1097
|
+
/* @__PURE__ */ jsx12(OddsMovementBadge, { previous: row.previousOdds, current: row.odds, direction: row.movementDirection, ui }),
|
|
1098
|
+
/* @__PURE__ */ jsx12("span", { className: "ss-w-mo-price", children: row.odds }),
|
|
1099
|
+
/* @__PURE__ */ jsx12(SlipButton, { selection, shownOdds: row.odds, marketName: vm.market, slip, ui })
|
|
1091
1100
|
] });
|
|
1092
1101
|
}
|
|
1093
1102
|
function MarketOddsCard({ vm, ui, slip }) {
|
|
1094
|
-
const [open, setOpen] =
|
|
1103
|
+
const [open, setOpen] = useState5(false);
|
|
1104
|
+
const kickoff = vm.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(vm.kickoffUtc) : void 0;
|
|
1105
|
+
const hasNamedTeams = !!vm.homeTeamName && !!vm.awayTeamName;
|
|
1106
|
+
const showHeader = !!vm.competition || vm.isLive || !!kickoff;
|
|
1095
1107
|
return /* @__PURE__ */ jsxs8("div", { className: "ss-w-mocard", children: [
|
|
1096
|
-
/* @__PURE__ */ jsxs8("div", { className: "ss-w-
|
|
1097
|
-
/* @__PURE__ */
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1108
|
+
showHeader ? /* @__PURE__ */ jsxs8("div", { className: "ss-w-bi-header", children: [
|
|
1109
|
+
/* @__PURE__ */ jsx12("span", { className: "ss-w-bi-header-left", children: vm.competition ? /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
1110
|
+
/* @__PURE__ */ jsx12(Crest2, { kind: "comp", url: vm.competitionCrest, name: vm.competition }),
|
|
1111
|
+
/* @__PURE__ */ jsx12("span", { className: "ss-w-bi-comp", children: vm.competition })
|
|
1112
|
+
] }) : null }),
|
|
1113
|
+
/* @__PURE__ */ jsxs8("span", { className: "ss-w-bi-header-right", children: [
|
|
1114
|
+
vm.isLive ? /* @__PURE__ */ jsxs8("span", { className: "ss-w-bi-live", children: [
|
|
1115
|
+
/* @__PURE__ */ jsx12("span", { className: "ss-w-bi-live-dot", "aria-hidden": "true" }),
|
|
1116
|
+
ui?.liveLabel ?? "Live"
|
|
1117
|
+
] }) : null,
|
|
1118
|
+
kickoff ? /* @__PURE__ */ jsxs8("span", { className: "ss-w-bi-kick", children: [
|
|
1119
|
+
kickoff.dayLabel,
|
|
1120
|
+
" ",
|
|
1121
|
+
kickoff.time
|
|
1122
|
+
] }) : null
|
|
1123
|
+
] })
|
|
1124
|
+
] }) : null,
|
|
1125
|
+
hasNamedTeams || vm.fixture || vm.market ? /* @__PURE__ */ jsxs8("div", { className: "ss-w-mo-sub", children: [
|
|
1126
|
+
hasNamedTeams ? /* @__PURE__ */ jsxs8("div", { className: "ss-w-bi-fixture", children: [
|
|
1127
|
+
/* @__PURE__ */ jsx12(Crest2, { kind: "team", url: vm.homeCrest, name: vm.homeTeamName }),
|
|
1128
|
+
/* @__PURE__ */ jsx12("span", { className: "ss-w-bi-team", children: vm.homeTeamName }),
|
|
1129
|
+
/* @__PURE__ */ jsx12("span", { className: "ss-w-bi-vs", "aria-hidden": "true", children: "vs" }),
|
|
1130
|
+
/* @__PURE__ */ jsx12("span", { className: "ss-w-bi-team", children: vm.awayTeamName }),
|
|
1131
|
+
/* @__PURE__ */ jsx12(Crest2, { kind: "team", url: vm.awayCrest, name: vm.awayTeamName })
|
|
1132
|
+
] }) : vm.fixture ? /* @__PURE__ */ jsx12("span", { className: "ss-w-mo-teams", children: vm.fixture }) : null,
|
|
1133
|
+
vm.market ? /* @__PURE__ */ jsx12("span", { className: "ss-w-mo-market", children: vm.market }) : null
|
|
1103
1134
|
] }) : null,
|
|
1104
1135
|
/* @__PURE__ */ jsxs8("div", { className: "ss-w-mo-rows", children: [
|
|
1105
|
-
vm.mainRows.map((row) => /* @__PURE__ */
|
|
1106
|
-
open ? vm.moreRows.map((row) => /* @__PURE__ */
|
|
1136
|
+
vm.mainRows.map((row) => /* @__PURE__ */ jsx12(OddsRow, { vm, row, ui, slip }, row.key)),
|
|
1137
|
+
open ? vm.moreRows.map((row) => /* @__PURE__ */ jsx12(OddsRow, { vm, row, ui, slip }, row.key)) : null
|
|
1107
1138
|
] }),
|
|
1108
|
-
vm.moreRows.length > 0 ? /* @__PURE__ */ jsxs8("button", { type: "button", className: "ss-w-
|
|
1109
|
-
/* @__PURE__ */
|
|
1110
|
-
/* @__PURE__ */
|
|
1139
|
+
vm.moreRows.length > 0 ? /* @__PURE__ */ jsxs8("button", { type: "button", className: "ss-w-mo-more", "aria-expanded": open, onClick: () => setOpen((v) => !v), children: [
|
|
1140
|
+
/* @__PURE__ */ jsx12("span", { children: open ? ui?.hideLines ?? "Hide lines" : `${ui?.moreLines ?? "More lines"} (${vm.moreRows.length})` }),
|
|
1141
|
+
/* @__PURE__ */ jsx12("span", { className: `ss-w-mo-more-chev${open ? " ss-w-mo-more-chev-up" : ""}`, "aria-hidden": "true" })
|
|
1111
1142
|
] }) : null,
|
|
1112
|
-
vm.bookmaker ? /* @__PURE__ */
|
|
1113
|
-
vm.disclaimer ? /* @__PURE__ */
|
|
1143
|
+
vm.bookmaker ? /* @__PURE__ */ jsx12("div", { className: "ss-w-mo-foot", children: /* @__PURE__ */ jsx12("span", { children: vm.bookmaker }) }) : null,
|
|
1144
|
+
vm.disclaimer ? /* @__PURE__ */ jsx12("p", { className: "ss-w-bi-disc", children: vm.disclaimer }) : null
|
|
1114
1145
|
] });
|
|
1115
1146
|
}
|
|
1116
1147
|
function MarketOddsCardList({ cards, ui, slip }) {
|
|
1117
1148
|
if (!cards || cards.length === 0) return null;
|
|
1118
|
-
return /* @__PURE__ */
|
|
1149
|
+
return /* @__PURE__ */ jsx12("div", { className: "ss-w-mocards", children: cards.map((vm) => /* @__PURE__ */ jsx12(MarketOddsCard, { vm, ui, slip }, vm.id)) });
|
|
1119
1150
|
}
|
|
1120
1151
|
|
|
1121
1152
|
// src/components/OddsMovementCard.tsx
|
|
1122
|
-
import { Fragment as
|
|
1153
|
+
import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1123
1154
|
function directionWord(vm, ui) {
|
|
1124
1155
|
if (vm.direction === "shortened") return ui?.oddsShortened ?? "shortened";
|
|
1125
1156
|
if (vm.direction === "drifted") return ui?.oddsDrifted ?? "drifted";
|
|
@@ -1131,16 +1162,16 @@ function OddsMovementCard({ vm, ui }) {
|
|
|
1131
1162
|
const aria = ui?.chartAria ? ui.chartAria(vm.opening, vm.current, word, vm.windowHours) : `Price movement over the last ${vm.windowHours} hours: opened at ${vm.opening}, currently ${vm.current}${drift}.`;
|
|
1132
1163
|
return /* @__PURE__ */ jsxs9("div", { className: "ss-w-omcard", children: [
|
|
1133
1164
|
/* @__PURE__ */ jsxs9("div", { className: "ss-w-om-head", children: [
|
|
1134
|
-
/* @__PURE__ */
|
|
1135
|
-
/* @__PURE__ */
|
|
1165
|
+
/* @__PURE__ */ jsx13("span", { className: "ss-w-om-market", children: vm.market }),
|
|
1166
|
+
/* @__PURE__ */ jsx13("span", { className: "ss-w-om-tag", children: ui?.priceMovement ?? "Price movement" })
|
|
1136
1167
|
] }),
|
|
1137
1168
|
vm.fixture ? /* @__PURE__ */ jsxs9("div", { className: "ss-w-om-fixture", children: [
|
|
1138
|
-
/* @__PURE__ */
|
|
1139
|
-
vm.competition ? /* @__PURE__ */
|
|
1169
|
+
/* @__PURE__ */ jsx13("span", { children: vm.fixture }),
|
|
1170
|
+
vm.competition ? /* @__PURE__ */ jsx13("span", { className: "ss-w-om-comp", children: vm.competition }) : null
|
|
1140
1171
|
] }) : null,
|
|
1141
|
-
/* @__PURE__ */
|
|
1142
|
-
/* @__PURE__ */
|
|
1143
|
-
vm.geometry === null ? /* @__PURE__ */
|
|
1172
|
+
/* @__PURE__ */ jsx13("div", { className: "ss-w-om-sel", children: vm.selection }),
|
|
1173
|
+
/* @__PURE__ */ jsx13(OddsMovementBadge, { previous: vm.opening, current: vm.current, direction: vm.direction, ui }),
|
|
1174
|
+
vm.geometry === null ? /* @__PURE__ */ jsx13("div", { className: "ss-w-om-empty", children: vm.observationCount === 1 ? ui?.singlePricePoint ?? "Only one price recorded so far for this selection." : ui?.notEnoughHistory ?? "No price history recorded yet for this selection." }) : /* @__PURE__ */ jsxs9(
|
|
1144
1175
|
"svg",
|
|
1145
1176
|
{
|
|
1146
1177
|
className: "ss-w-om-chart",
|
|
@@ -1150,15 +1181,15 @@ function OddsMovementCard({ vm, ui }) {
|
|
|
1150
1181
|
"aria-label": aria,
|
|
1151
1182
|
children: [
|
|
1152
1183
|
vm.geometry.gridlines.map((g) => /* @__PURE__ */ jsxs9("g", { children: [
|
|
1153
|
-
/* @__PURE__ */
|
|
1154
|
-
/* @__PURE__ */
|
|
1184
|
+
/* @__PURE__ */ jsx13("line", { className: "ss-w-om-grid", x1: 40, y1: g.y, x2: CHART_VIEW_W - 8, y2: g.y }),
|
|
1185
|
+
/* @__PURE__ */ jsx13("text", { className: "ss-w-om-ylab", x: 34, y: g.y + 3, textAnchor: "end", children: g.price.toFixed(2) })
|
|
1155
1186
|
] }, g.price)),
|
|
1156
|
-
/* @__PURE__ */
|
|
1157
|
-
vm.geometry.markers.map((m, i) => /* @__PURE__ */
|
|
1158
|
-
ui?.chartTimeLabel ? /* @__PURE__ */ jsxs9(
|
|
1159
|
-
/* @__PURE__ */
|
|
1160
|
-
/* @__PURE__ */
|
|
1161
|
-
] }) : /* @__PURE__ */
|
|
1187
|
+
/* @__PURE__ */ jsx13("path", { className: "ss-w-om-line", d: vm.geometry.path, fill: "none" }),
|
|
1188
|
+
vm.geometry.markers.map((m, i) => /* @__PURE__ */ jsx13("circle", { className: "ss-w-om-dot", cx: m.x, cy: m.y, r: 2.5 }, i)),
|
|
1189
|
+
ui?.chartTimeLabel ? /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
1190
|
+
/* @__PURE__ */ jsx13("text", { className: "ss-w-om-xlab", x: 40, y: CHART_VIEW_H - 8, textAnchor: "start", children: ui.chartTimeLabel(vm.geometry.startMs) }),
|
|
1191
|
+
/* @__PURE__ */ jsx13("text", { className: "ss-w-om-xlab", x: CHART_VIEW_W - 8, y: CHART_VIEW_H - 8, textAnchor: "end", children: ui.chartTimeLabel(vm.geometry.endMs) })
|
|
1192
|
+
] }) : /* @__PURE__ */ jsx13("text", { className: "ss-w-om-xlab", x: 40, y: CHART_VIEW_H - 8, children: ui?.movementWindow ? ui.movementWindow(vm.windowHours) : `Last ${vm.windowHours}h` })
|
|
1162
1193
|
]
|
|
1163
1194
|
}
|
|
1164
1195
|
),
|
|
@@ -1166,66 +1197,66 @@ function OddsMovementCard({ vm, ui }) {
|
|
|
1166
1197
|
/* @__PURE__ */ jsxs9("span", { children: [
|
|
1167
1198
|
ui?.openingLabel ?? "Opening",
|
|
1168
1199
|
" ",
|
|
1169
|
-
/* @__PURE__ */
|
|
1200
|
+
/* @__PURE__ */ jsx13("b", { children: vm.opening })
|
|
1170
1201
|
] }),
|
|
1171
1202
|
/* @__PURE__ */ jsxs9("span", { children: [
|
|
1172
1203
|
ui?.currentLabel ?? "Current",
|
|
1173
1204
|
" ",
|
|
1174
|
-
/* @__PURE__ */
|
|
1205
|
+
/* @__PURE__ */ jsx13("b", { children: vm.current })
|
|
1175
1206
|
] })
|
|
1176
1207
|
] }),
|
|
1177
|
-
vm.bookmaker ? /* @__PURE__ */
|
|
1178
|
-
vm.excludedCount > 0 ? /* @__PURE__ */
|
|
1179
|
-
vm.isSuspended ? /* @__PURE__ */
|
|
1180
|
-
vm.disclaimer ? /* @__PURE__ */
|
|
1208
|
+
vm.bookmaker ? /* @__PURE__ */ jsx13("div", { className: "ss-w-om-foot", children: /* @__PURE__ */ jsx13("span", { children: vm.bookmaker }) }) : null,
|
|
1209
|
+
vm.excludedCount > 0 ? /* @__PURE__ */ jsx13("div", { className: "ss-w-om-excl", children: ui?.excludedSuspended ? ui.excludedSuspended(vm.excludedCount) : `${vm.excludedCount} suspended price(s) excluded from this chart.` }) : null,
|
|
1210
|
+
vm.isSuspended ? /* @__PURE__ */ jsx13("div", { className: "ss-w-om-susp", children: ui?.selectionSuspended ?? "This selection is not currently available to bet." }) : null,
|
|
1211
|
+
vm.disclaimer ? /* @__PURE__ */ jsx13("div", { className: "ss-w-om-disc", children: vm.disclaimer }) : null
|
|
1181
1212
|
] });
|
|
1182
1213
|
}
|
|
1183
1214
|
function OddsMovementCardList({ cards, ui }) {
|
|
1184
1215
|
if (!cards || cards.length === 0) return null;
|
|
1185
|
-
return /* @__PURE__ */
|
|
1216
|
+
return /* @__PURE__ */ jsx13("div", { className: "ss-w-omcards", children: cards.map((vm) => /* @__PURE__ */ jsx13(OddsMovementCard, { vm, ui }, vm.id)) });
|
|
1186
1217
|
}
|
|
1187
1218
|
|
|
1188
1219
|
// src/components/ActionButtons.tsx
|
|
1189
|
-
import { Fragment as
|
|
1220
|
+
import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1190
1221
|
function ActionButtons({ actions, loading, disabled, onAct }) {
|
|
1191
1222
|
if (actions.length === 0 && !loading) return null;
|
|
1192
1223
|
return /* @__PURE__ */ jsxs10("div", { className: "ss-w-actions", children: [
|
|
1193
|
-
actions.map((a, i) => /* @__PURE__ */
|
|
1194
|
-
actions.length === 0 && loading ? /* @__PURE__ */ jsxs10(
|
|
1195
|
-
/* @__PURE__ */
|
|
1196
|
-
/* @__PURE__ */
|
|
1224
|
+
actions.map((a, i) => /* @__PURE__ */ jsx14("button", { type: "button", className: "ss-w-abtn", disabled, onClick: () => onAct(a), children: a.label }, `${a.label}-${i}`)),
|
|
1225
|
+
actions.length === 0 && loading ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
1226
|
+
/* @__PURE__ */ jsx14("span", { className: "ss-w-abtn-shimmer" }),
|
|
1227
|
+
/* @__PURE__ */ jsx14("span", { className: "ss-w-abtn-shimmer" })
|
|
1197
1228
|
] }) : null
|
|
1198
1229
|
] });
|
|
1199
1230
|
}
|
|
1200
1231
|
|
|
1201
1232
|
// src/components/dashboard/DashboardTile.tsx
|
|
1202
|
-
import { jsx as
|
|
1233
|
+
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1203
1234
|
var MAX_CRESTS = 3;
|
|
1204
1235
|
function DashboardTile({ tile, onTap }) {
|
|
1205
1236
|
const spanClass = tile.span === "full" ? "ss-w-dash-tile--full" : "ss-w-dash-tile--half";
|
|
1206
1237
|
const crests = (tile.imageUrls ?? []).slice(0, MAX_CRESTS);
|
|
1207
1238
|
const hasMeta = Boolean(tile.badgeText) || crests.length > 0;
|
|
1208
1239
|
return /* @__PURE__ */ jsxs11("button", { type: "button", className: `ss-w-dash-tile ${spanClass}`, onClick: onTap, children: [
|
|
1209
|
-
/* @__PURE__ */
|
|
1240
|
+
/* @__PURE__ */ jsx15("span", { className: "ss-w-dash-tile-icon", children: /* @__PURE__ */ jsx15(DashboardIcon, { name: tile.icon }) }),
|
|
1210
1241
|
/* @__PURE__ */ jsxs11("span", { className: "ss-w-dash-tile-body", children: [
|
|
1211
|
-
/* @__PURE__ */
|
|
1212
|
-
tile.subtitle ? /* @__PURE__ */
|
|
1242
|
+
/* @__PURE__ */ jsx15("span", { className: "ss-w-dash-tile-title", children: tile.title }),
|
|
1243
|
+
tile.subtitle ? /* @__PURE__ */ jsx15("span", { className: "ss-w-dash-tile-subtitle", children: tile.subtitle }) : null,
|
|
1213
1244
|
hasMeta ? (
|
|
1214
1245
|
// Badge + crests sit on their own row, below the title, instead of sharing the
|
|
1215
1246
|
// icon/chevron row -- at the half-span tile's ~180px width a nowrap badge alone
|
|
1216
1247
|
// (~70px) left the title column at ~22px and forced character-by-character wrapping.
|
|
1217
1248
|
/* @__PURE__ */ jsxs11("span", { className: "ss-w-dash-tile-meta", children: [
|
|
1218
|
-
tile.badgeText ? /* @__PURE__ */
|
|
1219
|
-
crests.length > 0 ? /* @__PURE__ */
|
|
1249
|
+
tile.badgeText ? /* @__PURE__ */ jsx15("span", { className: "ss-w-dash-tile-badge", children: tile.badgeText }) : null,
|
|
1250
|
+
crests.length > 0 ? /* @__PURE__ */ jsx15("span", { className: "ss-w-dash-tile-crests", children: crests.map((url, i) => /* @__PURE__ */ jsx15("span", { className: "ss-w-dash-tile-crest", style: { backgroundImage: `url(${url})` }, "aria-hidden": "true" }, `${url}-${i}`)) }) : null
|
|
1220
1251
|
] })
|
|
1221
1252
|
) : null
|
|
1222
1253
|
] }),
|
|
1223
|
-
/* @__PURE__ */
|
|
1254
|
+
/* @__PURE__ */ jsx15("span", { className: "ss-w-dash-tile-chevron", children: /* @__PURE__ */ jsx15(ChevronIcon, {}) })
|
|
1224
1255
|
] });
|
|
1225
1256
|
}
|
|
1226
1257
|
|
|
1227
1258
|
// src/components/dashboard/GreetingDashboard.tsx
|
|
1228
|
-
import { jsx as
|
|
1259
|
+
import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1229
1260
|
var LAYOUT_CLASSES = {
|
|
1230
1261
|
market: "ss-w-dash--market",
|
|
1231
1262
|
goal: "ss-w-dash--goal",
|
|
@@ -1237,35 +1268,35 @@ function layoutClass(layout) {
|
|
|
1237
1268
|
function GreetingDashboard({ dashboard, onTap }) {
|
|
1238
1269
|
return /* @__PURE__ */ jsxs12("div", { className: `ss-w-dash ${layoutClass(dashboard.layout)}`, children: [
|
|
1239
1270
|
/* @__PURE__ */ jsxs12("div", { className: "ss-w-dash-head", children: [
|
|
1240
|
-
/* @__PURE__ */
|
|
1241
|
-
dashboard.subtitle ? /* @__PURE__ */
|
|
1271
|
+
/* @__PURE__ */ jsx16("span", { className: "ss-w-dash-title", children: dashboard.title }),
|
|
1272
|
+
dashboard.subtitle ? /* @__PURE__ */ jsx16("span", { className: "ss-w-dash-subtitle", children: dashboard.subtitle }) : null
|
|
1242
1273
|
] }),
|
|
1243
|
-
/* @__PURE__ */
|
|
1244
|
-
dashboard.footerTip ? /* @__PURE__ */
|
|
1274
|
+
/* @__PURE__ */ jsx16("div", { className: "ss-w-dash-grid", children: dashboard.tiles.map((t, i) => /* @__PURE__ */ jsx16(DashboardTile, { tile: t, onTap: () => onTap(t, i) }, `${t.title}-${i}`)) }),
|
|
1275
|
+
dashboard.footerTip ? /* @__PURE__ */ jsx16("span", { className: "ss-w-dash-foot", children: dashboard.footerTip }) : null
|
|
1245
1276
|
] });
|
|
1246
1277
|
}
|
|
1247
1278
|
|
|
1248
1279
|
// src/components/club-dashboard/GreetingHeaderBlock.tsx
|
|
1249
|
-
import { jsx as
|
|
1280
|
+
import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1250
1281
|
function GreetingHeaderBlock({ block }) {
|
|
1251
1282
|
return /* @__PURE__ */ jsxs13("div", { className: "ss-w-cdash-greeting", children: [
|
|
1252
|
-
/* @__PURE__ */
|
|
1253
|
-
/* @__PURE__ */
|
|
1283
|
+
/* @__PURE__ */ jsx17("div", { className: "ss-w-cdash-greeting-title", children: block.title }),
|
|
1284
|
+
/* @__PURE__ */ jsx17("div", { className: "ss-w-cdash-greeting-subtitle", children: block.subtitle })
|
|
1254
1285
|
] });
|
|
1255
1286
|
}
|
|
1256
1287
|
|
|
1257
1288
|
// src/components/club-dashboard/FixtureHeroBlock.tsx
|
|
1258
|
-
import { useState as
|
|
1259
|
-
import { jsx as
|
|
1289
|
+
import { useState as useState6 } from "react";
|
|
1290
|
+
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1260
1291
|
function initials3(name) {
|
|
1261
1292
|
return name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
|
|
1262
1293
|
}
|
|
1263
1294
|
function Crest3({ url, name }) {
|
|
1264
|
-
const [broken, setBroken] =
|
|
1295
|
+
const [broken, setBroken] = useState6(false);
|
|
1265
1296
|
if (!url || broken) {
|
|
1266
|
-
return /* @__PURE__ */
|
|
1297
|
+
return /* @__PURE__ */ jsx18("span", { className: "ss-w-cdash-crest ss-w-cdash-crest--fallback", "aria-hidden": "true", children: initials3(name) });
|
|
1267
1298
|
}
|
|
1268
|
-
return /* @__PURE__ */
|
|
1299
|
+
return /* @__PURE__ */ jsx18("img", { className: "ss-w-cdash-crest", src: url, alt: "", "aria-hidden": "true", onError: () => setBroken(true) });
|
|
1269
1300
|
}
|
|
1270
1301
|
function FixtureHeroBlock({
|
|
1271
1302
|
block,
|
|
@@ -1274,67 +1305,101 @@ function FixtureHeroBlock({
|
|
|
1274
1305
|
}) {
|
|
1275
1306
|
return /* @__PURE__ */ jsxs14("div", { className: "ss-w-cdash-fixture", children: [
|
|
1276
1307
|
/* @__PURE__ */ jsxs14("div", { className: "ss-w-cdash-tie", children: [
|
|
1277
|
-
/* @__PURE__ */
|
|
1278
|
-
/* @__PURE__ */
|
|
1279
|
-
/* @__PURE__ */
|
|
1280
|
-
/* @__PURE__ */
|
|
1281
|
-
/* @__PURE__ */
|
|
1308
|
+
/* @__PURE__ */ jsx18(Crest3, { url: block.homeCrestUrl, name: block.homeName }),
|
|
1309
|
+
/* @__PURE__ */ jsx18("span", { className: "ss-w-cdash-team", children: block.homeName }),
|
|
1310
|
+
/* @__PURE__ */ jsx18("span", { className: "ss-w-cdash-vs", children: "v" }),
|
|
1311
|
+
/* @__PURE__ */ jsx18("span", { className: "ss-w-cdash-team", children: block.awayName }),
|
|
1312
|
+
/* @__PURE__ */ jsx18(Crest3, { url: block.awayCrestUrl, name: block.awayName })
|
|
1282
1313
|
] }),
|
|
1283
1314
|
/* @__PURE__ */ jsxs14("div", { className: "ss-w-cdash-fixture-meta", children: [
|
|
1284
|
-
/* @__PURE__ */
|
|
1285
|
-
block.venue ? /* @__PURE__ */
|
|
1286
|
-
block.competition ? /* @__PURE__ */
|
|
1315
|
+
/* @__PURE__ */ jsx18("span", { className: "ss-w-cdash-kickoff", children: ui.clubKickoff(block.kickoffUnix * 1e3) }),
|
|
1316
|
+
block.venue ? /* @__PURE__ */ jsx18("span", { className: "ss-w-cdash-venue", children: block.venue }) : null,
|
|
1317
|
+
block.competition ? /* @__PURE__ */ jsx18("span", { className: "ss-w-cdash-comp", children: block.competition }) : null
|
|
1287
1318
|
] }),
|
|
1288
|
-
/* @__PURE__ */
|
|
1319
|
+
/* @__PURE__ */ jsx18("button", { type: "button", className: "ss-w-cdash-cta", onClick: () => onAction(block.ctaActionValue, void 0, block.ctaLabel), children: block.ctaLabel })
|
|
1289
1320
|
] });
|
|
1290
1321
|
}
|
|
1291
1322
|
|
|
1292
1323
|
// src/components/club-dashboard/FormGuideBlock.tsx
|
|
1293
|
-
import { jsx as
|
|
1324
|
+
import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1294
1325
|
function FormGuideBlock({ block }) {
|
|
1295
1326
|
if (block.rows.length === 0) return null;
|
|
1296
|
-
return /* @__PURE__ */
|
|
1327
|
+
return /* @__PURE__ */ jsx19("div", { className: "ss-w-cdash-form", children: block.rows.map((row) => /* @__PURE__ */ jsxs15("div", { className: "ss-w-cdash-form-row", children: [
|
|
1297
1328
|
/* @__PURE__ */ jsxs15("span", { className: "ss-w-cdash-form-name", children: [
|
|
1298
1329
|
row.name,
|
|
1299
1330
|
row.position != null ? ` #${row.position}` : ""
|
|
1300
1331
|
] }),
|
|
1301
|
-
/* @__PURE__ */
|
|
1332
|
+
/* @__PURE__ */ jsx19("span", { className: "ss-w-cdash-form-pills", children: row.last5.map((r, i) => /* @__PURE__ */ jsx19("span", { className: `ss-w-cdash-pill ss-w-cdash-pill--${r.toLowerCase()}`, children: r }, i)) })
|
|
1302
1333
|
] }, row.name)) });
|
|
1303
1334
|
}
|
|
1304
1335
|
|
|
1305
1336
|
// src/components/club-dashboard/MatchPreviewBlock.tsx
|
|
1306
|
-
import { jsx as
|
|
1337
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1307
1338
|
function MatchPreviewBlock({
|
|
1308
1339
|
block,
|
|
1309
1340
|
ui,
|
|
1310
1341
|
onAction
|
|
1311
1342
|
}) {
|
|
1312
|
-
if (block.
|
|
1343
|
+
if (block.facts.length === 0) return null;
|
|
1313
1344
|
const heading = ui.clubMatchPreviewHeading;
|
|
1314
|
-
return /* @__PURE__ */ jsxs16("
|
|
1315
|
-
/* @__PURE__ */
|
|
1316
|
-
block.
|
|
1345
|
+
return /* @__PURE__ */ jsxs16("div", { className: "ss-w-cdash-lines", children: [
|
|
1346
|
+
/* @__PURE__ */ jsx20("span", { className: "ss-w-cdash-lines-heading", children: heading }),
|
|
1347
|
+
block.facts.map(
|
|
1348
|
+
(f, i) => f.entityRef ? /* @__PURE__ */ jsxs16(
|
|
1349
|
+
"button",
|
|
1350
|
+
{
|
|
1351
|
+
type: "button",
|
|
1352
|
+
className: "ss-w-cdash-fact",
|
|
1353
|
+
onClick: () => onAction(f.question ?? f.sentence, { ...f.entityRef, subject: f.sentence, personaHint: "club" }),
|
|
1354
|
+
children: [
|
|
1355
|
+
f.sentence,
|
|
1356
|
+
f.label ? /* @__PURE__ */ jsxs16("span", { className: "ss-w-cdash-fact-label", children: [
|
|
1357
|
+
" ",
|
|
1358
|
+
f.label
|
|
1359
|
+
] }) : null
|
|
1360
|
+
]
|
|
1361
|
+
},
|
|
1362
|
+
i
|
|
1363
|
+
) : /* @__PURE__ */ jsx20("p", { children: f.sentence }, i)
|
|
1364
|
+
)
|
|
1317
1365
|
] });
|
|
1318
1366
|
}
|
|
1319
1367
|
|
|
1320
1368
|
// src/components/club-dashboard/TeamDnaBlock.tsx
|
|
1321
|
-
import { jsx as
|
|
1369
|
+
import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1322
1370
|
function TeamDnaBlock({
|
|
1323
1371
|
block,
|
|
1324
1372
|
ui,
|
|
1325
1373
|
onAction
|
|
1326
1374
|
}) {
|
|
1327
|
-
if (block.
|
|
1375
|
+
if (block.facts.length === 0) return null;
|
|
1328
1376
|
const heading = ui.clubTeamDnaHeading;
|
|
1329
|
-
return /* @__PURE__ */ jsxs17("
|
|
1330
|
-
/* @__PURE__ */
|
|
1331
|
-
block.
|
|
1377
|
+
return /* @__PURE__ */ jsxs17("div", { className: "ss-w-cdash-lines", children: [
|
|
1378
|
+
/* @__PURE__ */ jsx21("span", { className: "ss-w-cdash-lines-heading", children: heading }),
|
|
1379
|
+
block.facts.map(
|
|
1380
|
+
(f, i) => f.entityRef ? /* @__PURE__ */ jsxs17(
|
|
1381
|
+
"button",
|
|
1382
|
+
{
|
|
1383
|
+
type: "button",
|
|
1384
|
+
className: "ss-w-cdash-fact",
|
|
1385
|
+
onClick: () => onAction(f.question ?? f.sentence, { ...f.entityRef, subject: f.sentence, personaHint: "club" }),
|
|
1386
|
+
children: [
|
|
1387
|
+
f.sentence,
|
|
1388
|
+
f.label ? /* @__PURE__ */ jsxs17("span", { className: "ss-w-cdash-fact-label", children: [
|
|
1389
|
+
" ",
|
|
1390
|
+
f.label
|
|
1391
|
+
] }) : null
|
|
1392
|
+
]
|
|
1393
|
+
},
|
|
1394
|
+
i
|
|
1395
|
+
) : /* @__PURE__ */ jsx21("p", { children: f.sentence }, i)
|
|
1396
|
+
)
|
|
1332
1397
|
] });
|
|
1333
1398
|
}
|
|
1334
1399
|
|
|
1335
1400
|
// src/components/club-dashboard/CountdownBlock.tsx
|
|
1336
|
-
import { useEffect as useEffect3, useState as
|
|
1337
|
-
import { jsx as
|
|
1401
|
+
import { useEffect as useEffect3, useState as useState7 } from "react";
|
|
1402
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1338
1403
|
var DAY_MS = 24 * 3600 * 1e3;
|
|
1339
1404
|
function pad2(n) {
|
|
1340
1405
|
return String(n).padStart(2, "0");
|
|
@@ -1347,7 +1412,7 @@ function splitRemaining(remainingMs) {
|
|
|
1347
1412
|
return { h: pad2(h), m: pad2(m), s: pad2(s) };
|
|
1348
1413
|
}
|
|
1349
1414
|
function CountdownBlock({ block, ui }) {
|
|
1350
|
-
const [remainingMs, setRemainingMs] =
|
|
1415
|
+
const [remainingMs, setRemainingMs] = useState7(() => block.kickoffUnix * 1e3 - Date.now());
|
|
1351
1416
|
useEffect3(() => {
|
|
1352
1417
|
setRemainingMs(block.kickoffUnix * 1e3 - Date.now());
|
|
1353
1418
|
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
|
@@ -1361,28 +1426,28 @@ function CountdownBlock({ block, ui }) {
|
|
|
1361
1426
|
const { h, m, s } = splitRemaining(remainingMs);
|
|
1362
1427
|
return /* @__PURE__ */ jsxs18("div", { className: "ss-w-cdash-cd", "aria-label": ui.clubKickoffAria(block.kickoffUnix * 1e3), children: [
|
|
1363
1428
|
/* @__PURE__ */ jsxs18("div", { className: "ss-w-cdash-cd-clock", "aria-hidden": "true", children: [
|
|
1364
|
-
/* @__PURE__ */
|
|
1429
|
+
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-cd-h", children: h }),
|
|
1365
1430
|
"h",
|
|
1366
1431
|
" ",
|
|
1367
|
-
/* @__PURE__ */
|
|
1432
|
+
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-cd-m", children: m }),
|
|
1368
1433
|
"m",
|
|
1369
1434
|
" ",
|
|
1370
|
-
/* @__PURE__ */
|
|
1435
|
+
/* @__PURE__ */ jsx22("span", { className: "ss-w-cdash-cd-s", children: s }),
|
|
1371
1436
|
"s"
|
|
1372
1437
|
] }),
|
|
1373
|
-
/* @__PURE__ */
|
|
1438
|
+
/* @__PURE__ */ jsx22("div", { className: "ss-w-cdash-cd-label", children: ui.clubCountdownLabel })
|
|
1374
1439
|
] });
|
|
1375
1440
|
}
|
|
1376
1441
|
|
|
1377
1442
|
// src/components/club-dashboard/ClubDashboard.tsx
|
|
1378
|
-
import { jsx as
|
|
1443
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1379
1444
|
var CLUB_BLOCK_REGISTRY = {
|
|
1380
|
-
greetingHeader: ({ block }) => block.type === "greetingHeader" ? /* @__PURE__ */
|
|
1381
|
-
fixtureHero: ({ block, ui, onAction }) => block.type === "fixtureHero" ? /* @__PURE__ */
|
|
1382
|
-
formGuide: ({ block, ui }) => block.type === "formGuide" ? /* @__PURE__ */
|
|
1383
|
-
matchPreview: ({ block, ui, onAction }) => block.type === "matchPreview" ? /* @__PURE__ */
|
|
1384
|
-
teamDna: ({ block, ui, onAction }) => block.type === "teamDna" ? /* @__PURE__ */
|
|
1385
|
-
countdown: ({ block, ui }) => block.type === "countdown" ? /* @__PURE__ */
|
|
1445
|
+
greetingHeader: ({ block }) => block.type === "greetingHeader" ? /* @__PURE__ */ jsx23(GreetingHeaderBlock, { block }) : null,
|
|
1446
|
+
fixtureHero: ({ block, ui, onAction }) => block.type === "fixtureHero" ? /* @__PURE__ */ jsx23(FixtureHeroBlock, { block, ui, onAction }) : null,
|
|
1447
|
+
formGuide: ({ block, ui }) => block.type === "formGuide" ? /* @__PURE__ */ jsx23(FormGuideBlock, { block, ui }) : null,
|
|
1448
|
+
matchPreview: ({ block, ui, onAction }) => block.type === "matchPreview" ? /* @__PURE__ */ jsx23(MatchPreviewBlock, { block, ui, onAction }) : null,
|
|
1449
|
+
teamDna: ({ block, ui, onAction }) => block.type === "teamDna" ? /* @__PURE__ */ jsx23(TeamDnaBlock, { block, ui, onAction }) : null,
|
|
1450
|
+
countdown: ({ block, ui }) => block.type === "countdown" ? /* @__PURE__ */ jsx23(CountdownBlock, { block, ui }) : null
|
|
1386
1451
|
};
|
|
1387
1452
|
function ClubDashboard({
|
|
1388
1453
|
dashboard,
|
|
@@ -1390,39 +1455,39 @@ function ClubDashboard({
|
|
|
1390
1455
|
onAction
|
|
1391
1456
|
}) {
|
|
1392
1457
|
if (!dashboard.blocks.length) return null;
|
|
1393
|
-
return /* @__PURE__ */
|
|
1458
|
+
return /* @__PURE__ */ jsx23("div", { className: "ss-w-cdash", children: dashboard.blocks.map((block, i) => {
|
|
1394
1459
|
const Comp = Object.prototype.hasOwnProperty.call(CLUB_BLOCK_REGISTRY, block.type) ? CLUB_BLOCK_REGISTRY[block.type] : void 0;
|
|
1395
1460
|
if (!Comp) {
|
|
1396
1461
|
console.warn(`[club-dashboard] no renderer for block type "${block.type}"`);
|
|
1397
1462
|
return null;
|
|
1398
1463
|
}
|
|
1399
|
-
return /* @__PURE__ */
|
|
1464
|
+
return /* @__PURE__ */ jsx23("div", { className: "ss-w-cdash-block", children: /* @__PURE__ */ jsx23(Comp, { block, ui, onAction }) }, i);
|
|
1400
1465
|
}) });
|
|
1401
1466
|
}
|
|
1402
1467
|
|
|
1403
1468
|
// src/components/ChatMessage.tsx
|
|
1404
|
-
import { jsx as
|
|
1469
|
+
import { jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1405
1470
|
function ChatMessage({ message, disabled, onAct, onTap, onClubAction, ui, slip }) {
|
|
1406
1471
|
if (message.role === "user") {
|
|
1407
|
-
return /* @__PURE__ */
|
|
1472
|
+
return /* @__PURE__ */ jsx24("div", { className: "ss-w-msg ss-w-user", children: /* @__PURE__ */ jsx24("div", { className: "ss-w-bubble", children: message.text }) });
|
|
1408
1473
|
}
|
|
1409
1474
|
return /* @__PURE__ */ jsxs19("div", { className: "ss-w-msg ss-w-bot", children: [
|
|
1410
|
-
message.text && !message.greetingDashboard && !message.clubDashboard ? /* @__PURE__ */
|
|
1411
|
-
message.greetingDashboard ? /* @__PURE__ */
|
|
1412
|
-
message.clubDashboard && ui ? /* @__PURE__ */
|
|
1413
|
-
/* @__PURE__ */
|
|
1414
|
-
/* @__PURE__ */
|
|
1415
|
-
/* @__PURE__ */
|
|
1416
|
-
/* @__PURE__ */
|
|
1417
|
-
/* @__PURE__ */
|
|
1475
|
+
message.text && !message.greetingDashboard && !message.clubDashboard ? /* @__PURE__ */ jsx24(Markdown, { text: message.text }) : null,
|
|
1476
|
+
message.greetingDashboard ? /* @__PURE__ */ jsx24(GreetingDashboard, { dashboard: message.greetingDashboard, onTap }) : null,
|
|
1477
|
+
message.clubDashboard && ui ? /* @__PURE__ */ jsx24(ClubDashboard, { dashboard: message.clubDashboard, ui, onAction: onClubAction }) : null,
|
|
1478
|
+
/* @__PURE__ */ jsx24(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
|
|
1479
|
+
/* @__PURE__ */ jsx24(BettingInsightList, { insights: message.insights, ui, slip }),
|
|
1480
|
+
/* @__PURE__ */ jsx24(MarketOddsCardList, { cards: message.marketOdds, ui, slip }),
|
|
1481
|
+
/* @__PURE__ */ jsx24(OddsMovementCardList, { cards: message.oddsMovement, ui }),
|
|
1482
|
+
/* @__PURE__ */ jsx24(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
|
|
1418
1483
|
] });
|
|
1419
1484
|
}
|
|
1420
1485
|
|
|
1421
1486
|
// src/components/IntentChips.tsx
|
|
1422
|
-
import { jsx as
|
|
1487
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
1423
1488
|
function IntentChips({ chips, onPick }) {
|
|
1424
1489
|
if (chips.length === 0) return null;
|
|
1425
|
-
return /* @__PURE__ */
|
|
1490
|
+
return /* @__PURE__ */ jsx25("div", { className: "ss-w-chips", children: chips.map((c, i) => /* @__PURE__ */ jsx25("button", { type: "button", className: "ss-w-chip", onClick: () => onPick(c.text), children: c.text }, `${c.text}-${i}`)) });
|
|
1426
1491
|
}
|
|
1427
1492
|
|
|
1428
1493
|
// src/scroll.ts
|
|
@@ -1432,7 +1497,7 @@ function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
|
|
|
1432
1497
|
}
|
|
1433
1498
|
|
|
1434
1499
|
// src/components/MessageList.tsx
|
|
1435
|
-
import { jsx as
|
|
1500
|
+
import { jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1436
1501
|
function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
1437
1502
|
const { state, send } = controller;
|
|
1438
1503
|
const listRef = useRef2(null);
|
|
@@ -1453,7 +1518,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
1453
1518
|
if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current);
|
|
1454
1519
|
},
|
|
1455
1520
|
children: [
|
|
1456
|
-
state.messages.map((m) => /* @__PURE__ */
|
|
1521
|
+
state.messages.map((m) => /* @__PURE__ */ jsx26(
|
|
1457
1522
|
ChatMessage,
|
|
1458
1523
|
{
|
|
1459
1524
|
message: m,
|
|
@@ -1463,31 +1528,31 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
1463
1528
|
send(tile.actionValue, { displayText: tile.title });
|
|
1464
1529
|
if (m.role === "assistant" && m.greetingDashboard) onDashboardTap?.(tile, index, m.greetingDashboard.layout);
|
|
1465
1530
|
},
|
|
1466
|
-
onClubAction: (
|
|
1531
|
+
onClubAction: (message, grounding, displayText) => send(message, { grounding, displayText: displayText ?? message }),
|
|
1467
1532
|
ui,
|
|
1468
1533
|
slip
|
|
1469
1534
|
},
|
|
1470
1535
|
m.id
|
|
1471
1536
|
)),
|
|
1472
|
-
state.isStreaming && state.actionsLoading ? /* @__PURE__ */
|
|
1537
|
+
state.isStreaming && state.actionsLoading ? /* @__PURE__ */ jsx26(ActionButtons, { actions: [], loading: true, onAct: () => {
|
|
1473
1538
|
} }) : null,
|
|
1474
|
-
state.status ? /* @__PURE__ */
|
|
1539
|
+
state.status ? /* @__PURE__ */ jsx26("div", { className: "ss-w-status", children: state.status }) : null,
|
|
1475
1540
|
state.error ? /* @__PURE__ */ jsxs20("div", { className: "ss-w-error", role: "alert", children: [
|
|
1476
|
-
/* @__PURE__ */
|
|
1477
|
-
/* @__PURE__ */
|
|
1541
|
+
/* @__PURE__ */ jsx26("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
|
|
1542
|
+
/* @__PURE__ */ jsx26("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
|
|
1478
1543
|
] }) : null,
|
|
1479
|
-
!hasUserMessage && !hasDashboard ? /* @__PURE__ */
|
|
1480
|
-
/* @__PURE__ */
|
|
1544
|
+
!hasUserMessage && !hasDashboard ? /* @__PURE__ */ jsx26(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
|
|
1545
|
+
/* @__PURE__ */ jsx26("div", { ref: endRef })
|
|
1481
1546
|
]
|
|
1482
1547
|
}
|
|
1483
1548
|
);
|
|
1484
1549
|
}
|
|
1485
1550
|
|
|
1486
1551
|
// src/components/ChatInput.tsx
|
|
1487
|
-
import { useState as
|
|
1488
|
-
import { jsx as
|
|
1552
|
+
import { useState as useState8 } from "react";
|
|
1553
|
+
import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1489
1554
|
function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
|
|
1490
|
-
const [value, setValue] =
|
|
1555
|
+
const [value, setValue] = useState8("");
|
|
1491
1556
|
const submit = () => {
|
|
1492
1557
|
const t = value.trim();
|
|
1493
1558
|
if (!t) return;
|
|
@@ -1501,16 +1566,16 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
|
|
|
1501
1566
|
}
|
|
1502
1567
|
};
|
|
1503
1568
|
return /* @__PURE__ */ jsxs21("div", { className: "ss-w-input", children: [
|
|
1504
|
-
/* @__PURE__ */
|
|
1505
|
-
streaming ? /* @__PURE__ */
|
|
1569
|
+
/* @__PURE__ */ jsx27("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
|
|
1570
|
+
streaming ? /* @__PURE__ */ jsx27("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ jsx27("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ jsx27("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ jsx27(SendIcon, {}) })
|
|
1506
1571
|
] });
|
|
1507
1572
|
}
|
|
1508
1573
|
|
|
1509
1574
|
// src/components/ChatPanel.tsx
|
|
1510
|
-
import { jsx as
|
|
1575
|
+
import { jsx as jsx28, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1511
1576
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
1512
1577
|
function useIsModal() {
|
|
1513
|
-
const [modal, setModal] =
|
|
1578
|
+
const [modal, setModal] = useState9(false);
|
|
1514
1579
|
useEffect5(() => {
|
|
1515
1580
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1516
1581
|
const mql = window.matchMedia(FULLSCREEN_QUERY);
|
|
@@ -1532,9 +1597,9 @@ function ChatPanel({ controller, ui, slip, onDashboardTap }) {
|
|
|
1532
1597
|
return () => window.removeEventListener("keydown", onKey);
|
|
1533
1598
|
}, [close]);
|
|
1534
1599
|
return /* @__PURE__ */ jsxs22("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
|
|
1535
|
-
/* @__PURE__ */
|
|
1536
|
-
/* @__PURE__ */
|
|
1537
|
-
/* @__PURE__ */
|
|
1600
|
+
/* @__PURE__ */ jsx28(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
|
|
1601
|
+
/* @__PURE__ */ jsx28(MessageList, { controller, ui, slip, onDashboardTap }),
|
|
1602
|
+
/* @__PURE__ */ jsx28(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: (t) => send(t), onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
|
|
1538
1603
|
] });
|
|
1539
1604
|
}
|
|
1540
1605
|
|
|
@@ -1582,7 +1647,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1582
1647
|
.ss-w-greeting-x { flex: none; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; font-size: 17px; line-height: 1; padding: 7px 9px 0 2px; }
|
|
1583
1648
|
|
|
1584
1649
|
/* panel */
|
|
1585
|
-
.ss-w-panel { position: fixed; bottom: calc(var(--ss-w-offset-y) + 72px); z-index: 2147483000; display: flex; flex-direction: column; width: min(
|
|
1650
|
+
.ss-w-panel { position: fixed; bottom: calc(var(--ss-w-offset-y) + 72px); z-index: 2147483000; display: flex; flex-direction: column; width: min(460px, calc(100vw - 40px)); height: min(640px, calc(100vh - 120px)); background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: var(--ss-w-radius); overflow: hidden; box-shadow: 0 12px 40px rgba(0,0,0,.24); }
|
|
1586
1651
|
.ss-w-root[data-ss-w-pos="right"] .ss-w-panel { right: var(--ss-w-offset-x); }
|
|
1587
1652
|
.ss-w-root[data-ss-w-pos="left"] .ss-w-panel { left: var(--ss-w-offset-x); }
|
|
1588
1653
|
@media (max-width: 639px) {
|
|
@@ -1685,9 +1750,9 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1685
1750
|
.ss-w-bi-floor { font-size: 8.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ss-w-faint); background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 4px; padding: 1px 5px; display: inline-flex; align-items: center; align-self: flex-start; flex: none; }
|
|
1686
1751
|
|
|
1687
1752
|
/* crests -- CSS background-image on a span, never <img> (matches .ss-w-ecard-crest precedent) */
|
|
1688
|
-
.ss-w-bi-comp-logo { width:
|
|
1689
|
-
.ss-w-bi-crest { width:
|
|
1690
|
-
.ss-w-bi-crest-mono { display: grid; place-items: center; font-size:
|
|
1753
|
+
.ss-w-bi-comp-logo { width: 16px; height: 16px; flex: none; display: block; border-radius: 50%; object-fit: contain; }
|
|
1754
|
+
.ss-w-bi-crest { width: 24px; height: 24px; flex: none; display: block; border-radius: 50%; object-fit: contain; }
|
|
1755
|
+
.ss-w-bi-crest-mono { display: grid; place-items: center; font-size: 10px; font-weight: 700; color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 16%, var(--ss-w-panel)); }
|
|
1691
1756
|
|
|
1692
1757
|
/* row 2: crest-flanked fixture on the left, boxed action panel on the right */
|
|
1693
1758
|
.ss-w-bi-body { display: flex; align-items: center; gap: 10px; }
|
|
@@ -1695,16 +1760,16 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1695
1760
|
.ss-w-bi-team { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1696
1761
|
.ss-w-bi-vs { font-size: 10px; font-weight: 600; color: var(--ss-w-faint); flex: none; }
|
|
1697
1762
|
.ss-w-bi-fixture-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1698
|
-
.ss-w-bi-action { margin-left: auto; flex: none; display: flex; flex-direction: column; align-items:
|
|
1699
|
-
.ss-w-bi-action .ss-w-slip
|
|
1763
|
+
.ss-w-bi-action { margin-left: auto; flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; min-width: 0; }
|
|
1764
|
+
.ss-w-bi-action .ss-w-slip { width: 100%; }
|
|
1765
|
+
.ss-w-bi-action .ss-w-slip > button { flex: 1; width: 100%; text-align: center; border-radius: 8px; }
|
|
1700
1766
|
/* The action column is narrow; let its toast size to its own text and anchor to the card's right edge instead of being clipped to the button width. */
|
|
1701
1767
|
.ss-w-bi-action .ss-w-toast { left: auto; right: 0; width: max-content; max-width: 210px; white-space: normal; }
|
|
1702
|
-
.ss-w-bi-mkt { display: flex; flex-direction: column; gap:
|
|
1703
|
-
.ss-w-bi-market { font-size:
|
|
1704
|
-
.ss-w-bi-sel { font-size:
|
|
1705
|
-
.ss-w-bi-odds { flex: none; display: flex;
|
|
1706
|
-
.ss-w-bi-odds
|
|
1707
|
-
.ss-w-bi-odds b { font-size: 19px; font-family: ui-monospace, monospace; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); line-height: 1.1; }
|
|
1768
|
+
.ss-w-bi-mkt { display: flex; flex-direction: column; gap: 1px; min-width: 0; align-items: flex-end; text-align: right; }
|
|
1769
|
+
.ss-w-bi-market { font-size: 12px; font-weight: 600; line-height: 1.2; color: var(--ss-w-faint); white-space: nowrap; }
|
|
1770
|
+
.ss-w-bi-sel { font-size: 11px; line-height: 1.25; color: var(--ss-w-faint); }
|
|
1771
|
+
.ss-w-bi-odds { flex: none; display: flex; align-items: baseline; justify-content: flex-end; gap: 5px; }
|
|
1772
|
+
.ss-w-bi-odds b { font-size: 23px; font-family: ui-monospace, monospace; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); line-height: 1.05; }
|
|
1708
1773
|
.ss-w-bi-book { font-size: 9.5px; color: var(--ss-w-faint); }
|
|
1709
1774
|
|
|
1710
1775
|
/* row 3: bar-chart glyph + reasoning prose + stats-expander chevron, in a subtle strip */
|
|
@@ -1718,11 +1783,11 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1718
1783
|
}
|
|
1719
1784
|
.ss-w-bi-reason-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; flex: 1; }
|
|
1720
1785
|
.ss-w-bi-text { font-size: 12px; line-height: 1.45; color: var(--ss-w-ink); }
|
|
1721
|
-
.ss-w-bi-
|
|
1722
|
-
.ss-w-bi-
|
|
1723
|
-
.ss-w-bi-
|
|
1724
|
-
.ss-w-bi-
|
|
1725
|
-
.ss-w-bi-
|
|
1786
|
+
.ss-w-bi-text-clamp { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
|
1787
|
+
.ss-w-bi-expand { flex: none; align-self: center; display: grid; place-items: center; width: 22px; height: 22px; margin: -2px -4px -2px 0; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; }
|
|
1788
|
+
.ss-w-bi-expand:hover { color: var(--ss-w-ink); }
|
|
1789
|
+
.ss-w-bi-arrow { width: 7px; height: 7px; border-right: 1.6px solid currentColor; border-top: 1.6px solid currentColor; transform: rotate(45deg); transition: transform .15s ease; }
|
|
1790
|
+
.ss-w-bi-arrow-open { transform: rotate(135deg); }
|
|
1726
1791
|
.ss-w-bi-rows { display: flex; flex-direction: column; }
|
|
1727
1792
|
.ss-w-bi-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 5px 0; border-top: 1px solid var(--ss-w-line); }
|
|
1728
1793
|
.ss-w-bi-row:first-child { border-top: none; }
|
|
@@ -1737,11 +1802,13 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1737
1802
|
/* market odds card */
|
|
1738
1803
|
.ss-w-mocards { display: flex; flex-direction: column; gap: 7px; }
|
|
1739
1804
|
.ss-w-mocard { background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; border-left: 3px solid var(--ss-w-accent); padding: 9px 11px; display: flex; flex-direction: column; gap: 6px; }
|
|
1740
|
-
.ss-w-mo-
|
|
1741
|
-
.ss-w-mo-
|
|
1742
|
-
.ss-w-mo-
|
|
1743
|
-
.ss-w-mo-
|
|
1744
|
-
.ss-w-mo-
|
|
1805
|
+
.ss-w-mo-sub { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
|
|
1806
|
+
.ss-w-mo-teams { font-size: 13px; font-weight: 650; color: var(--ss-w-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1807
|
+
.ss-w-mo-market { font-size: 11.5px; font-weight: 600; color: var(--ss-w-faint); }
|
|
1808
|
+
.ss-w-mo-more { align-self: flex-start; display: inline-flex; align-items: center; gap: 5px; background: none; border: none; color: var(--ss-w-accent); font: inherit; font-size: 11.5px; font-weight: 600; padding: 2px 0; cursor: pointer; }
|
|
1809
|
+
.ss-w-mo-more:hover { text-decoration: underline; }
|
|
1810
|
+
.ss-w-mo-more-chev { width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); transition: transform .15s ease; }
|
|
1811
|
+
.ss-w-mo-more-chev-up { transform: translateY(1px) rotate(-135deg); }
|
|
1745
1812
|
.ss-w-mo-rows { display: flex; flex-direction: column; gap: 4px; }
|
|
1746
1813
|
.ss-w-mo-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; border-bottom: 1px dashed var(--ss-w-line); }
|
|
1747
1814
|
.ss-w-mo-row:last-child { border-bottom: none; }
|
|
@@ -1913,9 +1980,12 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1913
1980
|
.ss-w-cdash-pill--d { background: var(--ss-w-faint); }
|
|
1914
1981
|
.ss-w-cdash-pill--l { background: color-mix(in srgb, var(--ss-w-neg) 88%, black); }
|
|
1915
1982
|
|
|
1916
|
-
.ss-w-cdash-lines { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; width: 100%; text-align: left; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-left: 3px solid var(--ss-w-accent); border-radius: 12px; padding: 10px 12px;
|
|
1983
|
+
.ss-w-cdash-lines { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; width: 100%; text-align: left; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-left: 3px solid var(--ss-w-accent); border-radius: 12px; padding: 10px 12px; }
|
|
1917
1984
|
.ss-w-cdash-lines-heading { font-size: 12px; font-weight: 700; color: var(--ss-w-accent); }
|
|
1918
|
-
.ss-w-cdash-lines p { font-size: 12px; line-height: 1.4; color: var(--ss-w-ink); }
|
|
1985
|
+
.ss-w-cdash-lines p { font-size: 12px; line-height: 1.4; color: var(--ss-w-ink); margin: 0; }
|
|
1986
|
+
.ss-w-cdash-fact { display: block; width: 100%; text-align: left; font: inherit; font-size: 12px; line-height: 1.4; color: var(--ss-w-ink); background: none; border: none; padding: 0; cursor: pointer; }
|
|
1987
|
+
.ss-w-cdash-fact:hover, .ss-w-cdash-fact:focus-visible { color: var(--ss-w-accent); text-decoration: underline; }
|
|
1988
|
+
.ss-w-cdash-fact-label { font-size: 11px; font-weight: 700; color: var(--ss-w-accent); }
|
|
1919
1989
|
|
|
1920
1990
|
.ss-w-cdash-cd { display: flex; flex-direction: column; align-items: center; gap: 4px; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 12px; padding: 10px 12px; text-align: center; }
|
|
1921
1991
|
.ss-w-cdash-cd-clock { display: flex; align-items: baseline; justify-content: center; gap: 2px; font-variant-numeric: tabular-nums; font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-weight: 700; font-size: 18px; color: var(--ss-w-ink); }
|
|
@@ -1924,7 +1994,7 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
1924
1994
|
`;
|
|
1925
1995
|
|
|
1926
1996
|
// src/StatsWidget.tsx
|
|
1927
|
-
import { jsx as
|
|
1997
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
1928
1998
|
function buildClient(props) {
|
|
1929
1999
|
try {
|
|
1930
2000
|
if ("client" in props && props.client) {
|
|
@@ -1977,7 +2047,7 @@ function StatsWidget(props) {
|
|
|
1977
2047
|
}, [built, ui.injectStyles]);
|
|
1978
2048
|
if (!built) return null;
|
|
1979
2049
|
const attrs = themeAttrs(ui);
|
|
1980
|
-
return /* @__PURE__ */
|
|
2050
|
+
return /* @__PURE__ */ jsx29("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__ */ jsx29(ChatPanel, { controller, ui, slip, onDashboardTap }) : /* @__PURE__ */ jsx29(
|
|
1981
2051
|
ChatFab,
|
|
1982
2052
|
{
|
|
1983
2053
|
label: ui.launcherLabel,
|