@sensiblestats/widget-react 0.30.0 → 0.31.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 +11 -0
- package/dist/index.cjs +1298 -576
- 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 +1292 -570
- package/dist/index.js.map +1 -1
- package/dist/styles.css +74 -4
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -36,7 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(index_exports);
|
|
37
37
|
|
|
38
38
|
// src/StatsWidget.tsx
|
|
39
|
-
var
|
|
39
|
+
var import_react21 = require("react");
|
|
40
40
|
var import_widget_sdk5 = require("@sensiblestats/widget-sdk");
|
|
41
41
|
|
|
42
42
|
// src/kickoff.ts
|
|
@@ -93,7 +93,7 @@ var STRINGS = {
|
|
|
93
93
|
return `Price movement over the last ${span}: opened at ${opening}, currently ${current}${drift}.`;
|
|
94
94
|
},
|
|
95
95
|
inSlip: "In slip",
|
|
96
|
-
slipAdded:
|
|
96
|
+
slipAdded: "Added to slip",
|
|
97
97
|
slipDuplicate: "Already in your slip",
|
|
98
98
|
slipPriceChanged: (from, to) => `Added at ${to} (was ${from})`,
|
|
99
99
|
slipPriceNotAccepted: (from, to) => `Price moved to ${to} (was ${from}). Tap to add.`,
|
|
@@ -102,7 +102,23 @@ var STRINGS = {
|
|
|
102
102
|
slipFailed: "Couldn't add to slip. Try again.",
|
|
103
103
|
today: "Today",
|
|
104
104
|
tomorrow: "Tomorrow",
|
|
105
|
-
bettingKickoff: (kickoffUtc, now) => formatBettingKickoff(kickoffUtc, STRINGS.en, "en", now)
|
|
105
|
+
bettingKickoff: (kickoffUtc, now) => formatBettingKickoff(kickoffUtc, STRINGS.en, "en", now),
|
|
106
|
+
tabChat: "Chat",
|
|
107
|
+
tabMatches: "Matches",
|
|
108
|
+
tabOdds: "Odds",
|
|
109
|
+
pinLabel: "Track odds",
|
|
110
|
+
unpinLabel: "Stop tracking odds",
|
|
111
|
+
matchPinLabel: "Track match",
|
|
112
|
+
matchUnpinLabel: "Stop tracking match",
|
|
113
|
+
matchLimitToast: "Match limit reached \u2014 unpin one first",
|
|
114
|
+
marketLimitToast: "Odds limit reached \u2014 unpin one first",
|
|
115
|
+
emptyMatchesTab: "No pinned matches yet. Pin a match from the conversation to track it live.",
|
|
116
|
+
emptyOddsTab: "No pinned odds yet. Pin a market from the conversation to track it live.",
|
|
117
|
+
asOf: (time) => `Prices as of ${time}`,
|
|
118
|
+
graceNote: "Unpins on next open \xB7 or in 4 h",
|
|
119
|
+
suspendedLabel: "Suspended",
|
|
120
|
+
fullTimeLabel: "Full time",
|
|
121
|
+
inSlipLabel: "In slip"
|
|
106
122
|
},
|
|
107
123
|
tr: {
|
|
108
124
|
launcherLabel: "SensibleStats ile sohbet et",
|
|
@@ -144,7 +160,7 @@ var STRINGS = {
|
|
|
144
160
|
return `Son ${span} i\xE7indeki oran hareketi: ${opening} ile a\xE7\u0131ld\u0131, \u015Fu anda ${current}${drift}.`;
|
|
145
161
|
},
|
|
146
162
|
inSlip: "Kuponda",
|
|
147
|
-
slipAdded:
|
|
163
|
+
slipAdded: "Kupona eklendi",
|
|
148
164
|
slipDuplicate: "Bu se\xE7im kuponunuzda zaten var",
|
|
149
165
|
slipPriceChanged: (from, to) => `${to} oran\u0131yla eklendi (\xF6nceki ${from})`,
|
|
150
166
|
slipPriceNotAccepted: (from, to) => `Oran ${to} oldu (\xF6nceki ${from}). Eklemek i\xE7in dokunun.`,
|
|
@@ -153,7 +169,23 @@ var STRINGS = {
|
|
|
153
169
|
slipFailed: "Kupona eklenemedi. Tekrar deneyin.",
|
|
154
170
|
today: "Bug\xFCn",
|
|
155
171
|
tomorrow: "Yar\u0131n",
|
|
156
|
-
bettingKickoff: (kickoffUtc, now) => formatBettingKickoff(kickoffUtc, STRINGS.tr, "tr", now)
|
|
172
|
+
bettingKickoff: (kickoffUtc, now) => formatBettingKickoff(kickoffUtc, STRINGS.tr, "tr", now),
|
|
173
|
+
tabChat: "Sohbet",
|
|
174
|
+
tabMatches: "Ma\xE7lar",
|
|
175
|
+
tabOdds: "Oranlar",
|
|
176
|
+
pinLabel: "Oran\u0131 takip et",
|
|
177
|
+
unpinLabel: "Oran takibini b\u0131rak",
|
|
178
|
+
matchPinLabel: "Ma\xE7\u0131 takip et",
|
|
179
|
+
matchUnpinLabel: "Ma\xE7 takibini b\u0131rak",
|
|
180
|
+
matchLimitToast: "Ma\xE7 limiti dolu \u2014 \xF6nce bir ma\xE7\u0131 kald\u0131r",
|
|
181
|
+
marketLimitToast: "Oran limiti dolu \u2014 \xF6nce birini kald\u0131r",
|
|
182
|
+
emptyMatchesTab: "Hen\xFCz sabitlenmi\u015F ma\xE7 yok. Canl\u0131 takip i\xE7in sohbetteki bir ma\xE7\u0131 sabitle.",
|
|
183
|
+
emptyOddsTab: "Hen\xFCz sabitlenmi\u015F oran yok. Canl\u0131 takip i\xE7in sohbetteki bir marketi sabitle.",
|
|
184
|
+
asOf: (time) => `Fiyatlar ${time} itibar\u0131yla`,
|
|
185
|
+
graceNote: "Bir sonraki a\xE7\u0131l\u0131\u015Fta kald\u0131r\u0131l\u0131r \xB7 en ge\xE7 4 saat",
|
|
186
|
+
suspendedLabel: "Ask\u0131da",
|
|
187
|
+
fullTimeLabel: "Ma\xE7 sonu",
|
|
188
|
+
inSlipLabel: "Kuponda"
|
|
157
189
|
}
|
|
158
190
|
};
|
|
159
191
|
function resolveLocaleStrings(locale) {
|
|
@@ -217,7 +249,23 @@ function normalizeUi(cfg) {
|
|
|
217
249
|
slipFailed: strings.slipFailed,
|
|
218
250
|
today: strings.today,
|
|
219
251
|
tomorrow: strings.tomorrow,
|
|
220
|
-
bettingKickoff: strings.bettingKickoff
|
|
252
|
+
bettingKickoff: strings.bettingKickoff,
|
|
253
|
+
tabChat: strings.tabChat,
|
|
254
|
+
tabMatches: strings.tabMatches,
|
|
255
|
+
tabOdds: strings.tabOdds,
|
|
256
|
+
pinLabel: strings.pinLabel,
|
|
257
|
+
unpinLabel: strings.unpinLabel,
|
|
258
|
+
matchPinLabel: strings.matchPinLabel,
|
|
259
|
+
matchUnpinLabel: strings.matchUnpinLabel,
|
|
260
|
+
matchLimitToast: strings.matchLimitToast,
|
|
261
|
+
marketLimitToast: strings.marketLimitToast,
|
|
262
|
+
emptyMatchesTab: strings.emptyMatchesTab,
|
|
263
|
+
emptyOddsTab: strings.emptyOddsTab,
|
|
264
|
+
asOf: strings.asOf,
|
|
265
|
+
graceNote: strings.graceNote,
|
|
266
|
+
suspendedLabel: strings.suspendedLabel,
|
|
267
|
+
fullTimeLabel: strings.fullTimeLabel,
|
|
268
|
+
inSlipLabel: strings.inSlipLabel
|
|
221
269
|
};
|
|
222
270
|
}
|
|
223
271
|
function toClientOptions(cfg) {
|
|
@@ -229,6 +277,34 @@ function toUserContext(cfg) {
|
|
|
229
277
|
return cfg.userContext && Object.keys(cfg.userContext).length > 0 ? cfg.userContext : void 0;
|
|
230
278
|
}
|
|
231
279
|
|
|
280
|
+
// src/slip.ts
|
|
281
|
+
var ADD_TO_SLIP_TIMEOUT_MS = 1e4;
|
|
282
|
+
function wasAdded(result) {
|
|
283
|
+
if (!result) return true;
|
|
284
|
+
if (result.status === "price_changed") return result.accepted;
|
|
285
|
+
return result.status === "added";
|
|
286
|
+
}
|
|
287
|
+
function isTerminal(result) {
|
|
288
|
+
if (!result) return true;
|
|
289
|
+
if (result.status === "price_changed") return result.accepted;
|
|
290
|
+
return result.status === "added" || result.status === "duplicate";
|
|
291
|
+
}
|
|
292
|
+
function resultToToast(result, shownOdds, ui) {
|
|
293
|
+
if (!result) return { kind: "success", text: ui.slipAdded };
|
|
294
|
+
switch (result.status) {
|
|
295
|
+
case "added":
|
|
296
|
+
return { kind: "success", text: ui.slipAdded };
|
|
297
|
+
case "duplicate":
|
|
298
|
+
return { kind: "success", text: ui.slipDuplicate };
|
|
299
|
+
case "price_changed":
|
|
300
|
+
return result.accepted ? { kind: "success", text: ui.slipPriceChanged(shownOdds, result.newOddsDecimal.toFixed(2)) } : { kind: "error", text: ui.slipPriceNotAccepted(shownOdds, result.newOddsDecimal.toFixed(2)) };
|
|
301
|
+
case "rejected":
|
|
302
|
+
if (result.reason === "login_required") return { kind: "error", text: ui.slipLoginRequired };
|
|
303
|
+
if (result.reason === "suspended") return { kind: "error", text: ui.slipSuspended };
|
|
304
|
+
return { kind: "error", text: result.message ?? ui.slipFailed };
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
232
308
|
// src/dashboardTap.ts
|
|
233
309
|
var import_widget_sdk = require("@sensiblestats/widget-sdk");
|
|
234
310
|
function isSignalEntityType(value) {
|
|
@@ -402,7 +478,11 @@ function toInsightVM(insight) {
|
|
|
402
478
|
disclaimer: str(insight.disclaimer),
|
|
403
479
|
matchId: typeof insight.matchId === "number" ? insight.matchId : 0,
|
|
404
480
|
matchOddsId,
|
|
481
|
+
marketDeveloperName: str(insight.marketDeveloperName),
|
|
482
|
+
selectionLabel: str(insight.selectionLabel),
|
|
483
|
+
line: str(insight.line),
|
|
405
484
|
addToSlipEnabled: insight.addToSlipEnabled === true,
|
|
485
|
+
pinEnabled: insight.pinEnabled === true,
|
|
406
486
|
isMarketFloor: insight.isMarketFloor === true,
|
|
407
487
|
oddsDecimal: typeof oddsValue === "number" && Number.isFinite(oddsValue) ? oddsValue : void 0,
|
|
408
488
|
quotedAtUtc: str(insight.odds?.quotedAtUtc),
|
|
@@ -469,7 +549,10 @@ function toMarketOddsVM(card) {
|
|
|
469
549
|
mainRows: vms.filter((r) => r.isMain),
|
|
470
550
|
moreRows: vms.filter((r) => !r.isMain),
|
|
471
551
|
disclaimer: str(card.disclaimer),
|
|
472
|
-
addToSlipEnabled: card.addToSlipEnabled === true
|
|
552
|
+
addToSlipEnabled: card.addToSlipEnabled === true,
|
|
553
|
+
marketDeveloperName: str(card.marketDeveloperName),
|
|
554
|
+
mainLine: str(card.mainLine),
|
|
555
|
+
pinEnabled: card.pinEnabled === true
|
|
473
556
|
};
|
|
474
557
|
}
|
|
475
558
|
function toOddsMovementVM(card) {
|
|
@@ -491,8 +574,12 @@ function toOddsMovementVM(card) {
|
|
|
491
574
|
const bookmakerId = typeof card.bookmakerId === "number" ? card.bookmakerId : "";
|
|
492
575
|
return {
|
|
493
576
|
id: `${typeof card.matchId === "number" ? card.matchId : 0}:${str(card.marketDeveloperName) ?? ""}:${selection}:${bookmakerId}`,
|
|
577
|
+
matchId: typeof card.matchId === "number" ? card.matchId : 0,
|
|
494
578
|
market: str(card.marketLabel) ?? str(card.marketDeveloperName) ?? "",
|
|
579
|
+
marketDeveloperName: str(card.marketDeveloperName),
|
|
495
580
|
selection,
|
|
581
|
+
selectionLabel: str(card.selectionLabel),
|
|
582
|
+
line: str(card.line),
|
|
496
583
|
fixture: home && away ? `${home} vs ${away}` : void 0,
|
|
497
584
|
competition: str(card.competitionName),
|
|
498
585
|
bookmaker: str(card.bookmakerName),
|
|
@@ -504,7 +591,9 @@ function toOddsMovementVM(card) {
|
|
|
504
591
|
isSuspended: card.isSuspended === true,
|
|
505
592
|
disclaimer: str(card.disclaimer),
|
|
506
593
|
geometry: projectSeries(samples),
|
|
507
|
-
observationCount: samples.length
|
|
594
|
+
observationCount: samples.length,
|
|
595
|
+
pinEnabled: card.pinEnabled === true,
|
|
596
|
+
matchOddsId: typeof card.matchOddsId === "number" ? card.matchOddsId : void 0
|
|
508
597
|
};
|
|
509
598
|
}
|
|
510
599
|
function marketOddsRowToSlipSelection(vm, row, conversationId) {
|
|
@@ -819,6 +908,264 @@ function useChatStream(conversation, starterTexts, greetingMessage) {
|
|
|
819
908
|
return { state, open, close, stop, toggle, send, retry, dismissPopup };
|
|
820
909
|
}
|
|
821
910
|
|
|
911
|
+
// src/useLiveMonitor.ts
|
|
912
|
+
var import_react3 = require("react");
|
|
913
|
+
|
|
914
|
+
// src/pinStore.ts
|
|
915
|
+
var MAX_MATCH_PINS = 5;
|
|
916
|
+
var MAX_MARKET_PINS = 10;
|
|
917
|
+
function pinKey(p) {
|
|
918
|
+
return `${p.kind}:${p.matchId}:${p.marketDeveloperName ?? ""}:${p.selectionLabel ?? ""}:${p.line ?? ""}:${p.matchOddsId ?? ""}`;
|
|
919
|
+
}
|
|
920
|
+
var GRACE_MS = 4 * 60 * 60 * 1e3;
|
|
921
|
+
function pruneExpired(pins, sessionId, now) {
|
|
922
|
+
return pins.filter((p) => p.graceAt === void 0 || p.graceSession === sessionId && now - p.graceAt <= GRACE_MS);
|
|
923
|
+
}
|
|
924
|
+
function safeRead(storageKey) {
|
|
925
|
+
try {
|
|
926
|
+
const raw = window.localStorage.getItem(storageKey);
|
|
927
|
+
if (!raw) return [];
|
|
928
|
+
const parsed = JSON.parse(raw);
|
|
929
|
+
return parsed.v === 1 && Array.isArray(parsed.pins) ? parsed.pins : [];
|
|
930
|
+
} catch {
|
|
931
|
+
return [];
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
function safeWrite(storageKey, pins) {
|
|
935
|
+
try {
|
|
936
|
+
window.localStorage.setItem(storageKey, JSON.stringify({ v: 1, pins }));
|
|
937
|
+
} catch {
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
function createPinStore(storageKey, sessionId, onChange) {
|
|
941
|
+
let pins = pruneExpired(safeRead(storageKey), sessionId, Date.now());
|
|
942
|
+
const commit = (next) => {
|
|
943
|
+
pins = next;
|
|
944
|
+
safeWrite(storageKey, pins);
|
|
945
|
+
onChange(pins);
|
|
946
|
+
};
|
|
947
|
+
commit(pins);
|
|
948
|
+
return {
|
|
949
|
+
get pins() {
|
|
950
|
+
return pins;
|
|
951
|
+
},
|
|
952
|
+
has: (key) => pins.some((p) => p.key === key),
|
|
953
|
+
remove: (key) => commit(pins.filter((p) => p.key !== key)),
|
|
954
|
+
markGrace(keys, session, now) {
|
|
955
|
+
commit(
|
|
956
|
+
pins.map((p) => keys.includes(p.key) && p.graceAt === void 0 ? { ...p, graceAt: now, graceSession: session } : p)
|
|
957
|
+
);
|
|
958
|
+
},
|
|
959
|
+
toggle(pin) {
|
|
960
|
+
if (pins.some((p) => p.key === pin.key)) {
|
|
961
|
+
commit(pins.filter((p) => p.key !== pin.key));
|
|
962
|
+
return "removed";
|
|
963
|
+
}
|
|
964
|
+
const matchCount = pins.filter((p) => p.kind === "match").length;
|
|
965
|
+
const marketCount = pins.length - matchCount;
|
|
966
|
+
if (pin.kind === "match" && matchCount >= MAX_MATCH_PINS) return "match_limit";
|
|
967
|
+
if (pin.kind !== "match" && marketCount >= MAX_MARKET_PINS) return "market_limit";
|
|
968
|
+
commit([...pins, pin]);
|
|
969
|
+
return "added";
|
|
970
|
+
}
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
// src/useLiveMonitor.ts
|
|
975
|
+
var GOAL_OR_RED = /* @__PURE__ */ new Set(["goal", "red"]);
|
|
976
|
+
var MIN_POLL_MS = 5e3;
|
|
977
|
+
var DEFAULT_POLL_MS = 6e4;
|
|
978
|
+
function eventIdentity(e) {
|
|
979
|
+
return `${e.type}:${e.side}:${e.minuteLabel}:${e.player ?? ""}`;
|
|
980
|
+
}
|
|
981
|
+
function priceForPin(snapshot, pin) {
|
|
982
|
+
if (!snapshot) return void 0;
|
|
983
|
+
const market = snapshot.markets.find((m) => m.key === pin.key);
|
|
984
|
+
const rows = market?.card?.rows;
|
|
985
|
+
if (!rows || rows.length === 0) return void 0;
|
|
986
|
+
const row = pin.matchOddsId != null ? rows.find((r) => r.matchOddsId === pin.matchOddsId) : rows[0];
|
|
987
|
+
return row?.price;
|
|
988
|
+
}
|
|
989
|
+
function phaseForPin(snapshot, pin) {
|
|
990
|
+
if (pin.kind === "match") return snapshot.matches.find((m) => m.matchId === pin.matchId)?.phase;
|
|
991
|
+
return snapshot.markets.find((mk) => mk.key === pin.key)?.phase;
|
|
992
|
+
}
|
|
993
|
+
function useLiveMonitor(opts) {
|
|
994
|
+
const sessionIdRef = (0, import_react3.useRef)(crypto.randomUUID());
|
|
995
|
+
const [pins, setPins] = (0, import_react3.useState)([]);
|
|
996
|
+
const [store] = (0, import_react3.useState)(() => createPinStore(opts.storageKey, sessionIdRef.current, setPins));
|
|
997
|
+
const [enabled, setEnabled] = (0, import_react3.useState)(true);
|
|
998
|
+
const [snapshot, setSnapshotState] = (0, import_react3.useState)(null);
|
|
999
|
+
const [activeTab, setActiveTabState] = (0, import_react3.useState)("chat");
|
|
1000
|
+
const [chatDot, setChatDot] = (0, import_react3.useState)(false);
|
|
1001
|
+
const [matchesDot, setMatchesDot] = (0, import_react3.useState)(false);
|
|
1002
|
+
const [oddsDot, setOddsDot] = (0, import_react3.useState)(false);
|
|
1003
|
+
const [lastViewedPrices, setLastViewedPrices] = (0, import_react3.useState)({});
|
|
1004
|
+
const [inSlip, setInSlip] = (0, import_react3.useState)({});
|
|
1005
|
+
const pinsRef = (0, import_react3.useRef)(pins);
|
|
1006
|
+
pinsRef.current = pins;
|
|
1007
|
+
const activeTabRef = (0, import_react3.useRef)(activeTab);
|
|
1008
|
+
activeTabRef.current = activeTab;
|
|
1009
|
+
const snapshotRef = (0, import_react3.useRef)(snapshot);
|
|
1010
|
+
snapshotRef.current = snapshot;
|
|
1011
|
+
const lastViewedPricesRef = (0, import_react3.useRef)(lastViewedPrices);
|
|
1012
|
+
lastViewedPricesRef.current = lastViewedPrices;
|
|
1013
|
+
const applySnapshot = (0, import_react3.useCallback)((next) => {
|
|
1014
|
+
if (next === null) {
|
|
1015
|
+
setEnabled(false);
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
const prev = snapshotRef.current;
|
|
1019
|
+
const currentPins = pinsRef.current;
|
|
1020
|
+
const pinnedMatchIds = new Set(currentPins.filter((p) => p.kind === "match").map((p) => p.matchId));
|
|
1021
|
+
let sawNewGoalOrRed = false;
|
|
1022
|
+
for (const m of next.matches) {
|
|
1023
|
+
if (!pinnedMatchIds.has(m.matchId)) continue;
|
|
1024
|
+
const prevMatch = prev?.matches.find((pm) => pm.matchId === m.matchId);
|
|
1025
|
+
const prevKeys = new Set((prevMatch?.events ?? []).filter((e) => GOAL_OR_RED.has(e.type)).map(eventIdentity));
|
|
1026
|
+
if (m.events.some((e) => GOAL_OR_RED.has(e.type) && !prevKeys.has(eventIdentity(e)))) {
|
|
1027
|
+
sawNewGoalOrRed = true;
|
|
1028
|
+
break;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
if (sawNewGoalOrRed && activeTabRef.current !== "matches") setMatchesDot(true);
|
|
1032
|
+
const marketPins = currentPins.filter((p) => p.kind !== "match");
|
|
1033
|
+
if (activeTabRef.current === "odds") {
|
|
1034
|
+
setLastViewedPrices((prevMap) => {
|
|
1035
|
+
let changed = false;
|
|
1036
|
+
const out = { ...prevMap };
|
|
1037
|
+
for (const pin of marketPins) {
|
|
1038
|
+
const price = priceForPin(next, pin);
|
|
1039
|
+
if (price !== void 0 && out[pin.key] !== price) {
|
|
1040
|
+
out[pin.key] = price;
|
|
1041
|
+
changed = true;
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
return changed ? out : prevMap;
|
|
1045
|
+
});
|
|
1046
|
+
} else {
|
|
1047
|
+
let sawPriceMove = false;
|
|
1048
|
+
for (const pin of marketPins) {
|
|
1049
|
+
const price = priceForPin(next, pin);
|
|
1050
|
+
const last = lastViewedPricesRef.current[pin.key];
|
|
1051
|
+
if (price !== void 0 && last !== void 0 && price !== last) {
|
|
1052
|
+
sawPriceMove = true;
|
|
1053
|
+
break;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
if (sawPriceMove) setOddsDot(true);
|
|
1057
|
+
}
|
|
1058
|
+
const graceKeys = currentPins.filter((p) => {
|
|
1059
|
+
const phase = phaseForPin(next, p);
|
|
1060
|
+
return phase === "fullTime" || phase === "postponed" || phase === "gone";
|
|
1061
|
+
}).map((p) => p.key);
|
|
1062
|
+
if (graceKeys.length > 0) store.markGrace(graceKeys, sessionIdRef.current, Date.now());
|
|
1063
|
+
snapshotRef.current = next;
|
|
1064
|
+
setSnapshotState(next);
|
|
1065
|
+
}, [store]);
|
|
1066
|
+
const inFlightRef = (0, import_react3.useRef)(false);
|
|
1067
|
+
const timerRef = (0, import_react3.useRef)(void 0);
|
|
1068
|
+
const disabledRef = (0, import_react3.useRef)(false);
|
|
1069
|
+
const getLiveMonitorRef = (0, import_react3.useRef)(opts.getLiveMonitor);
|
|
1070
|
+
getLiveMonitorRef.current = opts.getLiveMonitor;
|
|
1071
|
+
const tick = (0, import_react3.useCallback)(async () => {
|
|
1072
|
+
if (inFlightRef.current || disabledRef.current || pinsRef.current.length === 0) return;
|
|
1073
|
+
inFlightRef.current = true;
|
|
1074
|
+
try {
|
|
1075
|
+
const snap = await getLiveMonitorRef.current(pinsRef.current);
|
|
1076
|
+
if (snap === null) {
|
|
1077
|
+
disabledRef.current = true;
|
|
1078
|
+
applySnapshot(null);
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
applySnapshot(snap);
|
|
1082
|
+
} catch {
|
|
1083
|
+
} finally {
|
|
1084
|
+
inFlightRef.current = false;
|
|
1085
|
+
scheduleRef.current();
|
|
1086
|
+
}
|
|
1087
|
+
}, [applySnapshot]);
|
|
1088
|
+
const scheduleRef = (0, import_react3.useRef)(() => {
|
|
1089
|
+
});
|
|
1090
|
+
scheduleRef.current = () => {
|
|
1091
|
+
window.clearTimeout(timerRef.current);
|
|
1092
|
+
if (disabledRef.current || pinsRef.current.length === 0 || document.visibilityState === "hidden") return;
|
|
1093
|
+
const hinted = (snapshotRef.current?.nextPollSeconds ?? DEFAULT_POLL_MS / 1e3) * 1e3;
|
|
1094
|
+
timerRef.current = window.setTimeout(() => void tick(), Math.max(MIN_POLL_MS, hinted));
|
|
1095
|
+
};
|
|
1096
|
+
const prevPinsLengthRef = (0, import_react3.useRef)(0);
|
|
1097
|
+
(0, import_react3.useEffect)(() => {
|
|
1098
|
+
const wasEmpty = prevPinsLengthRef.current === 0;
|
|
1099
|
+
prevPinsLengthRef.current = pins.length;
|
|
1100
|
+
if (pins.length === 0) {
|
|
1101
|
+
window.clearTimeout(timerRef.current);
|
|
1102
|
+
setActiveTabState("chat");
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
if (wasEmpty) void tick();
|
|
1106
|
+
}, [pins.length, tick]);
|
|
1107
|
+
const prevIsOpenRef = (0, import_react3.useRef)(false);
|
|
1108
|
+
(0, import_react3.useEffect)(() => {
|
|
1109
|
+
const wasClosed = !prevIsOpenRef.current;
|
|
1110
|
+
prevIsOpenRef.current = opts.isOpen;
|
|
1111
|
+
if (wasClosed && opts.isOpen) void tick();
|
|
1112
|
+
}, [opts.isOpen, tick]);
|
|
1113
|
+
(0, import_react3.useEffect)(() => {
|
|
1114
|
+
const onVisibility = () => {
|
|
1115
|
+
if (document.visibilityState === "hidden") window.clearTimeout(timerRef.current);
|
|
1116
|
+
else void tick();
|
|
1117
|
+
};
|
|
1118
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
1119
|
+
return () => {
|
|
1120
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
1121
|
+
window.clearTimeout(timerRef.current);
|
|
1122
|
+
};
|
|
1123
|
+
}, [tick]);
|
|
1124
|
+
const setActiveTab = (0, import_react3.useCallback)((tab) => {
|
|
1125
|
+
setActiveTabState(tab);
|
|
1126
|
+
if (tab === "chat") setChatDot(false);
|
|
1127
|
+
if (tab === "matches") {
|
|
1128
|
+
setMatchesDot(false);
|
|
1129
|
+
void tick();
|
|
1130
|
+
}
|
|
1131
|
+
if (tab === "odds") {
|
|
1132
|
+
setOddsDot(false);
|
|
1133
|
+
setLastViewedPrices((prevMap) => {
|
|
1134
|
+
const out = { ...prevMap };
|
|
1135
|
+
for (const pin of pinsRef.current.filter((p) => p.kind !== "match")) {
|
|
1136
|
+
const price = priceForPin(snapshotRef.current, pin);
|
|
1137
|
+
if (price !== void 0) out[pin.key] = price;
|
|
1138
|
+
}
|
|
1139
|
+
return out;
|
|
1140
|
+
});
|
|
1141
|
+
void tick();
|
|
1142
|
+
}
|
|
1143
|
+
}, [tick]);
|
|
1144
|
+
const togglePin = (0, import_react3.useCallback)((pin) => store.toggle(pin), [store]);
|
|
1145
|
+
const isPinned = (0, import_react3.useCallback)((key) => pinsRef.current.some((p) => p.key === key), []);
|
|
1146
|
+
const markChatActivity = (0, import_react3.useCallback)(() => setChatDot(true), []);
|
|
1147
|
+
const markInSlip = (0, import_react3.useCallback)((matchOddsId) => {
|
|
1148
|
+
setInSlip((prev) => prev[matchOddsId] ? prev : { ...prev, [matchOddsId]: true });
|
|
1149
|
+
}, []);
|
|
1150
|
+
return {
|
|
1151
|
+
enabled,
|
|
1152
|
+
pins,
|
|
1153
|
+
snapshot,
|
|
1154
|
+
activeTab,
|
|
1155
|
+
setActiveTab,
|
|
1156
|
+
togglePin,
|
|
1157
|
+
isPinned,
|
|
1158
|
+
chatDot,
|
|
1159
|
+
markChatActivity,
|
|
1160
|
+
matchesDot,
|
|
1161
|
+
oddsDot,
|
|
1162
|
+
lastViewedPrices,
|
|
1163
|
+
inSlip,
|
|
1164
|
+
markInSlip,
|
|
1165
|
+
_setSnapshot: applySnapshot
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
|
|
822
1169
|
// src/assets/logo.ts
|
|
823
1170
|
var SS_LOGO_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjoAAAI6CAYAAAAuSOLAAAAAAXNSR0IArs4c6QAAAJplWElmTU0AKgAAAAgAAwESAAMAAAABAAEAAAExAAIAAAA9AAAAModpAAQAAAABAAAAcAAAAABBZG9iZSBQaG90b3Nob3AgMjYuMTAgKDIwMjUwNzMwLm0uMzE2NiAwN2IxMjM0KSAgKE1hY2ludG9zaCkAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAI6oAMABAAAAAEAAAI6AAAAACwGtVwAAAQwaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPnhtcC5kaWQ6QzBGRTM5NjM5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6QzBGRTM5NjI5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0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";
|
|
824
1171
|
|
|
@@ -876,7 +1223,7 @@ function ChatFab({ label, greeting, popupText, onOpen, onDismissPopup, dismissLa
|
|
|
876
1223
|
}
|
|
877
1224
|
|
|
878
1225
|
// src/components/ChatPanel.tsx
|
|
879
|
-
var
|
|
1226
|
+
var import_react20 = require("react");
|
|
880
1227
|
|
|
881
1228
|
// src/components/ChatHeader.tsx
|
|
882
1229
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
@@ -889,7 +1236,7 @@ function ChatHeader({ onClose, closeLabel = "Close chat" }) {
|
|
|
889
1236
|
}
|
|
890
1237
|
|
|
891
1238
|
// src/components/MessageList.tsx
|
|
892
|
-
var
|
|
1239
|
+
var import_react18 = require("react");
|
|
893
1240
|
|
|
894
1241
|
// src/components/Markdown.tsx
|
|
895
1242
|
var import_react_markdown = __toESM(require("react-markdown"), 1);
|
|
@@ -907,7 +1254,7 @@ function Markdown({ text }) {
|
|
|
907
1254
|
}
|
|
908
1255
|
|
|
909
1256
|
// src/components/EntityCardList.tsx
|
|
910
|
-
var
|
|
1257
|
+
var import_react4 = require("react");
|
|
911
1258
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
912
1259
|
var MAX_VISIBLE = 3;
|
|
913
1260
|
var RECORD_RE = /^(\d+)-(\d+)-(\d+)$/;
|
|
@@ -991,7 +1338,7 @@ function ScopeTabs({ scopes, active, onSelect }) {
|
|
|
991
1338
|
)) });
|
|
992
1339
|
}
|
|
993
1340
|
function EntityCardItem({ c }) {
|
|
994
|
-
const [active, setActive] = (0,
|
|
1341
|
+
const [active, setActive] = (0, import_react4.useState)(0);
|
|
995
1342
|
const hasBody = c.scopes.length > 0;
|
|
996
1343
|
if (!hasBody) {
|
|
997
1344
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ss-w-ecard ss-w-ecard-bare", "data-kind": c.kind, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(CardHeader, { c, showScopeCrest: false }) });
|
|
@@ -1005,7 +1352,7 @@ function EntityCardItem({ c }) {
|
|
|
1005
1352
|
] });
|
|
1006
1353
|
}
|
|
1007
1354
|
function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMoreLabel = (n) => `Show ${n} more` }) {
|
|
1008
|
-
const [expanded, setExpanded] = (0,
|
|
1355
|
+
const [expanded, setExpanded] = (0, import_react4.useState)(false);
|
|
1009
1356
|
if (cards.length === 0) return null;
|
|
1010
1357
|
const visible = expanded ? cards : cards.slice(0, MAX_VISIBLE);
|
|
1011
1358
|
const overflow = cards.length - MAX_VISIBLE;
|
|
@@ -1016,46 +1363,18 @@ function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMore
|
|
|
1016
1363
|
}
|
|
1017
1364
|
|
|
1018
1365
|
// src/components/BettingInsightList.tsx
|
|
1019
|
-
var
|
|
1366
|
+
var import_react9 = require("react");
|
|
1020
1367
|
|
|
1021
1368
|
// src/components/AddToSlipButton.tsx
|
|
1022
|
-
var
|
|
1369
|
+
var import_react6 = require("react");
|
|
1023
1370
|
var import_widget_sdk4 = require("@sensiblestats/widget-sdk");
|
|
1024
1371
|
|
|
1025
|
-
// src/slip.ts
|
|
1026
|
-
var ADD_TO_SLIP_TIMEOUT_MS = 1e4;
|
|
1027
|
-
function wasAdded(result) {
|
|
1028
|
-
if (!result) return true;
|
|
1029
|
-
if (result.status === "price_changed") return result.accepted;
|
|
1030
|
-
return result.status === "added";
|
|
1031
|
-
}
|
|
1032
|
-
function isTerminal(result) {
|
|
1033
|
-
if (!result) return true;
|
|
1034
|
-
if (result.status === "price_changed") return result.accepted;
|
|
1035
|
-
return result.status === "added" || result.status === "duplicate";
|
|
1036
|
-
}
|
|
1037
|
-
function resultToToast(result, shownOdds, ui) {
|
|
1038
|
-
if (!result) return { kind: "success", text: ui.slipAdded(void 0) };
|
|
1039
|
-
switch (result.status) {
|
|
1040
|
-
case "added":
|
|
1041
|
-
return { kind: "success", text: ui.slipAdded(result.slip?.selectionCount) };
|
|
1042
|
-
case "duplicate":
|
|
1043
|
-
return { kind: "success", text: ui.slipDuplicate };
|
|
1044
|
-
case "price_changed":
|
|
1045
|
-
return result.accepted ? { kind: "success", text: ui.slipPriceChanged(shownOdds, result.newOddsDecimal.toFixed(2)) } : { kind: "error", text: ui.slipPriceNotAccepted(shownOdds, result.newOddsDecimal.toFixed(2)) };
|
|
1046
|
-
case "rejected":
|
|
1047
|
-
if (result.reason === "login_required") return { kind: "error", text: ui.slipLoginRequired };
|
|
1048
|
-
if (result.reason === "suspended") return { kind: "error", text: ui.slipSuspended };
|
|
1049
|
-
return { kind: "error", text: result.message ?? ui.slipFailed };
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
|
|
1053
1372
|
// src/components/Toast.tsx
|
|
1054
|
-
var
|
|
1373
|
+
var import_react5 = require("react");
|
|
1055
1374
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1056
1375
|
var DISMISS_MS = 4e3;
|
|
1057
1376
|
function Toast({ toast, onDismiss }) {
|
|
1058
|
-
(0,
|
|
1377
|
+
(0, import_react5.useEffect)(() => {
|
|
1059
1378
|
if (!toast) return;
|
|
1060
1379
|
const timer = setTimeout(onDismiss, DISMISS_MS);
|
|
1061
1380
|
return () => clearTimeout(timer);
|
|
@@ -1073,10 +1392,10 @@ function withTimeout(value) {
|
|
|
1073
1392
|
]);
|
|
1074
1393
|
}
|
|
1075
1394
|
function SlipButton({ selection, shownOdds, marketName, slip, ui }) {
|
|
1076
|
-
const [pending, setPending] = (0,
|
|
1077
|
-
const [settled, setSettled] = (0,
|
|
1078
|
-
const [toast, setToast] = (0,
|
|
1079
|
-
const dismiss = (0,
|
|
1395
|
+
const [pending, setPending] = (0, import_react6.useState)(false);
|
|
1396
|
+
const [settled, setSettled] = (0, import_react6.useState)(false);
|
|
1397
|
+
const [toast, setToast] = (0, import_react6.useState)(null);
|
|
1398
|
+
const dismiss = (0, import_react6.useCallback)(() => setToast(null), []);
|
|
1080
1399
|
const handler = slip.onAddToSlip;
|
|
1081
1400
|
if (!ui || !handler || !selection) return null;
|
|
1082
1401
|
const onClick = async () => {
|
|
@@ -1140,53 +1459,88 @@ function OddsMovementBadge({
|
|
|
1140
1459
|
}
|
|
1141
1460
|
|
|
1142
1461
|
// src/components/Crest.tsx
|
|
1143
|
-
var
|
|
1462
|
+
var import_react7 = require("react");
|
|
1144
1463
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1145
1464
|
function initials2(name) {
|
|
1146
1465
|
return (name ?? "").trim().slice(0, 1).toUpperCase() || "?";
|
|
1147
1466
|
}
|
|
1148
1467
|
function Crest2({ url, name, kind }) {
|
|
1149
1468
|
const cls = kind === "comp" ? "ss-w-bi-comp-logo" : "ss-w-bi-crest";
|
|
1150
|
-
const [failed, setFailed] = (0,
|
|
1469
|
+
const [failed, setFailed] = (0, import_react7.useState)(false);
|
|
1151
1470
|
if (url && !failed) {
|
|
1152
1471
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
1153
1472
|
}
|
|
1154
1473
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: `${cls} ss-w-bi-crest-mono`, "aria-hidden": "true", children: initials2(name) });
|
|
1155
1474
|
}
|
|
1156
1475
|
|
|
1157
|
-
// src/components/
|
|
1476
|
+
// src/components/PinToggle.tsx
|
|
1477
|
+
var import_react8 = require("react");
|
|
1158
1478
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1479
|
+
function PinToggle({ pin, monitor, ui }) {
|
|
1480
|
+
const [toast, setToast] = (0, import_react8.useState)(null);
|
|
1481
|
+
const dismiss = (0, import_react8.useCallback)(() => setToast(null), []);
|
|
1482
|
+
if (!monitor || !monitor.enabled) return null;
|
|
1483
|
+
const key = pinKey(pin);
|
|
1484
|
+
const pinned = monitor.isPinned(key);
|
|
1485
|
+
const labels = pin.kind === "match" ? { pin: ui.matchPinLabel, unpin: ui.matchUnpinLabel } : { pin: ui.pinLabel, unpin: ui.unpinLabel };
|
|
1486
|
+
const onClick = () => {
|
|
1487
|
+
const result = monitor.togglePin({ ...pin, key });
|
|
1488
|
+
if (result === "match_limit") {
|
|
1489
|
+
setToast({ kind: "error", text: ui.matchLimitToast });
|
|
1490
|
+
} else if (result === "market_limit") {
|
|
1491
|
+
setToast({ kind: "error", text: ui.marketLimitToast });
|
|
1492
|
+
}
|
|
1493
|
+
};
|
|
1494
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ss-w-pin-wrap", children: [
|
|
1495
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1496
|
+
"button",
|
|
1497
|
+
{
|
|
1498
|
+
type: "button",
|
|
1499
|
+
className: "ss-w-pin",
|
|
1500
|
+
"data-on": pinned || void 0,
|
|
1501
|
+
"aria-pressed": pinned,
|
|
1502
|
+
"aria-label": pinned ? labels.unpin : labels.pin,
|
|
1503
|
+
onClick,
|
|
1504
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { fill: "currentColor", d: "M9.5 1.5 14.5 6.5 13 8l-.5-.5-3 3 .3 2.2-1.4 1.4L5.6 11.3l-3.3 3.3-1-1 3.3-3.3L1.9 7.5l1.4-1.4 2.2.3 3-3L8 2.9z" }) })
|
|
1505
|
+
}
|
|
1506
|
+
),
|
|
1507
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Toast, { toast, onDismiss: dismiss })
|
|
1508
|
+
] });
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// src/components/BettingInsightList.tsx
|
|
1512
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1159
1513
|
function StatRows({ stats }) {
|
|
1160
|
-
return /* @__PURE__ */ (0,
|
|
1161
|
-
/* @__PURE__ */ (0,
|
|
1162
|
-
/* @__PURE__ */ (0,
|
|
1514
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-bi-rows", children: stats.map((s) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-bi-row", children: [
|
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-row-lbl", children: s.label }),
|
|
1516
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-row-num", children: s.value })
|
|
1163
1517
|
] }, `${s.label}:${s.value}`)) });
|
|
1164
1518
|
}
|
|
1165
1519
|
function ScopedStats({ scopes }) {
|
|
1166
|
-
const [active, setActive] = (0,
|
|
1520
|
+
const [active, setActive] = (0, import_react9.useState)(0);
|
|
1167
1521
|
const current = scopes[active] ?? scopes[0] ?? { key: "", label: "", stats: [] };
|
|
1168
|
-
return /* @__PURE__ */ (0,
|
|
1169
|
-
/* @__PURE__ */ (0,
|
|
1170
|
-
/* @__PURE__ */ (0,
|
|
1522
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-bi-scoped", children: [
|
|
1523
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-bi-scopes", role: "group", children: scopes.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "ss-w-bi-chip", "aria-pressed": i === active, onClick: () => setActive(i), children: s.label }, s.key)) }),
|
|
1524
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(StatRows, { stats: current.stats }, current.key)
|
|
1171
1525
|
] });
|
|
1172
1526
|
}
|
|
1173
1527
|
function hasStatsContent(it) {
|
|
1174
1528
|
return !!it.scopes && it.scopes.length >= 2 || it.stats.length > 0;
|
|
1175
1529
|
}
|
|
1176
1530
|
function ReasonStrip({ it, ui }) {
|
|
1177
|
-
const [open, setOpen] = (0,
|
|
1531
|
+
const [open, setOpen] = (0, import_react9.useState)(false);
|
|
1178
1532
|
const hasScopes = !!it.scopes && it.scopes.length >= 2;
|
|
1179
1533
|
const hasStats = hasStatsContent(it);
|
|
1180
1534
|
const hasText = !!it.text;
|
|
1181
1535
|
if (!hasText && !hasStats) return null;
|
|
1182
1536
|
const expandable = hasStats || (it.text?.length ?? 0) > 90;
|
|
1183
|
-
return /* @__PURE__ */ (0,
|
|
1184
|
-
/* @__PURE__ */ (0,
|
|
1185
|
-
/* @__PURE__ */ (0,
|
|
1186
|
-
hasText ? /* @__PURE__ */ (0,
|
|
1187
|
-
open && hasStats ? hasScopes ? /* @__PURE__ */ (0,
|
|
1537
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-bi-reason", children: [
|
|
1538
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-chart", "aria-hidden": "true" }),
|
|
1539
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-bi-reason-body", children: [
|
|
1540
|
+
hasText ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: `ss-w-bi-text${open ? "" : " ss-w-bi-text-clamp"}`, children: it.text }) : null,
|
|
1541
|
+
open && hasStats ? hasScopes ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ScopedStats, { scopes: it.scopes }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(StatRows, { stats: it.stats }) : null
|
|
1188
1542
|
] }),
|
|
1189
|
-
expandable ? /* @__PURE__ */ (0,
|
|
1543
|
+
expandable ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1190
1544
|
"button",
|
|
1191
1545
|
{
|
|
1192
1546
|
type: "button",
|
|
@@ -1194,166 +1548,214 @@ function ReasonStrip({ it, ui }) {
|
|
|
1194
1548
|
"aria-expanded": open,
|
|
1195
1549
|
"aria-label": open ? ui?.hideStats ?? "Hide stats" : ui?.showStats ?? "Show stats",
|
|
1196
1550
|
onClick: () => setOpen((v) => !v),
|
|
1197
|
-
children: /* @__PURE__ */ (0,
|
|
1551
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `ss-w-bi-arrow${open ? " ss-w-bi-arrow-open" : ""}`, "aria-hidden": "true" })
|
|
1198
1552
|
}
|
|
1199
1553
|
) : null
|
|
1200
1554
|
] });
|
|
1201
1555
|
}
|
|
1202
1556
|
function CardFixture({ it }) {
|
|
1203
1557
|
if (it.homeTeamName && it.awayTeamName) {
|
|
1204
|
-
return /* @__PURE__ */ (0,
|
|
1205
|
-
/* @__PURE__ */ (0,
|
|
1206
|
-
/* @__PURE__ */ (0,
|
|
1207
|
-
/* @__PURE__ */ (0,
|
|
1208
|
-
/* @__PURE__ */ (0,
|
|
1209
|
-
/* @__PURE__ */ (0,
|
|
1558
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
1559
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Crest2, { kind: "team", url: it.homeCrest, name: it.homeTeamName }),
|
|
1560
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-team", children: it.homeTeamName }),
|
|
1561
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-vs", "aria-hidden": "true", children: "vs" }),
|
|
1562
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-team", children: it.awayTeamName }),
|
|
1563
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Crest2, { kind: "team", url: it.awayCrest, name: it.awayTeamName })
|
|
1210
1564
|
] });
|
|
1211
1565
|
}
|
|
1212
|
-
if (it.fixture) return /* @__PURE__ */ (0,
|
|
1566
|
+
if (it.fixture) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-fixture-txt", children: it.fixture });
|
|
1213
1567
|
if (it.competition) {
|
|
1214
|
-
return /* @__PURE__ */ (0,
|
|
1215
|
-
/* @__PURE__ */ (0,
|
|
1216
|
-
/* @__PURE__ */ (0,
|
|
1568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
1569
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Crest2, { kind: "comp", url: it.competitionCrest, name: it.competition }),
|
|
1570
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-comp", children: it.competition })
|
|
1217
1571
|
] });
|
|
1218
1572
|
}
|
|
1219
1573
|
return null;
|
|
1220
1574
|
}
|
|
1221
|
-
function InsightCard({ it, ui, slip }) {
|
|
1575
|
+
function InsightCard({ it, ui, slip, monitor }) {
|
|
1222
1576
|
const live = it.isLive || it.phase === "live";
|
|
1223
1577
|
const kickoff = it.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(it.kickoffUtc) : void 0;
|
|
1224
1578
|
const hasNamedTeams = !!it.homeTeamName && !!it.awayTeamName;
|
|
1225
1579
|
const leftIsFixture = hasNamedTeams || !!it.fixture;
|
|
1226
1580
|
const compInMeta = leftIsFixture && !!it.competition;
|
|
1227
|
-
const
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
/* @__PURE__ */ (0,
|
|
1232
|
-
|
|
1233
|
-
|
|
1581
|
+
const showPin = !!monitor && it.pinEnabled;
|
|
1582
|
+
const showHeader = leftIsFixture || !!it.competition || live || !!kickoff || showPin;
|
|
1583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-binsight", children: [
|
|
1584
|
+
showHeader ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-bi-header", children: [
|
|
1585
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-header-left", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CardFixture, { it }) }),
|
|
1586
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ss-w-bi-header-right", children: [
|
|
1587
|
+
live ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ss-w-bi-live", children: [
|
|
1588
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-live-dot", "aria-hidden": "true" }),
|
|
1234
1589
|
ui?.liveLabel ?? "Live"
|
|
1235
1590
|
] }) : null,
|
|
1236
|
-
compInMeta ? /* @__PURE__ */ (0,
|
|
1237
|
-
/* @__PURE__ */ (0,
|
|
1238
|
-
/* @__PURE__ */ (0,
|
|
1591
|
+
compInMeta ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ss-w-bi-comp-meta", children: [
|
|
1592
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Crest2, { kind: "comp", url: it.competitionCrest, name: it.competition }),
|
|
1593
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-comp", children: it.competition })
|
|
1239
1594
|
] }) : null,
|
|
1240
|
-
kickoff ? /* @__PURE__ */ (0,
|
|
1595
|
+
kickoff ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ss-w-bi-kick", children: [
|
|
1241
1596
|
kickoff.dayLabel,
|
|
1242
1597
|
" ",
|
|
1243
1598
|
kickoff.time
|
|
1244
|
-
] }) : null
|
|
1599
|
+
] }) : null,
|
|
1600
|
+
showPin && ui ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PinToggle, { ui, monitor, pin: { kind: "match", matchId: it.matchId } }) : null
|
|
1245
1601
|
] })
|
|
1246
1602
|
] }) : null,
|
|
1247
|
-
/* @__PURE__ */ (0,
|
|
1248
|
-
/* @__PURE__ */ (0,
|
|
1249
|
-
/* @__PURE__ */ (0,
|
|
1250
|
-
it.selection ? /* @__PURE__ */ (0,
|
|
1251
|
-
/* @__PURE__ */ (0,
|
|
1252
|
-
/* @__PURE__ */ (0,
|
|
1603
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "ss-w-bi-action-row", children: [
|
|
1604
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ss-w-bi-pick", children: [
|
|
1605
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-market", children: it.market }),
|
|
1606
|
+
it.selection ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
1607
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-pick-dot", "aria-hidden": "true", children: "\xB7" }),
|
|
1608
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-sel", children: it.selection })
|
|
1253
1609
|
] }) : null
|
|
1254
1610
|
] }),
|
|
1255
|
-
it.odds ? /* @__PURE__ */ (0,
|
|
1256
|
-
/* @__PURE__ */ (0,
|
|
1257
|
-
/* @__PURE__ */ (0,
|
|
1258
|
-
it.bookmaker ? /* @__PURE__ */ (0,
|
|
1611
|
+
it.odds ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "ss-w-bi-odds", children: [
|
|
1612
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("b", { children: it.odds }),
|
|
1613
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(OddsMovementBadge, { previous: it.previousOdds, current: it.odds, direction: it.movementDirection, ui }),
|
|
1614
|
+
it.bookmaker ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-book", children: it.bookmaker }) : null
|
|
1259
1615
|
] }) : null,
|
|
1260
|
-
/* @__PURE__ */ (0,
|
|
1616
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(AddToSlipButton, { it, slip, ui }),
|
|
1617
|
+
showPin && ui ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1618
|
+
PinToggle,
|
|
1619
|
+
{
|
|
1620
|
+
ui,
|
|
1621
|
+
monitor,
|
|
1622
|
+
pin: {
|
|
1623
|
+
kind: "selection",
|
|
1624
|
+
matchId: it.matchId,
|
|
1625
|
+
marketDeveloperName: it.marketDeveloperName,
|
|
1626
|
+
selectionLabel: it.selectionLabel,
|
|
1627
|
+
line: it.line,
|
|
1628
|
+
matchOddsId: it.matchOddsId
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
) : null
|
|
1261
1632
|
] }),
|
|
1262
|
-
it.isMarketFloor ? /* @__PURE__ */ (0,
|
|
1263
|
-
/* @__PURE__ */ (0,
|
|
1264
|
-
it.disclaimer ? /* @__PURE__ */ (0,
|
|
1633
|
+
it.isMarketFloor ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ss-w-bi-floor", children: ui?.marketFloorLabel ?? "Market price \xB7 not a value pick" }) : null,
|
|
1634
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ReasonStrip, { it, ui }),
|
|
1635
|
+
it.disclaimer ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "ss-w-bi-disc", children: it.disclaimer }) : null
|
|
1265
1636
|
] });
|
|
1266
1637
|
}
|
|
1267
|
-
function BettingInsightList({ insights, ui, slip }) {
|
|
1638
|
+
function BettingInsightList({ insights, ui, slip, monitor }) {
|
|
1268
1639
|
if (!insights || insights.length === 0) return null;
|
|
1269
|
-
return /* @__PURE__ */ (0,
|
|
1640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ss-w-binsights", children: insights.map((it) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(InsightCard, { it, ui, slip, monitor }, it.id)) });
|
|
1270
1641
|
}
|
|
1271
1642
|
|
|
1272
1643
|
// src/components/MarketOddsCardList.tsx
|
|
1273
|
-
var
|
|
1274
|
-
var
|
|
1275
|
-
function OddsRow({ vm, row, ui, slip }) {
|
|
1644
|
+
var import_react10 = require("react");
|
|
1645
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1646
|
+
function OddsRow({ vm, row, ui, slip, inSlipIds }) {
|
|
1276
1647
|
const selection = vm.addToSlipEnabled ? marketOddsRowToSlipSelection(vm, row, slip.conversationId) : null;
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
/* @__PURE__ */ (0,
|
|
1280
|
-
/* @__PURE__ */ (0,
|
|
1281
|
-
/* @__PURE__ */ (0,
|
|
1648
|
+
const inSlip = !!inSlipIds && row.matchOddsId != null && !!inSlipIds[row.matchOddsId];
|
|
1649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-mo-row", children: [
|
|
1650
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-mo-sel", children: row.selection }),
|
|
1651
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(OddsMovementBadge, { previous: row.previousOdds, current: row.odds, direction: row.movementDirection, ui }),
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-mo-price", children: row.odds }),
|
|
1653
|
+
inSlip && ui ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "ss-w-mon-inslip", children: [
|
|
1654
|
+
"\u2713 ",
|
|
1655
|
+
ui.inSlipLabel
|
|
1656
|
+
] }) : null,
|
|
1657
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SlipButton, { selection, shownOdds: row.odds, marketName: vm.market, slip, ui })
|
|
1282
1658
|
] });
|
|
1283
1659
|
}
|
|
1284
|
-
function MarketOddsCard({ vm, ui, slip }) {
|
|
1285
|
-
const [open, setOpen] = (0,
|
|
1660
|
+
function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds }) {
|
|
1661
|
+
const [open, setOpen] = (0, import_react10.useState)(false);
|
|
1286
1662
|
const kickoff = vm.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(vm.kickoffUtc) : void 0;
|
|
1287
1663
|
const hasNamedTeams = !!vm.homeTeamName && !!vm.awayTeamName;
|
|
1288
|
-
const
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
/* @__PURE__ */ (0,
|
|
1664
|
+
const showPin = !!monitor && vm.pinEnabled;
|
|
1665
|
+
const showHeader = !!vm.competition || vm.isLive || !!kickoff || showPin;
|
|
1666
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-mocard", children: [
|
|
1667
|
+
showHeader ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-bi-header", children: [
|
|
1668
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-bi-header-left", children: vm.competition ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1669
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Crest2, { kind: "comp", url: vm.competitionCrest, name: vm.competition }),
|
|
1670
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-bi-comp", children: vm.competition })
|
|
1294
1671
|
] }) : null }),
|
|
1295
|
-
/* @__PURE__ */ (0,
|
|
1296
|
-
vm.isLive ? /* @__PURE__ */ (0,
|
|
1297
|
-
/* @__PURE__ */ (0,
|
|
1672
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "ss-w-bi-header-right", children: [
|
|
1673
|
+
vm.isLive ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "ss-w-bi-live", children: [
|
|
1674
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-bi-live-dot", "aria-hidden": "true" }),
|
|
1298
1675
|
ui?.liveLabel ?? "Live"
|
|
1299
1676
|
] }) : null,
|
|
1300
|
-
kickoff ? /* @__PURE__ */ (0,
|
|
1677
|
+
kickoff ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "ss-w-bi-kick", children: [
|
|
1301
1678
|
kickoff.dayLabel,
|
|
1302
1679
|
" ",
|
|
1303
1680
|
kickoff.time
|
|
1304
|
-
] }) : null
|
|
1681
|
+
] }) : null,
|
|
1682
|
+
showPin && ui ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1683
|
+
PinToggle,
|
|
1684
|
+
{
|
|
1685
|
+
ui,
|
|
1686
|
+
monitor,
|
|
1687
|
+
pin: { kind: "market", matchId: vm.matchId, marketDeveloperName: vm.marketDeveloperName, line: vm.mainLine }
|
|
1688
|
+
}
|
|
1689
|
+
) : null
|
|
1305
1690
|
] })
|
|
1306
1691
|
] }) : null,
|
|
1307
|
-
hasNamedTeams || vm.fixture || vm.market ? /* @__PURE__ */ (0,
|
|
1308
|
-
hasNamedTeams ? /* @__PURE__ */ (0,
|
|
1309
|
-
/* @__PURE__ */ (0,
|
|
1310
|
-
/* @__PURE__ */ (0,
|
|
1311
|
-
/* @__PURE__ */ (0,
|
|
1312
|
-
/* @__PURE__ */ (0,
|
|
1313
|
-
/* @__PURE__ */ (0,
|
|
1314
|
-
] }) : vm.fixture ? /* @__PURE__ */ (0,
|
|
1315
|
-
vm.market ? /* @__PURE__ */ (0,
|
|
1692
|
+
hasNamedTeams || vm.fixture || vm.market ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-mo-sub", children: [
|
|
1693
|
+
hasNamedTeams ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-bi-fixture", children: [
|
|
1694
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Crest2, { kind: "team", url: vm.homeCrest, name: vm.homeTeamName }),
|
|
1695
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-bi-team", children: vm.homeTeamName }),
|
|
1696
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-bi-vs", "aria-hidden": "true", children: "vs" }),
|
|
1697
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-bi-team", children: vm.awayTeamName }),
|
|
1698
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Crest2, { kind: "team", url: vm.awayCrest, name: vm.awayTeamName })
|
|
1699
|
+
] }) : vm.fixture ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-mo-teams", children: vm.fixture }) : null,
|
|
1700
|
+
vm.market ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-mo-market", children: vm.market }) : null
|
|
1316
1701
|
] }) : null,
|
|
1317
|
-
/* @__PURE__ */ (0,
|
|
1318
|
-
vm.mainRows.map((row) => /* @__PURE__ */ (0,
|
|
1319
|
-
open ? vm.moreRows.map((row) => /* @__PURE__ */ (0,
|
|
1702
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-mo-rows", children: [
|
|
1703
|
+
vm.mainRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(OddsRow, { vm, row, ui, slip, inSlipIds }, row.key)),
|
|
1704
|
+
open ? vm.moreRows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(OddsRow, { vm, row, ui, slip, inSlipIds }, row.key)) : null
|
|
1320
1705
|
] }),
|
|
1321
|
-
vm.moreRows.length > 0 ? /* @__PURE__ */ (0,
|
|
1322
|
-
/* @__PURE__ */ (0,
|
|
1323
|
-
/* @__PURE__ */ (0,
|
|
1706
|
+
vm.moreRows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("button", { type: "button", className: "ss-w-mo-more", "aria-expanded": open, onClick: () => setOpen((v) => !v), children: [
|
|
1707
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: open ? ui?.hideLines ?? "Hide lines" : `${ui?.moreLines ?? "More lines"} (${vm.moreRows.length})` }),
|
|
1708
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: `ss-w-mo-more-chev${open ? " ss-w-mo-more-chev-up" : ""}`, "aria-hidden": "true" })
|
|
1324
1709
|
] }) : null,
|
|
1325
|
-
vm.bookmaker ? /* @__PURE__ */ (0,
|
|
1326
|
-
vm.disclaimer ? /* @__PURE__ */ (0,
|
|
1710
|
+
vm.bookmaker ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ss-w-mo-foot", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: vm.bookmaker }) }) : null,
|
|
1711
|
+
vm.disclaimer ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "ss-w-bi-disc", children: vm.disclaimer }) : null
|
|
1327
1712
|
] });
|
|
1328
1713
|
}
|
|
1329
|
-
function MarketOddsCardList({ cards, ui, slip }) {
|
|
1714
|
+
function MarketOddsCardList({ cards, ui, slip, monitor, inSlipIds }) {
|
|
1330
1715
|
if (!cards || cards.length === 0) return null;
|
|
1331
|
-
return /* @__PURE__ */ (0,
|
|
1716
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ss-w-mocards", children: cards.map((vm) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MarketOddsCard, { vm, ui, slip, monitor, inSlipIds }, vm.id)) });
|
|
1332
1717
|
}
|
|
1333
1718
|
|
|
1334
1719
|
// src/components/OddsMovementCard.tsx
|
|
1335
|
-
var
|
|
1720
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1336
1721
|
function directionWord(vm, ui) {
|
|
1337
1722
|
if (vm.direction === "shortened") return ui?.oddsShortened ?? "shortened";
|
|
1338
1723
|
if (vm.direction === "drifted") return ui?.oddsDrifted ?? "drifted";
|
|
1339
1724
|
return "";
|
|
1340
1725
|
}
|
|
1341
|
-
function OddsMovementCard({ vm, ui }) {
|
|
1726
|
+
function OddsMovementCard({ vm, ui, monitor }) {
|
|
1342
1727
|
const word = directionWord(vm, ui);
|
|
1343
1728
|
const drift = word ? `, ${word}` : "";
|
|
1344
1729
|
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}.`;
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
/* @__PURE__ */ (0,
|
|
1730
|
+
const showPin = !!monitor && vm.pinEnabled;
|
|
1731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-omcard", children: [
|
|
1732
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-om-head", children: [
|
|
1733
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-om-market", children: vm.market }),
|
|
1734
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-om-tag", children: ui?.priceMovement ?? "Price movement" }),
|
|
1735
|
+
showPin && ui ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1736
|
+
PinToggle,
|
|
1737
|
+
{
|
|
1738
|
+
ui,
|
|
1739
|
+
monitor,
|
|
1740
|
+
pin: {
|
|
1741
|
+
kind: "selection",
|
|
1742
|
+
matchId: vm.matchId,
|
|
1743
|
+
marketDeveloperName: vm.marketDeveloperName,
|
|
1744
|
+
selectionLabel: vm.selectionLabel,
|
|
1745
|
+
line: vm.line,
|
|
1746
|
+
withHistory: true,
|
|
1747
|
+
matchOddsId: vm.matchOddsId
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
) : null
|
|
1349
1751
|
] }),
|
|
1350
|
-
vm.fixture ? /* @__PURE__ */ (0,
|
|
1351
|
-
/* @__PURE__ */ (0,
|
|
1352
|
-
vm.competition ? /* @__PURE__ */ (0,
|
|
1752
|
+
vm.fixture ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-om-fixture", children: [
|
|
1753
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: vm.fixture }),
|
|
1754
|
+
vm.competition ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "ss-w-om-comp", children: vm.competition }) : null
|
|
1353
1755
|
] }) : null,
|
|
1354
|
-
/* @__PURE__ */ (0,
|
|
1355
|
-
/* @__PURE__ */ (0,
|
|
1356
|
-
vm.geometry === null ? /* @__PURE__ */ (0,
|
|
1756
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ss-w-om-sel", children: vm.selection }),
|
|
1757
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(OddsMovementBadge, { previous: vm.opening, current: vm.current, direction: vm.direction, ui }),
|
|
1758
|
+
vm.geometry === null ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("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__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1357
1759
|
"svg",
|
|
1358
1760
|
{
|
|
1359
1761
|
className: "ss-w-om-chart",
|
|
@@ -1362,83 +1764,83 @@ function OddsMovementCard({ vm, ui }) {
|
|
|
1362
1764
|
role: "img",
|
|
1363
1765
|
"aria-label": aria,
|
|
1364
1766
|
children: [
|
|
1365
|
-
vm.geometry.gridlines.map((g) => /* @__PURE__ */ (0,
|
|
1366
|
-
/* @__PURE__ */ (0,
|
|
1367
|
-
/* @__PURE__ */ (0,
|
|
1767
|
+
vm.geometry.gridlines.map((g) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("g", { children: [
|
|
1768
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("line", { className: "ss-w-om-grid", x1: 40, y1: g.y, x2: CHART_VIEW_W - 8, y2: g.y }),
|
|
1769
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("text", { className: "ss-w-om-ylab", x: 34, y: g.y + 3, textAnchor: "end", children: g.price.toFixed(2) })
|
|
1368
1770
|
] }, g.price)),
|
|
1369
|
-
/* @__PURE__ */ (0,
|
|
1370
|
-
vm.geometry.markers.map((m, i) => /* @__PURE__ */ (0,
|
|
1371
|
-
ui?.chartTimeLabel ? /* @__PURE__ */ (0,
|
|
1372
|
-
/* @__PURE__ */ (0,
|
|
1373
|
-
/* @__PURE__ */ (0,
|
|
1374
|
-
] }) : /* @__PURE__ */ (0,
|
|
1771
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { className: "ss-w-om-line", d: vm.geometry.path, fill: "none" }),
|
|
1772
|
+
vm.geometry.markers.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("circle", { className: "ss-w-om-dot", cx: m.x, cy: m.y, r: 2.5 }, i)),
|
|
1773
|
+
ui?.chartTimeLabel ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
1774
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("text", { className: "ss-w-om-xlab", x: 40, y: CHART_VIEW_H - 8, textAnchor: "start", children: ui.chartTimeLabel(vm.geometry.startMs) }),
|
|
1775
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("text", { className: "ss-w-om-xlab", x: CHART_VIEW_W - 8, y: CHART_VIEW_H - 8, textAnchor: "end", children: ui.chartTimeLabel(vm.geometry.endMs) })
|
|
1776
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("text", { className: "ss-w-om-xlab", x: 40, y: CHART_VIEW_H - 8, children: ui?.movementWindow ? ui.movementWindow(vm.windowHours) : `Last ${vm.windowHours}h` })
|
|
1375
1777
|
]
|
|
1376
1778
|
}
|
|
1377
1779
|
),
|
|
1378
|
-
/* @__PURE__ */ (0,
|
|
1379
|
-
/* @__PURE__ */ (0,
|
|
1780
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "ss-w-om-foot", children: [
|
|
1781
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
|
|
1380
1782
|
ui?.openingLabel ?? "Opening",
|
|
1381
1783
|
" ",
|
|
1382
|
-
/* @__PURE__ */ (0,
|
|
1784
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("b", { children: vm.opening })
|
|
1383
1785
|
] }),
|
|
1384
|
-
/* @__PURE__ */ (0,
|
|
1786
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
|
|
1385
1787
|
ui?.currentLabel ?? "Current",
|
|
1386
1788
|
" ",
|
|
1387
|
-
/* @__PURE__ */ (0,
|
|
1789
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("b", { children: vm.current })
|
|
1388
1790
|
] })
|
|
1389
1791
|
] }),
|
|
1390
|
-
vm.bookmaker ? /* @__PURE__ */ (0,
|
|
1391
|
-
vm.excludedCount > 0 ? /* @__PURE__ */ (0,
|
|
1392
|
-
vm.isSuspended ? /* @__PURE__ */ (0,
|
|
1393
|
-
vm.disclaimer ? /* @__PURE__ */ (0,
|
|
1792
|
+
vm.bookmaker ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ss-w-om-foot", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: vm.bookmaker }) }) : null,
|
|
1793
|
+
vm.excludedCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ss-w-om-excl", children: ui?.excludedSuspended ? ui.excludedSuspended(vm.excludedCount) : `${vm.excludedCount} suspended price(s) excluded from this chart.` }) : null,
|
|
1794
|
+
vm.isSuspended ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ss-w-om-susp", children: ui?.selectionSuspended ?? "This selection is not currently available to bet." }) : null,
|
|
1795
|
+
vm.disclaimer ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ss-w-om-disc", children: vm.disclaimer }) : null
|
|
1394
1796
|
] });
|
|
1395
1797
|
}
|
|
1396
|
-
function OddsMovementCardList({ cards, ui }) {
|
|
1798
|
+
function OddsMovementCardList({ cards, ui, monitor }) {
|
|
1397
1799
|
if (!cards || cards.length === 0) return null;
|
|
1398
|
-
return /* @__PURE__ */ (0,
|
|
1800
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "ss-w-omcards", children: cards.map((vm) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(OddsMovementCard, { vm, ui, monitor }, vm.id)) });
|
|
1399
1801
|
}
|
|
1400
1802
|
|
|
1401
1803
|
// src/components/ActionButtons.tsx
|
|
1402
|
-
var
|
|
1804
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1403
1805
|
function ActionButtons({ actions, loading, disabled, onAct }) {
|
|
1404
1806
|
if (actions.length === 0 && !loading) return null;
|
|
1405
|
-
return /* @__PURE__ */ (0,
|
|
1406
|
-
actions.map((a, i) => /* @__PURE__ */ (0,
|
|
1407
|
-
actions.length === 0 && loading ? /* @__PURE__ */ (0,
|
|
1408
|
-
/* @__PURE__ */ (0,
|
|
1409
|
-
/* @__PURE__ */ (0,
|
|
1807
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ss-w-actions", children: [
|
|
1808
|
+
actions.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: "ss-w-abtn", disabled, onClick: () => onAct(a), children: a.label }, `${a.label}-${i}`)),
|
|
1809
|
+
actions.length === 0 && loading ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
1810
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-abtn-shimmer" }),
|
|
1811
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ss-w-abtn-shimmer" })
|
|
1410
1812
|
] }) : null
|
|
1411
1813
|
] });
|
|
1412
1814
|
}
|
|
1413
1815
|
|
|
1414
1816
|
// src/components/dashboard/DashboardTile.tsx
|
|
1415
|
-
var
|
|
1817
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1416
1818
|
var MAX_CRESTS = 3;
|
|
1417
1819
|
function DashboardTile({ tile, onTap }) {
|
|
1418
1820
|
const spanClass = tile.span === "full" ? "ss-w-dash-tile--full" : "ss-w-dash-tile--half";
|
|
1419
1821
|
const crests = (tile.imageUrls ?? []).slice(0, MAX_CRESTS);
|
|
1420
1822
|
const hasMeta = Boolean(tile.badgeText) || crests.length > 0;
|
|
1421
|
-
return /* @__PURE__ */ (0,
|
|
1422
|
-
/* @__PURE__ */ (0,
|
|
1423
|
-
/* @__PURE__ */ (0,
|
|
1424
|
-
/* @__PURE__ */ (0,
|
|
1425
|
-
tile.subtitle ? /* @__PURE__ */ (0,
|
|
1823
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("button", { type: "button", className: `ss-w-dash-tile ${spanClass}`, onClick: onTap, children: [
|
|
1824
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "ss-w-dash-tile-icon", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(DashboardIcon, { name: tile.icon }) }),
|
|
1825
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "ss-w-dash-tile-body", children: [
|
|
1826
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "ss-w-dash-tile-title", children: tile.title }),
|
|
1827
|
+
tile.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "ss-w-dash-tile-subtitle", children: tile.subtitle }) : null,
|
|
1426
1828
|
hasMeta ? (
|
|
1427
1829
|
// Badge + crests sit on their own row, below the title, instead of sharing the
|
|
1428
1830
|
// icon/chevron row -- at the half-span tile's ~180px width a nowrap badge alone
|
|
1429
1831
|
// (~70px) left the title column at ~22px and forced character-by-character wrapping.
|
|
1430
|
-
/* @__PURE__ */ (0,
|
|
1431
|
-
tile.badgeText ? /* @__PURE__ */ (0,
|
|
1432
|
-
crests.length > 0 ? /* @__PURE__ */ (0,
|
|
1832
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "ss-w-dash-tile-meta", children: [
|
|
1833
|
+
tile.badgeText ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "ss-w-dash-tile-badge", children: tile.badgeText }) : null,
|
|
1834
|
+
crests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "ss-w-dash-tile-crests", children: crests.map((url, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "ss-w-dash-tile-crest", style: { backgroundImage: `url(${url})` }, "aria-hidden": "true" }, `${url}-${i}`)) }) : null
|
|
1433
1835
|
] })
|
|
1434
1836
|
) : null
|
|
1435
1837
|
] }),
|
|
1436
|
-
/* @__PURE__ */ (0,
|
|
1838
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "ss-w-dash-tile-chevron", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChevronIcon, {}) })
|
|
1437
1839
|
] });
|
|
1438
1840
|
}
|
|
1439
1841
|
|
|
1440
1842
|
// src/components/dashboard/GreetingDashboard.tsx
|
|
1441
|
-
var
|
|
1843
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1442
1844
|
var LAYOUT_CLASSES = {
|
|
1443
1845
|
market: "ss-w-dash--market",
|
|
1444
1846
|
goal: "ss-w-dash--goal",
|
|
@@ -1448,109 +1850,109 @@ function layoutClass(layout) {
|
|
|
1448
1850
|
return Object.prototype.hasOwnProperty.call(LAYOUT_CLASSES, layout) ? LAYOUT_CLASSES[layout] : LAYOUT_CLASSES.goal;
|
|
1449
1851
|
}
|
|
1450
1852
|
function GreetingDashboard({ dashboard, onTap }) {
|
|
1451
|
-
return /* @__PURE__ */ (0,
|
|
1452
|
-
/* @__PURE__ */ (0,
|
|
1453
|
-
/* @__PURE__ */ (0,
|
|
1454
|
-
dashboard.subtitle ? /* @__PURE__ */ (0,
|
|
1853
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: `ss-w-dash ${layoutClass(dashboard.layout)}`, children: [
|
|
1854
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "ss-w-dash-head", children: [
|
|
1855
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-dash-title", children: dashboard.title }),
|
|
1856
|
+
dashboard.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-dash-subtitle", children: dashboard.subtitle }) : null
|
|
1455
1857
|
] }),
|
|
1456
|
-
/* @__PURE__ */ (0,
|
|
1457
|
-
dashboard.footerTip ? /* @__PURE__ */ (0,
|
|
1858
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "ss-w-dash-grid", children: dashboard.tiles.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DashboardTile, { tile: t, onTap: () => onTap(t, i) }, `${t.title}-${i}`)) }),
|
|
1859
|
+
dashboard.footerTip ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-dash-foot", children: dashboard.footerTip }) : null
|
|
1458
1860
|
] });
|
|
1459
1861
|
}
|
|
1460
1862
|
|
|
1461
1863
|
// src/components/dashboard/FixtureCard.tsx
|
|
1462
|
-
var
|
|
1864
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1463
1865
|
function teamFormResultClass(result) {
|
|
1464
1866
|
if (result === "W") return "ss-w-fandash-teamform-cell--win";
|
|
1465
1867
|
if (result === "L") return "ss-w-fandash-teamform-cell--loss";
|
|
1466
1868
|
return "ss-w-fandash-teamform-cell--draw";
|
|
1467
1869
|
}
|
|
1468
1870
|
function TeamFormCell({ m, subjectCrestUrl, subjectName }) {
|
|
1469
|
-
const subjectCrest = /* @__PURE__ */ (0,
|
|
1470
|
-
const opponentCrest = /* @__PURE__ */ (0,
|
|
1871
|
+
const subjectCrest = /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Crest2, { url: subjectCrestUrl ?? void 0, name: subjectName, kind: "team" });
|
|
1872
|
+
const opponentCrest = /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Crest2, { url: m.opponentCrestUrl ?? void 0, kind: "team" });
|
|
1471
1873
|
const score = m.teamIsHome ? `${m.teamScore} - ${m.oppScore}` : `${m.oppScore} - ${m.teamScore}`;
|
|
1472
|
-
return /* @__PURE__ */ (0,
|
|
1874
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `ss-w-fandash-teamform-cell ${teamFormResultClass(m.result)}`, children: [
|
|
1473
1875
|
m.teamIsHome ? subjectCrest : opponentCrest,
|
|
1474
|
-
/* @__PURE__ */ (0,
|
|
1876
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-teamform-score", children: score }),
|
|
1475
1877
|
m.teamIsHome ? opponentCrest : subjectCrest
|
|
1476
1878
|
] });
|
|
1477
1879
|
}
|
|
1478
1880
|
var TEAM_FORM_ROWS = 5;
|
|
1479
1881
|
function teamFormRows(data) {
|
|
1480
1882
|
return Array.from({ length: TEAM_FORM_ROWS }, (_, i) => i).flatMap((i) => [
|
|
1481
|
-
/* @__PURE__ */ (0,
|
|
1482
|
-
/* @__PURE__ */ (0,
|
|
1883
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-teamform-slot", children: data.homeForm[i] ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TeamFormCell, { m: data.homeForm[i], subjectCrestUrl: data.homeCrestUrl, subjectName: data.homeName }) : null }, `h-${i}`),
|
|
1884
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-teamform-slot", children: data.awayForm[i] ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TeamFormCell, { m: data.awayForm[i], subjectCrestUrl: data.awayCrestUrl, subjectName: data.awayName }) : null }, `a-${i}`)
|
|
1483
1885
|
]);
|
|
1484
1886
|
}
|
|
1485
1887
|
function FixtureCard({ card }) {
|
|
1486
1888
|
const { data } = card;
|
|
1487
1889
|
const h2h = data.h2H;
|
|
1488
|
-
return /* @__PURE__ */ (0,
|
|
1489
|
-
/* @__PURE__ */ (0,
|
|
1490
|
-
/* @__PURE__ */ (0,
|
|
1890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
1891
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-fixture", children: [
|
|
1892
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "ss-w-fandash-eyebrow", children: [
|
|
1491
1893
|
card.title,
|
|
1492
1894
|
" \xB7 ",
|
|
1493
1895
|
data.competition
|
|
1494
1896
|
] }),
|
|
1495
|
-
/* @__PURE__ */ (0,
|
|
1496
|
-
/* @__PURE__ */ (0,
|
|
1497
|
-
/* @__PURE__ */ (0,
|
|
1498
|
-
/* @__PURE__ */ (0,
|
|
1897
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-fandash-fixture-teams", children: [
|
|
1898
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "ss-w-fandash-fixture-team", children: [
|
|
1899
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Crest2, { url: data.homeCrestUrl ?? void 0, name: data.homeName, kind: "team" }),
|
|
1900
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-fixture-name", children: data.homeName })
|
|
1499
1901
|
] }),
|
|
1500
|
-
/* @__PURE__ */ (0,
|
|
1501
|
-
/* @__PURE__ */ (0,
|
|
1502
|
-
/* @__PURE__ */ (0,
|
|
1503
|
-
/* @__PURE__ */ (0,
|
|
1902
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-fixture-vs", children: "v" }),
|
|
1903
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "ss-w-fandash-fixture-team ss-w-fandash-fixture-team--away", children: [
|
|
1904
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-fixture-name", children: data.awayName }),
|
|
1905
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Crest2, { url: data.awayCrestUrl ?? void 0, name: data.awayName, kind: "team" })
|
|
1504
1906
|
] })
|
|
1505
1907
|
] }),
|
|
1506
|
-
/* @__PURE__ */ (0,
|
|
1507
|
-
/* @__PURE__ */ (0,
|
|
1508
|
-
data.venue ? /* @__PURE__ */ (0,
|
|
1908
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-fandash-fixture-meta", children: [
|
|
1909
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-fixture-kickoff", children: data.kickoffLabel }),
|
|
1910
|
+
data.venue ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "ss-w-fandash-fixture-venue", children: [
|
|
1509
1911
|
" \xB7 ",
|
|
1510
1912
|
data.venue
|
|
1511
1913
|
] }) : null
|
|
1512
1914
|
] })
|
|
1513
1915
|
] }),
|
|
1514
|
-
/* @__PURE__ */ (0,
|
|
1515
|
-
/* @__PURE__ */ (0,
|
|
1516
|
-
/* @__PURE__ */ (0,
|
|
1517
|
-
/* @__PURE__ */ (0,
|
|
1518
|
-
/* @__PURE__ */ (0,
|
|
1519
|
-
/* @__PURE__ */ (0,
|
|
1916
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-lastfive", children: [
|
|
1917
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-eyebrow", children: data.formLabel }),
|
|
1918
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-fandash-teamform-head", children: [
|
|
1919
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "ss-w-fandash-teamform-head-team", children: [
|
|
1920
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Crest2, { url: data.homeCrestUrl ?? void 0, name: data.homeName, kind: "team" }),
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-teamform-head-name", children: data.homeName })
|
|
1520
1922
|
] }),
|
|
1521
|
-
/* @__PURE__ */ (0,
|
|
1522
|
-
/* @__PURE__ */ (0,
|
|
1523
|
-
/* @__PURE__ */ (0,
|
|
1923
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "ss-w-fandash-teamform-head-team", children: [
|
|
1924
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Crest2, { url: data.awayCrestUrl ?? void 0, name: data.awayName, kind: "team" }),
|
|
1925
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-teamform-head-name", children: data.awayName })
|
|
1524
1926
|
] })
|
|
1525
1927
|
] }),
|
|
1526
|
-
/* @__PURE__ */ (0,
|
|
1928
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "ss-w-fandash-teamform-rows", children: teamFormRows(data) })
|
|
1527
1929
|
] }),
|
|
1528
|
-
h2h || data.fact ? /* @__PURE__ */ (0,
|
|
1529
|
-
h2h ? /* @__PURE__ */ (0,
|
|
1530
|
-
/* @__PURE__ */ (0,
|
|
1531
|
-
/* @__PURE__ */ (0,
|
|
1532
|
-
/* @__PURE__ */ (0,
|
|
1533
|
-
/* @__PURE__ */ (0,
|
|
1534
|
-
/* @__PURE__ */ (0,
|
|
1930
|
+
h2h || data.fact ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-h2h", children: [
|
|
1931
|
+
h2h ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
1932
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-eyebrow", children: h2h.label }),
|
|
1933
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "ss-w-fandash-split", children: [
|
|
1934
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "ss-w-fandash-split-cell", children: [
|
|
1935
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-split-value", children: h2h.wins }),
|
|
1936
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-split-label", children: h2h.homeWinsLabel })
|
|
1535
1937
|
] }),
|
|
1536
|
-
/* @__PURE__ */ (0,
|
|
1537
|
-
/* @__PURE__ */ (0,
|
|
1538
|
-
/* @__PURE__ */ (0,
|
|
1938
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "ss-w-fandash-split-cell", children: [
|
|
1939
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-split-value", children: h2h.draws }),
|
|
1940
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-split-label", children: h2h.drawsLabel })
|
|
1539
1941
|
] }),
|
|
1540
|
-
/* @__PURE__ */ (0,
|
|
1541
|
-
/* @__PURE__ */ (0,
|
|
1542
|
-
/* @__PURE__ */ (0,
|
|
1942
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "ss-w-fandash-split-cell", children: [
|
|
1943
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-split-value", children: h2h.losses }),
|
|
1944
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-split-label", children: h2h.awayWinsLabel })
|
|
1543
1945
|
] })
|
|
1544
1946
|
] })
|
|
1545
1947
|
] }) : null,
|
|
1546
|
-
data.fact ? /* @__PURE__ */ (0,
|
|
1948
|
+
data.fact ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-fact", children: data.fact }) : null
|
|
1547
1949
|
] }) : null
|
|
1548
1950
|
] });
|
|
1549
1951
|
}
|
|
1550
1952
|
|
|
1551
1953
|
// src/components/dashboard/CountdownCard.tsx
|
|
1552
|
-
var
|
|
1553
|
-
var
|
|
1954
|
+
var import_react11 = require("react");
|
|
1955
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1554
1956
|
var DAY_MS = 864e5;
|
|
1555
1957
|
function remainingSegments(kickoffUnix, nowMs, withSeconds) {
|
|
1556
1958
|
const totalSeconds = Math.floor((kickoffUnix * 1e3 - nowMs) / 1e3);
|
|
@@ -1568,72 +1970,72 @@ function remainingSegments(kickoffUnix, nowMs, withSeconds) {
|
|
|
1568
1970
|
function CountdownCard({ card }) {
|
|
1569
1971
|
const { data } = card;
|
|
1570
1972
|
const unitLabel = { d: data.daysUnit, h: data.hoursUnit, m: data.minutesUnit, s: data.secondsUnit };
|
|
1571
|
-
const [nowMs, setNowMs] = (0,
|
|
1572
|
-
const [reduced] = (0,
|
|
1973
|
+
const [nowMs, setNowMs] = (0, import_react11.useState)(() => Date.now());
|
|
1974
|
+
const [reduced] = (0, import_react11.useState)(
|
|
1573
1975
|
() => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
|
|
1574
1976
|
);
|
|
1575
1977
|
const withinDay = data.kickoffUnix * 1e3 - nowMs < DAY_MS;
|
|
1576
|
-
(0,
|
|
1978
|
+
(0, import_react11.useEffect)(() => {
|
|
1577
1979
|
if (reduced) return;
|
|
1578
1980
|
const id = window.setInterval(() => setNowMs(Date.now()), withinDay ? 1e3 : 6e4);
|
|
1579
1981
|
return () => window.clearInterval(id);
|
|
1580
1982
|
}, [reduced, withinDay]);
|
|
1581
1983
|
const segments = remainingSegments(data.kickoffUnix, nowMs, withinDay && !reduced);
|
|
1582
|
-
return /* @__PURE__ */ (0,
|
|
1583
|
-
/* @__PURE__ */ (0,
|
|
1584
|
-
segments ? /* @__PURE__ */ (0,
|
|
1585
|
-
i > 0 ? /* @__PURE__ */ (0,
|
|
1586
|
-
/* @__PURE__ */ (0,
|
|
1587
|
-
/* @__PURE__ */ (0,
|
|
1588
|
-
/* @__PURE__ */ (0,
|
|
1984
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "ss-w-fandash-card ss-w-fandash-countdown", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "ss-w-fandash-countdown-top", children: [
|
|
1985
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title ?? "Kick-off in" }),
|
|
1986
|
+
segments ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-fandash-countdown-clock", children: segments.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react11.Fragment, { children: [
|
|
1987
|
+
i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-fandash-countdown-colon", children: ":" }) : null,
|
|
1988
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "ss-w-fandash-countdown-seg", children: [
|
|
1989
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-fandash-countdown-value", children: s.value }),
|
|
1990
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ss-w-fandash-countdown-unit", children: unitLabel[s.unit] })
|
|
1589
1991
|
] })
|
|
1590
1992
|
] }, s.unit)) }) : null
|
|
1591
1993
|
] }) });
|
|
1592
1994
|
}
|
|
1593
1995
|
|
|
1594
1996
|
// src/components/dashboard/InjuriesCard.tsx
|
|
1595
|
-
var
|
|
1596
|
-
var
|
|
1997
|
+
var import_react12 = require("react");
|
|
1998
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1597
1999
|
var SHOWN = 3;
|
|
1598
2000
|
function ColHead({ name, crestUrl }) {
|
|
1599
|
-
return /* @__PURE__ */ (0,
|
|
1600
|
-
/* @__PURE__ */ (0,
|
|
1601
|
-
/* @__PURE__ */ (0,
|
|
2001
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-fandash-injuries-col-head", children: [
|
|
2002
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Crest2, { url: crestUrl ?? void 0, name, kind: "team" }),
|
|
2003
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-injuries-col-head-name", children: name })
|
|
1602
2004
|
] });
|
|
1603
2005
|
}
|
|
1604
2006
|
function InjuryList({ rows, emptyLabel, limit }) {
|
|
1605
|
-
if (rows.length === 0) return /* @__PURE__ */ (0,
|
|
2007
|
+
if (rows.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-injuries-empty", children: emptyLabel });
|
|
1606
2008
|
const shown = limit === void 0 ? rows : rows.slice(0, limit);
|
|
1607
|
-
return /* @__PURE__ */ (0,
|
|
1608
|
-
/* @__PURE__ */ (0,
|
|
1609
|
-
/* @__PURE__ */ (0,
|
|
1610
|
-
/* @__PURE__ */ (0,
|
|
1611
|
-
r.injuryType ? /* @__PURE__ */ (0,
|
|
1612
|
-
r.expectedReturnLabel ? /* @__PURE__ */ (0,
|
|
2009
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("ul", { className: "ss-w-fandash-injury-list", children: shown.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("li", { className: "ss-w-fandash-injury-row", children: [
|
|
2010
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-injury-name", children: r.playerName }),
|
|
2011
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-fandash-injury-meta", children: [
|
|
2012
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-injury-status", children: r.status }),
|
|
2013
|
+
r.injuryType ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-injury-type", children: r.injuryType }) : null,
|
|
2014
|
+
r.expectedReturnLabel ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-injury-return", children: r.expectedReturnLabel }) : null
|
|
1613
2015
|
] })
|
|
1614
2016
|
] }, `${r.playerName}-${i}`)) });
|
|
1615
2017
|
}
|
|
1616
2018
|
function InjuriesCard({ card, ui }) {
|
|
1617
2019
|
const { data } = card;
|
|
1618
|
-
const [expanded, setExpanded] = (0,
|
|
2020
|
+
const [expanded, setExpanded] = (0, import_react12.useState)(false);
|
|
1619
2021
|
const hidden = Math.max(0, data.ours.length - SHOWN) + Math.max(0, data.theirs.length - SHOWN);
|
|
1620
2022
|
const limit = expanded ? void 0 : SHOWN;
|
|
1621
2023
|
const showMore = ui?.showMore ?? ((n) => `Show ${n} more`);
|
|
1622
2024
|
const showLess = ui?.showLess ?? "Show less";
|
|
1623
|
-
return /* @__PURE__ */ (0,
|
|
1624
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1625
|
-
/* @__PURE__ */ (0,
|
|
1626
|
-
/* @__PURE__ */ (0,
|
|
1627
|
-
/* @__PURE__ */ (0,
|
|
1628
|
-
/* @__PURE__ */ (0,
|
|
2025
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-injuries", children: [
|
|
2026
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2027
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "ss-w-fandash-injuries-cols", children: [
|
|
2028
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "ss-w-fandash-injuries-col", children: [
|
|
2029
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ColHead, { name: data.oursName, crestUrl: data.oursCrestUrl }),
|
|
2030
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InjuryList, { rows: data.ours, emptyLabel: data.emptyLabel, limit })
|
|
1629
2031
|
] }),
|
|
1630
|
-
/* @__PURE__ */ (0,
|
|
1631
|
-
/* @__PURE__ */ (0,
|
|
1632
|
-
/* @__PURE__ */ (0,
|
|
1633
|
-
/* @__PURE__ */ (0,
|
|
2032
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "ss-w-fandash-injuries-divider" }),
|
|
2033
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "ss-w-fandash-injuries-col", children: [
|
|
2034
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ColHead, { name: data.theirsName, crestUrl: data.theirsCrestUrl }),
|
|
2035
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InjuryList, { rows: data.theirs, emptyLabel: data.emptyLabel, limit })
|
|
1634
2036
|
] })
|
|
1635
2037
|
] }),
|
|
1636
|
-
hidden > 0 ? /* @__PURE__ */ (0,
|
|
2038
|
+
hidden > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1637
2039
|
"button",
|
|
1638
2040
|
{
|
|
1639
2041
|
type: "button",
|
|
@@ -1647,80 +2049,80 @@ function InjuriesCard({ card, ui }) {
|
|
|
1647
2049
|
}
|
|
1648
2050
|
|
|
1649
2051
|
// src/components/dashboard/ReasonToBetCard.tsx
|
|
1650
|
-
var
|
|
2052
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1651
2053
|
function ReasonToBetCard({ card }) {
|
|
1652
|
-
return /* @__PURE__ */ (0,
|
|
1653
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1654
|
-
/* @__PURE__ */ (0,
|
|
2054
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-reasons", children: [
|
|
2055
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2056
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("ul", { className: "ss-w-fandash-reason-list", children: card.data.angles.map((angle, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("li", { className: "ss-w-fandash-reason-item", children: angle }, `${angle}-${i}`)) })
|
|
1655
2057
|
] });
|
|
1656
2058
|
}
|
|
1657
2059
|
|
|
1658
2060
|
// src/components/dashboard/WhereToWatchCard.tsx
|
|
1659
|
-
var
|
|
2061
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1660
2062
|
function WhereToWatchCard({ card }) {
|
|
1661
|
-
return /* @__PURE__ */ (0,
|
|
1662
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1663
|
-
/* @__PURE__ */ (0,
|
|
2063
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-watch", children: [
|
|
2064
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2065
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-fandash-stations", children: card.data.stations.map((station, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "ss-w-fandash-station-chip", children: station }, `${station}-${i}`)) })
|
|
1664
2066
|
] });
|
|
1665
2067
|
}
|
|
1666
2068
|
|
|
1667
2069
|
// src/components/dashboard/CongestedWeekCard.tsx
|
|
1668
|
-
var
|
|
2070
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1669
2071
|
function CongestedWeekCard({ card, onTap }) {
|
|
1670
|
-
return /* @__PURE__ */ (0,
|
|
1671
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1672
|
-
/* @__PURE__ */ (0,
|
|
1673
|
-
/* @__PURE__ */ (0,
|
|
1674
|
-
/* @__PURE__ */ (0,
|
|
1675
|
-
/* @__PURE__ */ (0,
|
|
1676
|
-
/* @__PURE__ */ (0,
|
|
2072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-congested", onClick: () => onTap(card), children: [
|
|
2073
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2074
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "ss-w-fandash-congested-grid", children: card.data.entries.map((entry, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "ss-w-fandash-congested-cell", children: [
|
|
2075
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "ss-w-fandash-congested-day", children: entry.dayLabel }),
|
|
2076
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "ss-w-fandash-congested-opponent", children: entry.opponent }),
|
|
2077
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "ss-w-fandash-congested-comp", children: entry.competition }),
|
|
2078
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "ss-w-fandash-congested-time", children: entry.timeLabel })
|
|
1677
2079
|
] }, `${entry.opponent}-${i}`)) }),
|
|
1678
|
-
/* @__PURE__ */ (0,
|
|
2080
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1679
2081
|
] });
|
|
1680
2082
|
}
|
|
1681
2083
|
|
|
1682
2084
|
// src/components/dashboard/TransfersCard.tsx
|
|
1683
|
-
var
|
|
2085
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1684
2086
|
function TransferList({ rows }) {
|
|
1685
|
-
if (rows.length === 0) return /* @__PURE__ */ (0,
|
|
1686
|
-
return /* @__PURE__ */ (0,
|
|
1687
|
-
/* @__PURE__ */ (0,
|
|
1688
|
-
/* @__PURE__ */ (0,
|
|
1689
|
-
r.type ? /* @__PURE__ */ (0,
|
|
2087
|
+
if (rows.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "ss-w-fandash-transfers-empty", children: "None" });
|
|
2088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("ul", { className: "ss-w-fandash-transfer-list", children: rows.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("li", { className: "ss-w-fandash-transfer-row", children: [
|
|
2089
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "ss-w-fandash-transfer-name", children: r.playerName }),
|
|
2090
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "ss-w-fandash-transfer-club", children: r.otherClub }),
|
|
2091
|
+
r.type ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "ss-w-fandash-transfer-type", children: r.type }) : null
|
|
1690
2092
|
] }, `${r.playerName}-${i}`)) });
|
|
1691
2093
|
}
|
|
1692
2094
|
function TransfersCard({ card }) {
|
|
1693
2095
|
const { data } = card;
|
|
1694
|
-
return /* @__PURE__ */ (0,
|
|
1695
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1696
|
-
/* @__PURE__ */ (0,
|
|
1697
|
-
/* @__PURE__ */ (0,
|
|
1698
|
-
/* @__PURE__ */ (0,
|
|
1699
|
-
/* @__PURE__ */ (0,
|
|
2096
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-transfers", children: [
|
|
2097
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2098
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "ss-w-fandash-transfers-cols", children: [
|
|
2099
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "ss-w-fandash-transfers-col", children: [
|
|
2100
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "ss-w-fandash-transfers-col-head", children: "In" }),
|
|
2101
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TransferList, { rows: data.in })
|
|
1700
2102
|
] }),
|
|
1701
|
-
/* @__PURE__ */ (0,
|
|
1702
|
-
/* @__PURE__ */ (0,
|
|
1703
|
-
/* @__PURE__ */ (0,
|
|
2103
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "ss-w-fandash-transfers-col", children: [
|
|
2104
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "ss-w-fandash-transfers-col-head", children: "Out" }),
|
|
2105
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TransferList, { rows: data.out })
|
|
1704
2106
|
] })
|
|
1705
2107
|
] })
|
|
1706
2108
|
] });
|
|
1707
2109
|
}
|
|
1708
2110
|
|
|
1709
2111
|
// src/components/dashboard/LinksCard.tsx
|
|
1710
|
-
var
|
|
2112
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1711
2113
|
function LinksCard({ card }) {
|
|
1712
|
-
return /* @__PURE__ */ (0,
|
|
1713
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1714
|
-
/* @__PURE__ */ (0,
|
|
1715
|
-
/* @__PURE__ */ (0,
|
|
1716
|
-
/* @__PURE__ */ (0,
|
|
2114
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-links", children: [
|
|
2115
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2116
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "ss-w-fandash-link-grid", children: card.data.links.map((link, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("a", { className: "ss-w-fandash-link-tile", href: link.url, target: "_blank", rel: "noopener noreferrer", children: [
|
|
2117
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-link-label", children: link.label }),
|
|
2118
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "ss-w-fandash-link-chevron", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ChevronIcon, {}) })
|
|
1717
2119
|
] }, `${link.url}-${i}`)) })
|
|
1718
2120
|
] });
|
|
1719
2121
|
}
|
|
1720
2122
|
|
|
1721
2123
|
// src/components/dashboard/PostMatchResultCard.tsx
|
|
1722
|
-
var
|
|
1723
|
-
var
|
|
2124
|
+
var import_react13 = require("react");
|
|
2125
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1724
2126
|
function initials3(name) {
|
|
1725
2127
|
return name.trim().slice(0, 3).toUpperCase();
|
|
1726
2128
|
}
|
|
@@ -1729,37 +2131,37 @@ function PostMatchCrest({
|
|
|
1729
2131
|
name,
|
|
1730
2132
|
side
|
|
1731
2133
|
}) {
|
|
1732
|
-
const [failed, setFailed] = (0,
|
|
2134
|
+
const [failed, setFailed] = (0, import_react13.useState)(false);
|
|
1733
2135
|
const cls = `ss-w-fandash-postmatch-crest ss-w-fandash-postmatch-crest--${side}`;
|
|
1734
2136
|
if (url && !failed) {
|
|
1735
|
-
return /* @__PURE__ */ (0,
|
|
2137
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
1736
2138
|
}
|
|
1737
|
-
return /* @__PURE__ */ (0,
|
|
2139
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: `${cls} ss-w-fandash-postmatch-crest--fallback`, "aria-hidden": "true", children: initials3(name) });
|
|
1738
2140
|
}
|
|
1739
2141
|
function PostMatchResultCard({ card }) {
|
|
1740
2142
|
const { data } = card;
|
|
1741
2143
|
const homeWon = data.homeScore >= data.awayScore;
|
|
1742
2144
|
const awayWon = data.awayScore >= data.homeScore;
|
|
1743
|
-
return /* @__PURE__ */ (0,
|
|
1744
|
-
/* @__PURE__ */ (0,
|
|
1745
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1746
|
-
/* @__PURE__ */ (0,
|
|
2145
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-postmatch-result", children: [
|
|
2146
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-fandash-postmatch-top", children: [
|
|
2147
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-fandash-postmatch-pill", children: card.title }) : null,
|
|
2148
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: `ss-w-fandash-postmatch-tag ss-w-fandash-postmatch-tag--${data.outcome}`, children: data.resultLabel })
|
|
1747
2149
|
] }),
|
|
1748
|
-
/* @__PURE__ */ (0,
|
|
1749
|
-
/* @__PURE__ */ (0,
|
|
1750
|
-
/* @__PURE__ */ (0,
|
|
1751
|
-
/* @__PURE__ */ (0,
|
|
2150
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-fandash-postmatch-main", children: [
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-fandash-postmatch-side ss-w-fandash-postmatch-side--home", children: [
|
|
2152
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PostMatchCrest, { url: data.homeCrestUrl, name: data.homeName, side: "home" }),
|
|
2153
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-fandash-postmatch-team-name", children: data.homeName })
|
|
1752
2154
|
] }),
|
|
1753
|
-
/* @__PURE__ */ (0,
|
|
1754
|
-
/* @__PURE__ */ (0,
|
|
2155
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-fandash-postmatch-score-main", children: [
|
|
2156
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1755
2157
|
"span",
|
|
1756
2158
|
{
|
|
1757
2159
|
className: `ss-w-fandash-postmatch-score-value ss-w-fandash-postmatch-score-value--${homeWon ? "win" : "lose"}`,
|
|
1758
2160
|
children: data.homeScore
|
|
1759
2161
|
}
|
|
1760
2162
|
),
|
|
1761
|
-
/* @__PURE__ */ (0,
|
|
1762
|
-
/* @__PURE__ */ (0,
|
|
2163
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-fandash-postmatch-score-sep", children: "\u2013" }),
|
|
2164
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
1763
2165
|
"span",
|
|
1764
2166
|
{
|
|
1765
2167
|
className: `ss-w-fandash-postmatch-score-value ss-w-fandash-postmatch-score-value--${awayWon ? "win" : "lose"}`,
|
|
@@ -1767,12 +2169,12 @@ function PostMatchResultCard({ card }) {
|
|
|
1767
2169
|
}
|
|
1768
2170
|
)
|
|
1769
2171
|
] }),
|
|
1770
|
-
/* @__PURE__ */ (0,
|
|
1771
|
-
/* @__PURE__ */ (0,
|
|
1772
|
-
/* @__PURE__ */ (0,
|
|
2172
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-fandash-postmatch-side ss-w-fandash-postmatch-side--away", children: [
|
|
2173
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PostMatchCrest, { url: data.awayCrestUrl, name: data.awayName, side: "away" }),
|
|
2174
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "ss-w-fandash-postmatch-team-name", children: data.awayName })
|
|
1773
2175
|
] })
|
|
1774
2176
|
] }),
|
|
1775
|
-
/* @__PURE__ */ (0,
|
|
2177
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-fandash-postmatch-meta", children: [
|
|
1776
2178
|
data.kickoffLabel,
|
|
1777
2179
|
data.competition ? ` \xB7 ${data.competition}` : ""
|
|
1778
2180
|
] })
|
|
@@ -1780,20 +2182,20 @@ function PostMatchResultCard({ card }) {
|
|
|
1780
2182
|
}
|
|
1781
2183
|
|
|
1782
2184
|
// src/components/dashboard/PostMatchGoalsCard.tsx
|
|
1783
|
-
var
|
|
2185
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1784
2186
|
function PostMatchGoalsCard({ card, onTap }) {
|
|
1785
|
-
return /* @__PURE__ */ (0,
|
|
1786
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1787
|
-
/* @__PURE__ */ (0,
|
|
1788
|
-
/* @__PURE__ */ (0,
|
|
1789
|
-
/* @__PURE__ */ (0,
|
|
2187
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-postmatch-goals", onClick: () => onTap(card), children: [
|
|
2188
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2189
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("ul", { className: "ss-w-fandash-postmatch-goal-list", children: card.data.goals.map((g, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("li", { className: g.scoredByClub ? "ss-w-fandash-postmatch-goal ss-w-fandash-postmatch-goal--club" : "ss-w-fandash-postmatch-goal", children: [
|
|
2190
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-postmatch-goal-ball" }),
|
|
2191
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: g.text })
|
|
1790
2192
|
] }, `${g.text}-${i}`)) }),
|
|
1791
|
-
/* @__PURE__ */ (0,
|
|
2193
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1792
2194
|
] });
|
|
1793
2195
|
}
|
|
1794
2196
|
|
|
1795
2197
|
// src/components/dashboard/PostMatchStatsCard.tsx
|
|
1796
|
-
var
|
|
2198
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1797
2199
|
function splitWidths(homeNum, awayNum) {
|
|
1798
2200
|
const total = homeNum + awayNum;
|
|
1799
2201
|
if (total <= 0) return { home: "50%", away: "50%" };
|
|
@@ -1802,42 +2204,42 @@ function splitWidths(homeNum, awayNum) {
|
|
|
1802
2204
|
}
|
|
1803
2205
|
function PostMatchStatsCard({ card, onTap }) {
|
|
1804
2206
|
const { data } = card;
|
|
1805
|
-
return /* @__PURE__ */ (0,
|
|
1806
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1807
|
-
/* @__PURE__ */ (0,
|
|
2207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-postmatch-stats", onClick: () => onTap(card), children: [
|
|
2208
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2209
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "ss-w-fandash-postmatch-stat-rows", children: data.rows.map((r, i) => {
|
|
1808
2210
|
const leftValue = data.clubIsHome ? r.clubValue : r.oppValue;
|
|
1809
2211
|
const rightValue = data.clubIsHome ? r.oppValue : r.clubValue;
|
|
1810
2212
|
const homeNum = data.clubIsHome ? r.clubNum : r.oppNum;
|
|
1811
2213
|
const awayNum = data.clubIsHome ? r.oppNum : r.clubNum;
|
|
1812
2214
|
const { home, away } = splitWidths(homeNum, awayNum);
|
|
1813
|
-
return /* @__PURE__ */ (0,
|
|
1814
|
-
/* @__PURE__ */ (0,
|
|
1815
|
-
/* @__PURE__ */ (0,
|
|
1816
|
-
/* @__PURE__ */ (0,
|
|
1817
|
-
/* @__PURE__ */ (0,
|
|
2215
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-fandash-postmatch-stat", children: [
|
|
2216
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-fandash-postmatch-stat-row", children: [
|
|
2217
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-stat-value ss-w-fandash-postmatch-stat-value--home", children: leftValue }),
|
|
2218
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-stat-label", children: r.label }),
|
|
2219
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-stat-value ss-w-fandash-postmatch-stat-value--away", children: rightValue })
|
|
1818
2220
|
] }),
|
|
1819
|
-
/* @__PURE__ */ (0,
|
|
1820
|
-
/* @__PURE__ */ (0,
|
|
1821
|
-
/* @__PURE__ */ (0,
|
|
2221
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-fandash-postmatch-stat-bar", children: [
|
|
2222
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-stat-bar-home", style: { width: home } }),
|
|
2223
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-postmatch-stat-bar-away", style: { width: away } })
|
|
1822
2224
|
] })
|
|
1823
2225
|
] }, `${r.label}-${i}`);
|
|
1824
2226
|
}) }),
|
|
1825
|
-
data.rows.length > 0 ? /* @__PURE__ */ (0,
|
|
1826
|
-
/* @__PURE__ */ (0,
|
|
1827
|
-
/* @__PURE__ */ (0,
|
|
2227
|
+
data.rows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "ss-w-fandash-postmatch-legend", children: [
|
|
2228
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "ss-w-fandash-postmatch-legend-item", children: [
|
|
2229
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("i", { className: "ss-w-fandash-postmatch-legend-swatch ss-w-fandash-postmatch-legend-swatch--home" }),
|
|
1828
2230
|
data.homeName
|
|
1829
2231
|
] }),
|
|
1830
|
-
/* @__PURE__ */ (0,
|
|
1831
|
-
/* @__PURE__ */ (0,
|
|
2232
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "ss-w-fandash-postmatch-legend-item", children: [
|
|
2233
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("i", { className: "ss-w-fandash-postmatch-legend-swatch ss-w-fandash-postmatch-legend-swatch--away" }),
|
|
1832
2234
|
data.awayName
|
|
1833
2235
|
] })
|
|
1834
2236
|
] }) : null,
|
|
1835
|
-
/* @__PURE__ */ (0,
|
|
2237
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1836
2238
|
] });
|
|
1837
2239
|
}
|
|
1838
2240
|
|
|
1839
2241
|
// src/components/dashboard/PostMatchTopPerformerCard.tsx
|
|
1840
|
-
var
|
|
2242
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1841
2243
|
function initials4(playerName) {
|
|
1842
2244
|
const words = playerName.trim().split(/\s+/).filter(Boolean);
|
|
1843
2245
|
if (words.length === 0) return "?";
|
|
@@ -1847,72 +2249,72 @@ function initials4(playerName) {
|
|
|
1847
2249
|
}
|
|
1848
2250
|
function PostMatchTopPerformerCard({ card, onTap }) {
|
|
1849
2251
|
const { data } = card;
|
|
1850
|
-
return /* @__PURE__ */ (0,
|
|
1851
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1852
|
-
/* @__PURE__ */ (0,
|
|
1853
|
-
/* @__PURE__ */ (0,
|
|
1854
|
-
/* @__PURE__ */ (0,
|
|
1855
|
-
/* @__PURE__ */ (0,
|
|
2252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-postmatch-performer", onClick: () => onTap(card), children: [
|
|
2253
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2254
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "ss-w-fandash-postmatch-perf-row", children: [
|
|
2255
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-fandash-postmatch-perf-avatar", "aria-hidden": "true", children: initials4(data.playerName) }),
|
|
2256
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-fandash-postmatch-perf-name", children: data.playerName }),
|
|
2257
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-fandash-postmatch-perf-rating", children: data.ratingLabel })
|
|
1856
2258
|
] }),
|
|
1857
|
-
/* @__PURE__ */ (0,
|
|
2259
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1858
2260
|
] });
|
|
1859
2261
|
}
|
|
1860
2262
|
|
|
1861
2263
|
// src/components/dashboard/PostMatchNextCard.tsx
|
|
1862
|
-
var
|
|
2264
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1863
2265
|
function PostMatchNextCard({ card }) {
|
|
1864
2266
|
const { data } = card;
|
|
1865
|
-
return /* @__PURE__ */ (0,
|
|
1866
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1867
|
-
/* @__PURE__ */ (0,
|
|
2267
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-postmatch-next", children: [
|
|
2268
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2269
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "ss-w-fandash-postmatch-next-row", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "ss-w-fandash-postmatch-next-when", children: data.whenLabel }) })
|
|
1868
2270
|
] });
|
|
1869
2271
|
}
|
|
1870
2272
|
|
|
1871
2273
|
// src/components/dashboard/RestingNextCard.tsx
|
|
1872
|
-
var
|
|
2274
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1873
2275
|
function RestingNextCard({ card, onTap }) {
|
|
1874
2276
|
const { data } = card;
|
|
1875
|
-
return /* @__PURE__ */ (0,
|
|
1876
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1877
|
-
/* @__PURE__ */ (0,
|
|
1878
|
-
/* @__PURE__ */ (0,
|
|
1879
|
-
data.competition ? /* @__PURE__ */ (0,
|
|
2277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-resting-next", onClick: () => onTap(card), children: [
|
|
2278
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2279
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "ss-w-fandash-resting-next-row", children: [
|
|
2280
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "ss-w-fandash-resting-next-when", children: data.whenLabel }),
|
|
2281
|
+
data.competition ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "ss-w-fandash-resting-next-competition", children: data.competition }) : null
|
|
1880
2282
|
] }),
|
|
1881
|
-
/* @__PURE__ */ (0,
|
|
2283
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1882
2284
|
] });
|
|
1883
2285
|
}
|
|
1884
2286
|
|
|
1885
2287
|
// src/components/dashboard/RestingStandingsCard.tsx
|
|
1886
|
-
var
|
|
2288
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1887
2289
|
function RestingStandingsCard({ card, onTap }) {
|
|
1888
2290
|
const { data } = card;
|
|
1889
|
-
return /* @__PURE__ */ (0,
|
|
1890
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1891
|
-
/* @__PURE__ */ (0,
|
|
1892
|
-
/* @__PURE__ */ (0,
|
|
1893
|
-
/* @__PURE__ */ (0,
|
|
2291
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-resting-standings", onClick: () => onTap(card), children: [
|
|
2292
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2293
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "ss-w-fandash-resting-standings-row", children: [
|
|
2294
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "ss-w-fandash-resting-standings-position", children: data.positionLabel }),
|
|
2295
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "ss-w-fandash-resting-standings-record", children: data.recordLabel })
|
|
1894
2296
|
] }),
|
|
1895
|
-
/* @__PURE__ */ (0,
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1896
2298
|
] });
|
|
1897
2299
|
}
|
|
1898
2300
|
|
|
1899
2301
|
// src/components/dashboard/RestingSeasonCard.tsx
|
|
1900
|
-
var
|
|
2302
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1901
2303
|
function RestingSeasonCard({ card, onTap }) {
|
|
1902
2304
|
const { data } = card;
|
|
1903
|
-
return /* @__PURE__ */ (0,
|
|
1904
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1905
|
-
/* @__PURE__ */ (0,
|
|
1906
|
-
data.scorerLabel ? /* @__PURE__ */ (0,
|
|
1907
|
-
data.playerLabel ? /* @__PURE__ */ (0,
|
|
1908
|
-
/* @__PURE__ */ (0,
|
|
2305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("button", { type: "button", className: "ss-w-fandash-card ss-w-fandash-card--tap ss-w-fandash-resting-season", onClick: () => onTap(card), children: [
|
|
2306
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2307
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "ss-w-fandash-resting-season-rows", children: [
|
|
2308
|
+
data.scorerLabel ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "ss-w-fandash-resting-season-row", children: data.scorerLabel }) : null,
|
|
2309
|
+
data.playerLabel ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "ss-w-fandash-resting-season-row", children: data.playerLabel }) : null,
|
|
2310
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "ss-w-fandash-resting-season-row", children: data.tallyLabel })
|
|
1909
2311
|
] }),
|
|
1910
|
-
/* @__PURE__ */ (0,
|
|
2312
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1911
2313
|
] });
|
|
1912
2314
|
}
|
|
1913
2315
|
|
|
1914
2316
|
// src/components/dashboard/RestingFormCard.tsx
|
|
1915
|
-
var
|
|
2317
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
1916
2318
|
function resultClass(result) {
|
|
1917
2319
|
const upper = result.toUpperCase();
|
|
1918
2320
|
if (upper === "W") return "ss-w-fandash-form-pill--win";
|
|
@@ -1921,17 +2323,17 @@ function resultClass(result) {
|
|
|
1921
2323
|
}
|
|
1922
2324
|
function RestingFormCard({ card }) {
|
|
1923
2325
|
const { data } = card;
|
|
1924
|
-
return /* @__PURE__ */ (0,
|
|
1925
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1926
|
-
/* @__PURE__ */ (0,
|
|
2326
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-resting-form", children: [
|
|
2327
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2328
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "ss-w-fandash-form", children: data.letters.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: `ss-w-fandash-form-pill ${resultClass(r)}`, children: r }, `${r}-${i}`)) })
|
|
1927
2329
|
] });
|
|
1928
2330
|
}
|
|
1929
2331
|
|
|
1930
2332
|
// src/components/dashboard/LiveScoreCard.tsx
|
|
1931
|
-
var
|
|
2333
|
+
var import_react15 = require("react");
|
|
1932
2334
|
|
|
1933
2335
|
// src/useLiveClock.ts
|
|
1934
|
-
var
|
|
2336
|
+
var import_react14 = require("react");
|
|
1935
2337
|
var TICK_MS = 6e4;
|
|
1936
2338
|
var MAX_LIVE_TICK_MINUTES = 15;
|
|
1937
2339
|
function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
@@ -1940,10 +2342,10 @@ function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
|
1940
2342
|
return minute + Math.min(Math.max(0, elapsedMinutes), MAX_LIVE_TICK_MINUTES);
|
|
1941
2343
|
}
|
|
1942
2344
|
function useLiveClock(minute, clockRunning, receivedAtMs) {
|
|
1943
|
-
const [displayMinute, setDisplayMinute] = (0,
|
|
2345
|
+
const [displayMinute, setDisplayMinute] = (0, import_react14.useState)(
|
|
1944
2346
|
() => computeDisplayMinute(minute, clockRunning, receivedAtMs)
|
|
1945
2347
|
);
|
|
1946
|
-
(0,
|
|
2348
|
+
(0, import_react14.useEffect)(() => {
|
|
1947
2349
|
setDisplayMinute(computeDisplayMinute(minute, clockRunning, receivedAtMs));
|
|
1948
2350
|
if (!clockRunning) return;
|
|
1949
2351
|
const id = window.setInterval(() => {
|
|
@@ -1955,17 +2357,17 @@ function useLiveClock(minute, clockRunning, receivedAtMs) {
|
|
|
1955
2357
|
}
|
|
1956
2358
|
|
|
1957
2359
|
// src/components/dashboard/LiveScoreCard.tsx
|
|
1958
|
-
var
|
|
2360
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1959
2361
|
function initials5(name) {
|
|
1960
2362
|
return name.trim().slice(0, 3).toUpperCase();
|
|
1961
2363
|
}
|
|
1962
2364
|
function LiveCrest({ url, name, side }) {
|
|
1963
|
-
const [failed, setFailed] = (0,
|
|
2365
|
+
const [failed, setFailed] = (0, import_react15.useState)(false);
|
|
1964
2366
|
const cls = `ss-w-fandash-live-crest ss-w-fandash-live-crest--${side}`;
|
|
1965
2367
|
if (url && !failed) {
|
|
1966
|
-
return /* @__PURE__ */ (0,
|
|
2368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
1967
2369
|
}
|
|
1968
|
-
return /* @__PURE__ */ (0,
|
|
2370
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: `${cls} ss-w-fandash-live-crest--fallback`, "aria-hidden": "true", children: initials5(name) });
|
|
1969
2371
|
}
|
|
1970
2372
|
function scorersLine(goalEvents) {
|
|
1971
2373
|
if (!goalEvents || goalEvents.length === 0) return null;
|
|
@@ -1979,72 +2381,72 @@ function LiveScoreCard({
|
|
|
1979
2381
|
}) {
|
|
1980
2382
|
const { data } = card;
|
|
1981
2383
|
const seedKey = `${data.minute}:${data.homeScore}:${data.awayScore}`;
|
|
1982
|
-
const seedRef = (0,
|
|
2384
|
+
const seedRef = (0, import_react15.useRef)(null);
|
|
1983
2385
|
if (!seedRef.current || seedRef.current.key !== seedKey) {
|
|
1984
2386
|
seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
|
|
1985
2387
|
}
|
|
1986
2388
|
const displayMinute = useLiveClock(data.minute, data.clockRunning, seedRef.current.receivedAtMs);
|
|
1987
2389
|
const minuteSuffix = data.minuteLabel.replace(/^\d+/, "");
|
|
1988
2390
|
const scorers = scorersLine(goalEvents);
|
|
1989
|
-
return /* @__PURE__ */ (0,
|
|
1990
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1991
|
-
/* @__PURE__ */ (0,
|
|
1992
|
-
/* @__PURE__ */ (0,
|
|
1993
|
-
/* @__PURE__ */ (0,
|
|
2391
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-live-score", children: [
|
|
2392
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2393
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "ss-w-fandash-live-top", children: [
|
|
2394
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "ss-w-fandash-live-pill", children: [
|
|
2395
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-live-dot", "aria-hidden": "true" }),
|
|
1994
2396
|
data.statusLabel
|
|
1995
2397
|
] }),
|
|
1996
|
-
/* @__PURE__ */ (0,
|
|
1997
|
-
data.competition ? /* @__PURE__ */ (0,
|
|
2398
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-live-minute", children: `${displayMinute}${minuteSuffix}` }),
|
|
2399
|
+
data.competition ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-live-competition", children: data.competition }) : null
|
|
1998
2400
|
] }),
|
|
1999
|
-
/* @__PURE__ */ (0,
|
|
2000
|
-
/* @__PURE__ */ (0,
|
|
2001
|
-
/* @__PURE__ */ (0,
|
|
2002
|
-
/* @__PURE__ */ (0,
|
|
2401
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "ss-w-fandash-live-main", children: [
|
|
2402
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "ss-w-fandash-live-side ss-w-fandash-live-side--home", children: [
|
|
2403
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(LiveCrest, { url: data.homeCrestUrl, name: data.homeName, side: "home" }),
|
|
2404
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-live-team-name", children: data.homeName })
|
|
2003
2405
|
] }),
|
|
2004
|
-
/* @__PURE__ */ (0,
|
|
2005
|
-
/* @__PURE__ */ (0,
|
|
2006
|
-
/* @__PURE__ */ (0,
|
|
2007
|
-
/* @__PURE__ */ (0,
|
|
2406
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "ss-w-fandash-live-score-main", children: [
|
|
2407
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-live-score-value", children: data.homeScore }),
|
|
2408
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-live-score-sep", children: "\u2013" }),
|
|
2409
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-live-score-value", children: data.awayScore })
|
|
2008
2410
|
] }),
|
|
2009
|
-
/* @__PURE__ */ (0,
|
|
2010
|
-
/* @__PURE__ */ (0,
|
|
2011
|
-
/* @__PURE__ */ (0,
|
|
2411
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "ss-w-fandash-live-side ss-w-fandash-live-side--away", children: [
|
|
2412
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(LiveCrest, { url: data.awayCrestUrl, name: data.awayName, side: "away" }),
|
|
2413
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-live-team-name", children: data.awayName })
|
|
2012
2414
|
] })
|
|
2013
2415
|
] }),
|
|
2014
|
-
scorers ? /* @__PURE__ */ (0,
|
|
2015
|
-
/* @__PURE__ */ (0,
|
|
2416
|
+
scorers ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "ss-w-fandash-live-scorers", children: [
|
|
2417
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "ss-w-fandash-live-scorers-icon", "aria-hidden": "true", children: "\u26BD" }),
|
|
2016
2418
|
scorers
|
|
2017
2419
|
] }) : null
|
|
2018
2420
|
] });
|
|
2019
2421
|
}
|
|
2020
2422
|
|
|
2021
2423
|
// src/components/dashboard/LiveTimelineCard.tsx
|
|
2022
|
-
var
|
|
2023
|
-
var
|
|
2424
|
+
var import_react16 = require("react");
|
|
2425
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
2024
2426
|
var SHOWN2 = 3;
|
|
2025
2427
|
function EventIcon({ type }) {
|
|
2026
2428
|
if (type === "goal") {
|
|
2027
|
-
return /* @__PURE__ */ (0,
|
|
2429
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-live-tl-ico ss-w-fandash-live-tl-ico--goal", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-live-tl-ball" }) });
|
|
2028
2430
|
}
|
|
2029
2431
|
if (type === "yellow" || type === "red") {
|
|
2030
|
-
return /* @__PURE__ */ (0,
|
|
2432
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-live-tl-ico", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: `ss-w-fandash-live-tl-card ss-w-fandash-live-tl-card--${type}` }) });
|
|
2031
2433
|
}
|
|
2032
2434
|
if (type === "sub") {
|
|
2033
|
-
return /* @__PURE__ */ (0,
|
|
2435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-live-tl-ico", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-live-tl-subarrows", children: "\u21C5" }) });
|
|
2034
2436
|
}
|
|
2035
|
-
return /* @__PURE__ */ (0,
|
|
2437
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-live-tl-ico", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-live-tl-dot" }) });
|
|
2036
2438
|
}
|
|
2037
2439
|
function EventLabel({ e }) {
|
|
2038
2440
|
if (e.type === "sub") {
|
|
2039
|
-
return /* @__PURE__ */ (0,
|
|
2441
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "ss-w-fandash-live-tl-who", children: [
|
|
2040
2442
|
e.player ?? e.text,
|
|
2041
|
-
e.playerOff ? /* @__PURE__ */ (0,
|
|
2443
|
+
e.playerOff ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "ss-w-fandash-live-tl-off", children: [
|
|
2042
2444
|
" for ",
|
|
2043
2445
|
e.playerOff
|
|
2044
2446
|
] }) : null
|
|
2045
2447
|
] });
|
|
2046
2448
|
}
|
|
2047
|
-
return /* @__PURE__ */ (0,
|
|
2449
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-live-tl-who", children: e.player ?? e.text });
|
|
2048
2450
|
}
|
|
2049
2451
|
function EventRow({ e }) {
|
|
2050
2452
|
const cls = [
|
|
@@ -2052,16 +2454,16 @@ function EventRow({ e }) {
|
|
|
2052
2454
|
e.side === "home" ? "ss-w-fandash-live-tl-ev--home" : "ss-w-fandash-live-tl-ev--away",
|
|
2053
2455
|
e.type === "goal" ? "ss-w-fandash-live-tl-ev--goal" : ""
|
|
2054
2456
|
].filter(Boolean).join(" ");
|
|
2055
|
-
return /* @__PURE__ */ (0,
|
|
2056
|
-
/* @__PURE__ */ (0,
|
|
2057
|
-
/* @__PURE__ */ (0,
|
|
2058
|
-
/* @__PURE__ */ (0,
|
|
2457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cls, children: [
|
|
2458
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "ss-w-fandash-live-tl-txt", children: [
|
|
2459
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(EventLabel, { e }),
|
|
2460
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(EventIcon, { type: e.type })
|
|
2059
2461
|
] }),
|
|
2060
|
-
/* @__PURE__ */ (0,
|
|
2462
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-live-tl-badge", children: e.minuteLabel })
|
|
2061
2463
|
] });
|
|
2062
2464
|
}
|
|
2063
2465
|
function LiveTimelineCard({ card, ui }) {
|
|
2064
|
-
const [expanded, setExpanded] = (0,
|
|
2466
|
+
const [expanded, setExpanded] = (0, import_react16.useState)(false);
|
|
2065
2467
|
const events = card.data.events;
|
|
2066
2468
|
if (!events || events.length === 0) return null;
|
|
2067
2469
|
const sorted = [...events].sort((a, b) => b.minute - a.minute);
|
|
@@ -2069,10 +2471,10 @@ function LiveTimelineCard({ card, ui }) {
|
|
|
2069
2471
|
const shown = expanded ? sorted : sorted.slice(0, SHOWN2);
|
|
2070
2472
|
const showMore = ui?.showMore ?? ((n) => `Show ${n} more`);
|
|
2071
2473
|
const showLess = ui?.showLess ?? "Show less";
|
|
2072
|
-
return /* @__PURE__ */ (0,
|
|
2073
|
-
card.title ? /* @__PURE__ */ (0,
|
|
2074
|
-
/* @__PURE__ */ (0,
|
|
2075
|
-
rest > 0 ? /* @__PURE__ */ (0,
|
|
2474
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-live-timeline", children: [
|
|
2475
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2476
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "ss-w-fandash-live-tl", children: shown.map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(EventRow, { e }, `${e.minute}-${e.side}-${e.type}-${i}`)) }),
|
|
2477
|
+
rest > 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
2076
2478
|
"button",
|
|
2077
2479
|
{
|
|
2078
2480
|
type: "button",
|
|
@@ -2086,8 +2488,8 @@ function LiveTimelineCard({ card, ui }) {
|
|
|
2086
2488
|
}
|
|
2087
2489
|
|
|
2088
2490
|
// src/components/dashboard/MomentumWave.tsx
|
|
2089
|
-
var
|
|
2090
|
-
var
|
|
2491
|
+
var import_react17 = require("react");
|
|
2492
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
2091
2493
|
var WIDTH = 270;
|
|
2092
2494
|
var HEIGHT = 56;
|
|
2093
2495
|
var BASELINE = HEIGHT / 2;
|
|
@@ -2109,14 +2511,14 @@ function MomentumWave({
|
|
|
2109
2511
|
}) {
|
|
2110
2512
|
if (points.length === 0) return null;
|
|
2111
2513
|
const { area, line, lastX, lastY } = buildPaths(points);
|
|
2112
|
-
const clipId = (0,
|
|
2514
|
+
const clipId = (0, import_react17.useId)();
|
|
2113
2515
|
const topClipId = `${clipId}-top`;
|
|
2114
2516
|
const bottomClipId = `${clipId}-bottom`;
|
|
2115
2517
|
const topClass = clubIsHome ? "ss-w-fandash-live-mom-home" : "ss-w-fandash-live-mom-away";
|
|
2116
2518
|
const bottomClass = clubIsHome ? "ss-w-fandash-live-mom-away" : "ss-w-fandash-live-mom-home";
|
|
2117
|
-
return /* @__PURE__ */ (0,
|
|
2118
|
-
caption ? /* @__PURE__ */ (0,
|
|
2119
|
-
/* @__PURE__ */ (0,
|
|
2519
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "ss-w-fandash-live-mom", children: [
|
|
2520
|
+
caption ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "ss-w-fandash-live-mom-caption", children: caption }) : null,
|
|
2521
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
2120
2522
|
"svg",
|
|
2121
2523
|
{
|
|
2122
2524
|
className: "ss-w-fandash-live-mom-svg",
|
|
@@ -2125,15 +2527,15 @@ function MomentumWave({
|
|
|
2125
2527
|
role: "img",
|
|
2126
2528
|
"aria-label": caption ?? "Momentum",
|
|
2127
2529
|
children: [
|
|
2128
|
-
/* @__PURE__ */ (0,
|
|
2129
|
-
/* @__PURE__ */ (0,
|
|
2130
|
-
/* @__PURE__ */ (0,
|
|
2530
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("defs", { children: [
|
|
2531
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("clipPath", { id: topClipId, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("rect", { x: 0, y: 0, width: WIDTH, height: BASELINE }) }),
|
|
2532
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("clipPath", { id: bottomClipId, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("rect", { x: 0, y: BASELINE, width: WIDTH, height: HEIGHT - BASELINE }) })
|
|
2131
2533
|
] }),
|
|
2132
|
-
/* @__PURE__ */ (0,
|
|
2133
|
-
/* @__PURE__ */ (0,
|
|
2134
|
-
/* @__PURE__ */ (0,
|
|
2135
|
-
/* @__PURE__ */ (0,
|
|
2136
|
-
/* @__PURE__ */ (0,
|
|
2534
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("path", { d: area, className: topClass, clipPath: `url(#${topClipId})` }),
|
|
2535
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("path", { d: area, className: bottomClass, clipPath: `url(#${bottomClipId})` }),
|
|
2536
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("line", { x1: 0, y1: BASELINE, x2: WIDTH, y2: BASELINE, className: "ss-w-fandash-live-mom-base" }),
|
|
2537
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("path", { d: line, className: "ss-w-fandash-live-mom-line", vectorEffect: "non-scaling-stroke" }),
|
|
2538
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("circle", { cx: lastX, cy: lastY, r: 3.2, className: "ss-w-fandash-live-mom-now", vectorEffect: "non-scaling-stroke" })
|
|
2137
2539
|
]
|
|
2138
2540
|
}
|
|
2139
2541
|
)
|
|
@@ -2141,7 +2543,7 @@ function MomentumWave({
|
|
|
2141
2543
|
}
|
|
2142
2544
|
|
|
2143
2545
|
// src/components/dashboard/LiveStatsCard.tsx
|
|
2144
|
-
var
|
|
2546
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
2145
2547
|
function splitWidths2(homeNum, awayNum) {
|
|
2146
2548
|
const total = homeNum + awayNum;
|
|
2147
2549
|
if (total <= 0) return { home: "50%", away: "50%" };
|
|
@@ -2150,34 +2552,34 @@ function splitWidths2(homeNum, awayNum) {
|
|
|
2150
2552
|
}
|
|
2151
2553
|
function LiveStatsCard({ card }) {
|
|
2152
2554
|
const { data } = card;
|
|
2153
|
-
return /* @__PURE__ */ (0,
|
|
2154
|
-
card.title ? /* @__PURE__ */ (0,
|
|
2155
|
-
/* @__PURE__ */ (0,
|
|
2555
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "ss-w-fandash-card ss-w-fandash-live-stats", children: [
|
|
2556
|
+
card.title ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title }) : null,
|
|
2557
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "ss-w-fandash-live-stat-rows", children: data.rows.map((r, i) => {
|
|
2156
2558
|
const homeValue = data.clubIsHome ? r.clubValue : r.oppValue;
|
|
2157
2559
|
const awayValue = data.clubIsHome ? r.oppValue : r.clubValue;
|
|
2158
2560
|
const homeNum = data.clubIsHome ? r.clubNum : r.oppNum;
|
|
2159
2561
|
const awayNum = data.clubIsHome ? r.oppNum : r.clubNum;
|
|
2160
2562
|
const { home, away } = splitWidths2(homeNum, awayNum);
|
|
2161
|
-
return /* @__PURE__ */ (0,
|
|
2162
|
-
/* @__PURE__ */ (0,
|
|
2163
|
-
/* @__PURE__ */ (0,
|
|
2164
|
-
/* @__PURE__ */ (0,
|
|
2165
|
-
/* @__PURE__ */ (0,
|
|
2563
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "ss-w-fandash-live-stat", children: [
|
|
2564
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "ss-w-fandash-live-stat-row", children: [
|
|
2565
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "ss-w-fandash-live-stat-value ss-w-fandash-live-stat-value--home", children: homeValue }),
|
|
2566
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "ss-w-fandash-live-stat-label", children: r.label }),
|
|
2567
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "ss-w-fandash-live-stat-value ss-w-fandash-live-stat-value--away", children: awayValue })
|
|
2166
2568
|
] }),
|
|
2167
|
-
/* @__PURE__ */ (0,
|
|
2168
|
-
/* @__PURE__ */ (0,
|
|
2169
|
-
/* @__PURE__ */ (0,
|
|
2569
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "ss-w-fandash-live-bar", children: [
|
|
2570
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "ss-w-fandash-live-bar-home", style: { width: home } }),
|
|
2571
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "ss-w-fandash-live-bar-away", style: { width: away } })
|
|
2170
2572
|
] })
|
|
2171
2573
|
] }, `${r.label}-${i}`);
|
|
2172
2574
|
}) }),
|
|
2173
|
-
data.momentum.length > 0 ? /* @__PURE__ */ (0,
|
|
2174
|
-
data.rows.length > 0 ? /* @__PURE__ */ (0,
|
|
2175
|
-
/* @__PURE__ */ (0,
|
|
2176
|
-
/* @__PURE__ */ (0,
|
|
2575
|
+
data.momentum.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(MomentumWave, { points: data.momentum, caption: data.momentumLabel, clubIsHome: data.clubIsHome }) : data.momentumLabel ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "ss-w-fandash-live-momentum", children: data.momentumLabel }) : null,
|
|
2576
|
+
data.rows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "ss-w-fandash-live-legend", children: [
|
|
2577
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "ss-w-fandash-live-legend-item", children: [
|
|
2578
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("i", { className: "ss-w-fandash-live-legend-swatch ss-w-fandash-live-legend-swatch--home" }),
|
|
2177
2579
|
data.homeName
|
|
2178
2580
|
] }),
|
|
2179
|
-
/* @__PURE__ */ (0,
|
|
2180
|
-
/* @__PURE__ */ (0,
|
|
2581
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "ss-w-fandash-live-legend-item", children: [
|
|
2582
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("i", { className: "ss-w-fandash-live-legend-swatch ss-w-fandash-live-legend-swatch--away" }),
|
|
2181
2583
|
data.awayName
|
|
2182
2584
|
] })
|
|
2183
2585
|
] }) : null
|
|
@@ -2185,7 +2587,7 @@ function LiveStatsCard({ card }) {
|
|
|
2185
2587
|
}
|
|
2186
2588
|
|
|
2187
2589
|
// src/components/dashboard/ClubFanDashboard.tsx
|
|
2188
|
-
var
|
|
2590
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
2189
2591
|
function ClubFanDashboard({ dashboard, onTap, ui }) {
|
|
2190
2592
|
const orderedCards = [
|
|
2191
2593
|
...dashboard.cards.filter((c) => c.cardType === "countdown"),
|
|
@@ -2195,84 +2597,84 @@ function ClubFanDashboard({ dashboard, onTap, ui }) {
|
|
|
2195
2597
|
(c) => c.cardType === "liveTimeline"
|
|
2196
2598
|
);
|
|
2197
2599
|
const goalEvents = timelineCard?.data.events.filter((e) => e.type === "goal");
|
|
2198
|
-
return /* @__PURE__ */ (0,
|
|
2199
|
-
dashboard.greeting ? /* @__PURE__ */ (0,
|
|
2200
|
-
/* @__PURE__ */ (0,
|
|
2600
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "ss-w-fandash", children: [
|
|
2601
|
+
dashboard.greeting ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "ss-w-fandash-greeting", children: dashboard.greeting }) : null,
|
|
2602
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "ss-w-fandash-cards", children: orderedCards.map((card, i) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(FanDashboardCard, { card, onTap, ui, goalEvents }, `${card.cardType}-${i}`)) })
|
|
2201
2603
|
] });
|
|
2202
2604
|
}
|
|
2203
2605
|
function FanDashboardCard({ card, onTap, ui, goalEvents }) {
|
|
2204
2606
|
switch (card.cardType) {
|
|
2205
2607
|
case "fixture":
|
|
2206
|
-
return /* @__PURE__ */ (0,
|
|
2608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(FixtureCard, { card });
|
|
2207
2609
|
case "countdown":
|
|
2208
|
-
return /* @__PURE__ */ (0,
|
|
2610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(CountdownCard, { card });
|
|
2209
2611
|
case "injuries":
|
|
2210
|
-
return /* @__PURE__ */ (0,
|
|
2612
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(InjuriesCard, { card, ui });
|
|
2211
2613
|
case "reasonToBet":
|
|
2212
|
-
return /* @__PURE__ */ (0,
|
|
2614
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ReasonToBetCard, { card });
|
|
2213
2615
|
case "whereToWatch":
|
|
2214
|
-
return /* @__PURE__ */ (0,
|
|
2616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(WhereToWatchCard, { card });
|
|
2215
2617
|
case "congestedWeek":
|
|
2216
|
-
return /* @__PURE__ */ (0,
|
|
2618
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(CongestedWeekCard, { card, onTap });
|
|
2217
2619
|
case "transfers":
|
|
2218
|
-
return /* @__PURE__ */ (0,
|
|
2620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(TransfersCard, { card });
|
|
2219
2621
|
case "links":
|
|
2220
|
-
return /* @__PURE__ */ (0,
|
|
2622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LinksCard, { card });
|
|
2221
2623
|
case "postMatchResult":
|
|
2222
|
-
return /* @__PURE__ */ (0,
|
|
2624
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PostMatchResultCard, { card });
|
|
2223
2625
|
case "postMatchGoals":
|
|
2224
|
-
return /* @__PURE__ */ (0,
|
|
2626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PostMatchGoalsCard, { card, onTap });
|
|
2225
2627
|
case "postMatchStats":
|
|
2226
|
-
return /* @__PURE__ */ (0,
|
|
2628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PostMatchStatsCard, { card, onTap });
|
|
2227
2629
|
case "postMatchTopPerformer":
|
|
2228
|
-
return /* @__PURE__ */ (0,
|
|
2630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PostMatchTopPerformerCard, { card, onTap });
|
|
2229
2631
|
case "postMatchNext":
|
|
2230
|
-
return /* @__PURE__ */ (0,
|
|
2632
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PostMatchNextCard, { card });
|
|
2231
2633
|
case "restingNext":
|
|
2232
|
-
return /* @__PURE__ */ (0,
|
|
2634
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RestingNextCard, { card, onTap });
|
|
2233
2635
|
case "restingStandings":
|
|
2234
|
-
return /* @__PURE__ */ (0,
|
|
2636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RestingStandingsCard, { card, onTap });
|
|
2235
2637
|
case "restingSeason":
|
|
2236
|
-
return /* @__PURE__ */ (0,
|
|
2638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RestingSeasonCard, { card, onTap });
|
|
2237
2639
|
case "restingForm":
|
|
2238
|
-
return /* @__PURE__ */ (0,
|
|
2640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RestingFormCard, { card });
|
|
2239
2641
|
case "liveScore":
|
|
2240
|
-
return /* @__PURE__ */ (0,
|
|
2642
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LiveScoreCard, { card, goalEvents });
|
|
2241
2643
|
case "liveTimeline":
|
|
2242
|
-
return /* @__PURE__ */ (0,
|
|
2644
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LiveTimelineCard, { card, ui });
|
|
2243
2645
|
case "liveStats":
|
|
2244
|
-
return /* @__PURE__ */ (0,
|
|
2646
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LiveStatsCard, { card });
|
|
2245
2647
|
default:
|
|
2246
2648
|
return null;
|
|
2247
2649
|
}
|
|
2248
2650
|
}
|
|
2249
2651
|
|
|
2250
2652
|
// src/components/ChatMessage.tsx
|
|
2251
|
-
var
|
|
2252
|
-
function ChatMessage({ message, disabled, onAct, onTap, ui, slip }) {
|
|
2653
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
2654
|
+
function ChatMessage({ message, disabled, onAct, onTap, ui, slip, monitor }) {
|
|
2253
2655
|
if (message.role === "user") {
|
|
2254
|
-
return /* @__PURE__ */ (0,
|
|
2656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "ss-w-msg ss-w-user", "data-msg-id": message.id, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "ss-w-bubble", children: message.text }) });
|
|
2255
2657
|
}
|
|
2256
2658
|
const onFanDashboardTap = (card) => {
|
|
2257
2659
|
onAct({ message: card.actionLabel, actionRef: card.actionRef, label: card.actionLabel || card.title || "" });
|
|
2258
2660
|
};
|
|
2259
|
-
return /* @__PURE__ */ (0,
|
|
2260
|
-
message.text && !message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0,
|
|
2261
|
-
message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0,
|
|
2262
|
-
message.clubFanDashboard ? /* @__PURE__ */ (0,
|
|
2263
|
-
/* @__PURE__ */ (0,
|
|
2264
|
-
/* @__PURE__ */ (0,
|
|
2265
|
-
/* @__PURE__ */ (0,
|
|
2266
|
-
/* @__PURE__ */ (0,
|
|
2267
|
-
/* @__PURE__ */ (0,
|
|
2661
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "ss-w-msg ss-w-bot", "data-msg-id": message.id, children: [
|
|
2662
|
+
message.text && !message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Markdown, { text: message.text }) : null,
|
|
2663
|
+
message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(GreetingDashboard, { dashboard: message.greetingDashboard, onTap }) : null,
|
|
2664
|
+
message.clubFanDashboard ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ClubFanDashboard, { dashboard: message.clubFanDashboard, onTap: onFanDashboardTap, ui }) : null,
|
|
2665
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(EntityCardList, { cards: message.cards, disabled, showLessLabel: ui?.showLess, showMoreLabel: ui?.showMore }),
|
|
2666
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(BettingInsightList, { insights: message.insights, ui, slip, monitor }),
|
|
2667
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(MarketOddsCardList, { cards: message.marketOdds, ui, slip, monitor }),
|
|
2668
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(OddsMovementCardList, { cards: message.oddsMovement, ui, monitor }),
|
|
2669
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(ActionButtons, { actions: message.actions, loading: false, disabled, onAct })
|
|
2268
2670
|
] });
|
|
2269
2671
|
}
|
|
2270
2672
|
|
|
2271
2673
|
// src/components/IntentChips.tsx
|
|
2272
|
-
var
|
|
2674
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
2273
2675
|
function IntentChips({ chips, onPick }) {
|
|
2274
2676
|
if (chips.length === 0) return null;
|
|
2275
|
-
return /* @__PURE__ */ (0,
|
|
2677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "ss-w-chips", children: chips.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { type: "button", className: "ss-w-chip", onClick: () => onPick(c.text), children: c.text }, `${c.text}-${i}`)) });
|
|
2276
2678
|
}
|
|
2277
2679
|
|
|
2278
2680
|
// src/scroll.ts
|
|
@@ -2282,20 +2684,20 @@ function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
|
|
|
2282
2684
|
}
|
|
2283
2685
|
|
|
2284
2686
|
// src/components/MessageList.tsx
|
|
2285
|
-
var
|
|
2687
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
2286
2688
|
function turnAnchor(messages) {
|
|
2287
2689
|
const last = messages[messages.length - 1];
|
|
2288
2690
|
if (!last || last.role !== "assistant") return null;
|
|
2289
2691
|
const prev = messages[messages.length - 2];
|
|
2290
2692
|
return { turnId: last.id, anchorId: prev && prev.role === "user" ? prev.id : last.id };
|
|
2291
2693
|
}
|
|
2292
|
-
function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
2694
|
+
function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
2293
2695
|
const { state, send } = controller;
|
|
2294
|
-
const listRef = (0,
|
|
2295
|
-
const endRef = (0,
|
|
2296
|
-
const pinnedRef = (0,
|
|
2297
|
-
const anchoredTurnRef = (0,
|
|
2298
|
-
(0,
|
|
2696
|
+
const listRef = (0, import_react18.useRef)(null);
|
|
2697
|
+
const endRef = (0, import_react18.useRef)(null);
|
|
2698
|
+
const pinnedRef = (0, import_react18.useRef)(true);
|
|
2699
|
+
const anchoredTurnRef = (0, import_react18.useRef)(null);
|
|
2700
|
+
(0, import_react18.useEffect)(() => {
|
|
2299
2701
|
const anchor = turnAnchor(state.messages);
|
|
2300
2702
|
const list = listRef.current;
|
|
2301
2703
|
if (anchor && anchor.turnId !== anchoredTurnRef.current) {
|
|
@@ -2310,7 +2712,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
2310
2712
|
}, [state.messages, state.status, state.isStreaming]);
|
|
2311
2713
|
const hasUserMessage = state.messages.some((m) => m.role === "user");
|
|
2312
2714
|
const hasDashboard = state.messages.some((m) => m.role === "assistant" && (m.greetingDashboard || m.clubFanDashboard));
|
|
2313
|
-
return /* @__PURE__ */ (0,
|
|
2715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
2314
2716
|
"div",
|
|
2315
2717
|
{
|
|
2316
2718
|
className: "ss-w-list",
|
|
@@ -2320,7 +2722,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
2320
2722
|
if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current);
|
|
2321
2723
|
},
|
|
2322
2724
|
children: [
|
|
2323
|
-
state.messages.map((m) => /* @__PURE__ */ (0,
|
|
2725
|
+
state.messages.map((m) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2324
2726
|
ChatMessage,
|
|
2325
2727
|
{
|
|
2326
2728
|
message: m,
|
|
@@ -2331,29 +2733,30 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
2331
2733
|
if (m.role === "assistant" && m.greetingDashboard) onDashboardTap?.(tile, index, m.greetingDashboard.layout);
|
|
2332
2734
|
},
|
|
2333
2735
|
ui,
|
|
2334
|
-
slip
|
|
2736
|
+
slip,
|
|
2737
|
+
monitor
|
|
2335
2738
|
},
|
|
2336
2739
|
m.id
|
|
2337
2740
|
)),
|
|
2338
|
-
state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0,
|
|
2741
|
+
state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ActionButtons, { actions: [], loading: true, onAct: () => {
|
|
2339
2742
|
} }) : null,
|
|
2340
|
-
state.status ? /* @__PURE__ */ (0,
|
|
2341
|
-
state.error ? /* @__PURE__ */ (0,
|
|
2342
|
-
/* @__PURE__ */ (0,
|
|
2343
|
-
/* @__PURE__ */ (0,
|
|
2743
|
+
state.status ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "ss-w-status", children: state.status }) : null,
|
|
2744
|
+
state.error ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "ss-w-error", role: "alert", children: [
|
|
2745
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "message" in state.error ? state.error.message : ui.somethingWentWrong }),
|
|
2746
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("button", { type: "button", className: "ss-w-retry", onClick: () => controller.retry(), children: ui.retry })
|
|
2344
2747
|
] }) : null,
|
|
2345
|
-
!hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0,
|
|
2346
|
-
/* @__PURE__ */ (0,
|
|
2748
|
+
!hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(IntentChips, { chips: state.starters, onPick: (t) => send(t) }) : null,
|
|
2749
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { ref: endRef, className: "ss-w-turn-spacer", "aria-hidden": "true" })
|
|
2347
2750
|
]
|
|
2348
2751
|
}
|
|
2349
2752
|
);
|
|
2350
2753
|
}
|
|
2351
2754
|
|
|
2352
2755
|
// src/components/ChatInput.tsx
|
|
2353
|
-
var
|
|
2354
|
-
var
|
|
2756
|
+
var import_react19 = require("react");
|
|
2757
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
2355
2758
|
function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
|
|
2356
|
-
const [value, setValue] = (0,
|
|
2759
|
+
const [value, setValue] = (0, import_react19.useState)("");
|
|
2357
2760
|
const submit = () => {
|
|
2358
2761
|
const t = value.trim();
|
|
2359
2762
|
if (!t) return;
|
|
@@ -2366,18 +2769,228 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
|
|
|
2366
2769
|
submit();
|
|
2367
2770
|
}
|
|
2368
2771
|
};
|
|
2369
|
-
return /* @__PURE__ */ (0,
|
|
2370
|
-
/* @__PURE__ */ (0,
|
|
2371
|
-
streaming ? /* @__PURE__ */ (0,
|
|
2772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "ss-w-input", children: [
|
|
2773
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("textarea", { className: "ss-w-textarea", rows: 1, placeholder, value, disabled: streaming, onChange: (e) => setValue(e.target.value), onKeyDown }),
|
|
2774
|
+
streaming ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: "ss-w-send ss-w-stop", "aria-label": stopLabel, onClick: onStop, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "ss-w-stop-glyph" }) }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: "ss-w-send", "aria-label": sendLabel, onClick: submit, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(SendIcon, {}) })
|
|
2775
|
+
] });
|
|
2776
|
+
}
|
|
2777
|
+
|
|
2778
|
+
// src/components/TabBar.tsx
|
|
2779
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
2780
|
+
var TABS = [
|
|
2781
|
+
{ tab: "chat", labelKey: "tabChat" },
|
|
2782
|
+
{ tab: "matches", labelKey: "tabMatches" },
|
|
2783
|
+
{ tab: "odds", labelKey: "tabOdds" }
|
|
2784
|
+
];
|
|
2785
|
+
function TabBar({ monitor, ui, matchCount, oddsCount }) {
|
|
2786
|
+
if (monitor.pins.length === 0) return null;
|
|
2787
|
+
const counts = { chat: 0, matches: matchCount, odds: oddsCount };
|
|
2788
|
+
const dots = {
|
|
2789
|
+
chat: monitor.chatDot && monitor.activeTab !== "chat",
|
|
2790
|
+
matches: monitor.matchesDot && monitor.activeTab !== "matches",
|
|
2791
|
+
odds: monitor.oddsDot && monitor.activeTab !== "odds"
|
|
2792
|
+
};
|
|
2793
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "ss-w-tabs", role: "tablist", children: TABS.map(({ tab, labelKey }) => {
|
|
2794
|
+
const active = monitor.activeTab === tab;
|
|
2795
|
+
const count = counts[tab];
|
|
2796
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
2797
|
+
"button",
|
|
2798
|
+
{
|
|
2799
|
+
type: "button",
|
|
2800
|
+
role: "tab",
|
|
2801
|
+
"aria-selected": active,
|
|
2802
|
+
"data-on": active ? "" : void 0,
|
|
2803
|
+
className: "ss-w-tab",
|
|
2804
|
+
onClick: () => monitor.setActiveTab(tab),
|
|
2805
|
+
children: [
|
|
2806
|
+
ui[labelKey],
|
|
2807
|
+
count > 0 && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "ss-w-tab-count", children: count }),
|
|
2808
|
+
dots[tab] && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "ss-w-tab-dot", "aria-hidden": "true" })
|
|
2809
|
+
]
|
|
2810
|
+
},
|
|
2811
|
+
tab
|
|
2812
|
+
);
|
|
2813
|
+
}) });
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
// src/components/MonitorMatchCard.tsx
|
|
2817
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
2818
|
+
function chipSelection(row, matchId, conversationId) {
|
|
2819
|
+
const chip = row.market;
|
|
2820
|
+
if (!chip || !chip.addToSlipEnabled || typeof chip.matchOddsId !== "number" || typeof chip.price !== "number") return null;
|
|
2821
|
+
const selection = { matchOddsId: chip.matchOddsId, matchId, oddsDecimal: chip.price };
|
|
2822
|
+
if (conversationId !== void 0) selection.conversationId = conversationId;
|
|
2823
|
+
return selection;
|
|
2824
|
+
}
|
|
2825
|
+
function isPromoted(row, promotedPins) {
|
|
2826
|
+
const chip = row.market;
|
|
2827
|
+
if (!chip) return false;
|
|
2828
|
+
return promotedPins.some((pin) => pin.marketDeveloperName === chip.marketDeveloperName || chip.matchOddsId != null && pin.matchOddsId === chip.matchOddsId);
|
|
2829
|
+
}
|
|
2830
|
+
function formatTime(iso) {
|
|
2831
|
+
return new Date(iso).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
2832
|
+
}
|
|
2833
|
+
function MonitorMatchCard({ match, promotedPins, monitor, ui, slip }) {
|
|
2834
|
+
const live = match.phase === "live";
|
|
2835
|
+
const scorers = match.events.filter((e) => e.type === "goal");
|
|
2836
|
+
const promotedRows = match.statRows.filter((row) => isPromoted(row, promotedPins));
|
|
2837
|
+
const otherRows = match.statRows.filter((row) => !isPromoted(row, promotedPins));
|
|
2838
|
+
const orderedRows = [...promotedRows, ...otherRows];
|
|
2839
|
+
const kickoff = match.phase === "preMatch" && match.kickoffUtc ? ui.bettingKickoff(match.kickoffUtc) : void 0;
|
|
2840
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "ss-w-mon", children: [
|
|
2841
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "ss-w-mon-top", children: [
|
|
2842
|
+
live && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "ss-w-fandash-live-pill", children: [
|
|
2843
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-fandash-live-dot", "aria-hidden": "true" }),
|
|
2844
|
+
ui.liveLabel
|
|
2845
|
+
] }),
|
|
2846
|
+
match.phase === "fullTime" && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-pill", children: ui.fullTimeLabel }),
|
|
2847
|
+
kickoff && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "ss-w-mon-pill", children: [
|
|
2848
|
+
kickoff.dayLabel,
|
|
2849
|
+
" \xB7 ",
|
|
2850
|
+
kickoff.time
|
|
2851
|
+
] }),
|
|
2852
|
+
live && match.minuteLabel && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-min", children: match.minuteLabel }),
|
|
2853
|
+
match.competitionName && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-comp", children: match.competitionName }),
|
|
2854
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(PinToggle, { ui, monitor, pin: { kind: "match", matchId: match.matchId } })
|
|
2855
|
+
] }),
|
|
2856
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "ss-w-mon-main", children: [
|
|
2857
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "ss-w-mon-side", children: [
|
|
2858
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Crest2, { kind: "team", url: match.homeCrestUrl ?? void 0, name: match.homeTeamName ?? void 0 }),
|
|
2859
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-name", children: match.homeTeamName })
|
|
2860
|
+
] }),
|
|
2861
|
+
match.phase === "preMatch" ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-vs", children: "vs" }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "ss-w-mon-score", children: [
|
|
2862
|
+
match.homeScore,
|
|
2863
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("i", { children: "\u2013" }),
|
|
2864
|
+
match.awayScore
|
|
2865
|
+
] }),
|
|
2866
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "ss-w-mon-side ss-w-mon-side--away", children: [
|
|
2867
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Crest2, { kind: "team", url: match.awayCrestUrl ?? void 0, name: match.awayTeamName ?? void 0 }),
|
|
2868
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-name", children: match.awayTeamName })
|
|
2869
|
+
] })
|
|
2870
|
+
] }),
|
|
2871
|
+
scorers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "ss-w-mon-scorers", children: scorers.map((e) => `${e.player ?? ""} ${e.minuteLabel}`).join(", ") }),
|
|
2872
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "ss-w-mon-stats", children: orderedRows.map((row) => {
|
|
2873
|
+
const total = row.homeNum + row.awayNum;
|
|
2874
|
+
const homePct = total > 0 ? row.homeNum / total * 75 : 0;
|
|
2875
|
+
const awayPct = total > 0 ? row.awayNum / total * 75 : 0;
|
|
2876
|
+
const promoted = isPromoted(row, promotedPins);
|
|
2877
|
+
const selection = chipSelection(row, match.matchId, slip.conversationId);
|
|
2878
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: promoted ? "ss-w-mon-stat ss-w-mon-pstrip" : "ss-w-mon-stat", children: [
|
|
2879
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "ss-w-mon-stat-row", children: [
|
|
2880
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-stat-v ss-w-mon-stat-v--home", children: row.homeValue }),
|
|
2881
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-stat-l", children: row.label }),
|
|
2882
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-stat-v ss-w-mon-stat-v--away", children: row.awayValue })
|
|
2883
|
+
] }),
|
|
2884
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "ss-w-mon-bar", children: [
|
|
2885
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("b", { className: "ss-w-mon-bar-home", style: { width: `${homePct}%` } }),
|
|
2886
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("i", { className: "ss-w-mon-bar-away", style: { width: `${awayPct}%` } })
|
|
2887
|
+
] }),
|
|
2888
|
+
row.market && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: promoted ? "ss-w-mon-stat-mkt ss-w-mon-mkt" : "ss-w-mon-stat-mkt", children: [
|
|
2889
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { children: [
|
|
2890
|
+
row.market.marketLabel,
|
|
2891
|
+
" \xB7 ",
|
|
2892
|
+
row.market.selectionLabel
|
|
2893
|
+
] }),
|
|
2894
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "ss-w-mon-stat-mkt-right", children: [
|
|
2895
|
+
row.market.isSuspended ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-susp", children: ui.suspendedLabel }) : typeof row.market.price === "number" && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-price", children: row.market.price.toFixed(2) }),
|
|
2896
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
2897
|
+
SlipButton,
|
|
2898
|
+
{
|
|
2899
|
+
selection,
|
|
2900
|
+
shownOdds: typeof row.market.price === "number" ? row.market.price.toFixed(2) : "",
|
|
2901
|
+
marketName: row.market.marketLabel,
|
|
2902
|
+
slip,
|
|
2903
|
+
ui
|
|
2904
|
+
}
|
|
2905
|
+
)
|
|
2906
|
+
] })
|
|
2907
|
+
] })
|
|
2908
|
+
] }, row.label);
|
|
2909
|
+
}) }),
|
|
2910
|
+
match.status === "stale" && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-mon-asof", children: ui.asOf(formatTime(match.asOfUtc)) }),
|
|
2911
|
+
match.momentum.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(MomentumWave, { points: match.momentum, clubIsHome: true }),
|
|
2912
|
+
match.mainMarket && match.phase !== "fullTime" && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(MarketOddsCardList, { cards: [toMarketOddsVM(match.mainMarket)], ui, slip }),
|
|
2913
|
+
match.phase === "fullTime" && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "ss-w-mon-grace", children: ui.graceNote })
|
|
2372
2914
|
] });
|
|
2373
2915
|
}
|
|
2374
2916
|
|
|
2917
|
+
// src/components/MonitorTabs.tsx
|
|
2918
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
2919
|
+
function ContextLine({ m, monitor, ui }) {
|
|
2920
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "ss-w-mk-ctx", children: [
|
|
2921
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Crest2, { kind: "team", name: m.homeTeamName ?? void 0 }),
|
|
2922
|
+
typeof m.homeScore === "number" && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("b", { children: [
|
|
2923
|
+
m.homeScore,
|
|
2924
|
+
"\u2013",
|
|
2925
|
+
m.awayScore
|
|
2926
|
+
] }),
|
|
2927
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Crest2, { kind: "team", name: m.awayTeamName ?? void 0 }),
|
|
2928
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "ss-w-mon-name", children: [
|
|
2929
|
+
m.homeTeamName,
|
|
2930
|
+
" v ",
|
|
2931
|
+
m.awayTeamName
|
|
2932
|
+
] }),
|
|
2933
|
+
m.minuteLabel && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ss-w-mon-min", children: m.minuteLabel }),
|
|
2934
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "ss-w-mk-ctx-right", children: [
|
|
2935
|
+
m.isSuspended && !m.isSettled && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ss-w-mon-susp", children: ui.suspendedLabel }),
|
|
2936
|
+
m.isSettled && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ss-w-mon-pill", children: ui.fullTimeLabel }),
|
|
2937
|
+
m.status === "stale" && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ss-w-mon-asof", children: ui.asOf(new Date(m.asOfUtc).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })) }),
|
|
2938
|
+
(() => {
|
|
2939
|
+
const pin = monitor.pins.find((p) => p.key === m.key);
|
|
2940
|
+
return pin ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(PinToggle, { ui, monitor, pin }) : null;
|
|
2941
|
+
})()
|
|
2942
|
+
] })
|
|
2943
|
+
] });
|
|
2944
|
+
}
|
|
2945
|
+
function MatchesPanel({ monitor, ui, slip }) {
|
|
2946
|
+
const matches = (monitor.snapshot?.matches ?? []).filter((m) => monitor.pins.some((p) => p.kind === "match" && p.matchId === m.matchId));
|
|
2947
|
+
if (matches.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "ss-w-mon-empty", children: ui.emptyMatchesTab });
|
|
2948
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "ss-w-mon-list", children: matches.map((m) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
2949
|
+
MonitorMatchCard,
|
|
2950
|
+
{
|
|
2951
|
+
match: m,
|
|
2952
|
+
promotedPins: monitor.pins.filter((p) => p.kind !== "match" && p.matchId === m.matchId),
|
|
2953
|
+
monitor,
|
|
2954
|
+
ui,
|
|
2955
|
+
slip
|
|
2956
|
+
},
|
|
2957
|
+
m.matchId
|
|
2958
|
+
)) });
|
|
2959
|
+
}
|
|
2960
|
+
function withSinceViewMovement(vm, prev) {
|
|
2961
|
+
const primary = vm.mainRows[0];
|
|
2962
|
+
if (prev === void 0 || !primary || primary.oddsDecimal === void 0 || primary.oddsDecimal === prev) return vm;
|
|
2963
|
+
const updatedPrimary = {
|
|
2964
|
+
...primary,
|
|
2965
|
+
previousOdds: prev.toFixed(2),
|
|
2966
|
+
movementDirection: primary.oddsDecimal < prev ? "shortened" : "drifted"
|
|
2967
|
+
};
|
|
2968
|
+
return { ...vm, mainRows: [updatedPrimary, ...vm.mainRows.slice(1)] };
|
|
2969
|
+
}
|
|
2970
|
+
function OddsPanel({ monitor, ui, slip }) {
|
|
2971
|
+
const markets = (monitor.snapshot?.markets ?? []).filter((m) => monitor.pins.some((p) => p.key === m.key));
|
|
2972
|
+
if (markets.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "ss-w-mon-empty", children: ui.emptyOddsTab });
|
|
2973
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "ss-w-mon-list", children: markets.map((m) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "ss-w-mon-oddspin", "data-settled": m.isSettled || void 0, children: [
|
|
2974
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ContextLine, { m, monitor, ui }),
|
|
2975
|
+
m.card && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
2976
|
+
MarketOddsCardList,
|
|
2977
|
+
{
|
|
2978
|
+
cards: [withSinceViewMovement(toMarketOddsVM(m.card), monitor.lastViewedPrices[m.key])],
|
|
2979
|
+
ui,
|
|
2980
|
+
slip,
|
|
2981
|
+
inSlipIds: monitor.inSlip
|
|
2982
|
+
}
|
|
2983
|
+
),
|
|
2984
|
+
m.history && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(OddsMovementCardList, { cards: [toOddsMovementVM(m.history)], ui })
|
|
2985
|
+
] }, m.key)) });
|
|
2986
|
+
}
|
|
2987
|
+
|
|
2375
2988
|
// src/components/ChatPanel.tsx
|
|
2376
|
-
var
|
|
2989
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
2377
2990
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
2378
2991
|
function useIsModal() {
|
|
2379
|
-
const [modal, setModal] = (0,
|
|
2380
|
-
(0,
|
|
2992
|
+
const [modal, setModal] = (0, import_react20.useState)(false);
|
|
2993
|
+
(0, import_react20.useEffect)(() => {
|
|
2381
2994
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
2382
2995
|
const mql = window.matchMedia(FULLSCREEN_QUERY);
|
|
2383
2996
|
const sync = () => setModal(mql.matches);
|
|
@@ -2387,20 +3000,44 @@ function useIsModal() {
|
|
|
2387
3000
|
}, []);
|
|
2388
3001
|
return modal;
|
|
2389
3002
|
}
|
|
2390
|
-
function ChatPanel({ controller, ui, slip, onDashboardTap }) {
|
|
3003
|
+
function ChatPanel({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
2391
3004
|
const { state, close, stop, send } = controller;
|
|
2392
3005
|
const isModal = useIsModal();
|
|
2393
|
-
(0,
|
|
3006
|
+
(0, import_react20.useEffect)(() => {
|
|
2394
3007
|
const onKey = (e) => {
|
|
2395
3008
|
if (e.key === "Escape") close();
|
|
2396
3009
|
};
|
|
2397
3010
|
window.addEventListener("keydown", onKey);
|
|
2398
3011
|
return () => window.removeEventListener("keydown", onKey);
|
|
2399
3012
|
}, [close]);
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
3013
|
+
const handleSend = (text) => {
|
|
3014
|
+
monitor?.setActiveTab("chat");
|
|
3015
|
+
send(text);
|
|
3016
|
+
};
|
|
3017
|
+
(0, import_react20.useEffect)(() => {
|
|
3018
|
+
if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
|
|
3019
|
+
}, [monitor, state.isStreaming, state.messages.length]);
|
|
3020
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
|
|
3021
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChatHeader, { onClose: close, closeLabel: ui.closeChat }),
|
|
3022
|
+
monitor && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
3023
|
+
TabBar,
|
|
3024
|
+
{
|
|
3025
|
+
monitor,
|
|
3026
|
+
ui,
|
|
3027
|
+
matchCount: monitor.pins.filter((p) => p.kind === "match").length,
|
|
3028
|
+
oddsCount: monitor.pins.filter((p) => p.kind !== "match").length
|
|
3029
|
+
}
|
|
3030
|
+
),
|
|
3031
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
3032
|
+
"div",
|
|
3033
|
+
{
|
|
3034
|
+
style: !monitor || monitor.activeTab === "chat" ? { display: "contents" } : { position: "absolute", inset: 0, visibility: "hidden", display: "flex", flexDirection: "column" },
|
|
3035
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(MessageList, { controller, ui, slip, onDashboardTap, monitor })
|
|
3036
|
+
}
|
|
3037
|
+
),
|
|
3038
|
+
monitor && monitor.activeTab === "matches" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(MatchesPanel, { monitor, ui, slip }),
|
|
3039
|
+
monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(OddsPanel, { monitor, ui, slip }),
|
|
3040
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: handleSend, onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
|
|
2404
3041
|
] });
|
|
2405
3042
|
}
|
|
2406
3043
|
|
|
@@ -2468,7 +3105,10 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
2468
3105
|
.ss-w-close { margin-left: auto; background: none; border: none; color: var(--ss-w-faint); cursor: pointer; font-size: 16px; display: grid; place-items: center; }
|
|
2469
3106
|
|
|
2470
3107
|
/* messages */
|
|
2471
|
-
.ss-w-list
|
|
3108
|
+
/* .ss-w-mon-list (Matches/Odds tab scrollers) shares .ss-w-list's box/scroll rules by design --
|
|
3109
|
+
same visual rhythm as the chat message list -- but gets its own class so it isn't the same DOM
|
|
3110
|
+
landmark as the chat list when both exist in the panel at once (Task 16 fix round, M4). */
|
|
3111
|
+
.ss-w-list, .ss-w-mon-list { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 12px; scroll-padding-top: 14px; }
|
|
2472
3112
|
/* Transient bottom spacer: reserves a viewport of room below a new turn so its
|
|
2473
3113
|
top can be scrolled into view while the reply is still streaming in. Height is
|
|
2474
3114
|
set imperatively and flex must not shrink it away. */
|
|
@@ -2584,8 +3224,6 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
2584
3224
|
.ss-w-bi-odds b { font-size: 20px; font-family: ui-monospace, monospace; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ss-w-accent); line-height: 1.05; }
|
|
2585
3225
|
.ss-w-bi-book { font-size: 9.5px; color: var(--ss-w-faint); }
|
|
2586
3226
|
.ss-w-bi-action-row .ss-w-slip { flex: none; }
|
|
2587
|
-
/* let the slip toast size to its own text and anchor to the card's right edge, not the button width */
|
|
2588
|
-
.ss-w-bi-action-row .ss-w-toast { left: auto; right: 0; width: max-content; max-width: 210px; white-space: normal; }
|
|
2589
3227
|
|
|
2590
3228
|
/* row 3: bar-chart glyph + reasoning prose + stats-expander chevron, in a subtle strip */
|
|
2591
3229
|
.ss-w-bi-reason { display: flex; align-items: flex-start; gap: 8px; background: var(--ss-w-bubble); border-radius: 10px; padding: 8px 10px; }
|
|
@@ -2692,10 +3330,21 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
2692
3330
|
.ss-w-slip { position: relative; display: flex; }
|
|
2693
3331
|
.ss-w-slip-btn { font-size: 11.5px; font-weight: 620; color: var(--ss-w-cta-ink); background: var(--ss-w-cta); border: 1px solid var(--ss-w-cta); border-radius: 14px; padding: 5px 12px; cursor: pointer; }
|
|
2694
3332
|
.ss-w-slip-btn:disabled { opacity: .6; cursor: default; background: var(--ss-w-bubble); color: var(--ss-w-faint); border-color: var(--ss-w-line); }
|
|
2695
|
-
|
|
3333
|
+
/* Anchored to the RIGHT of its (narrow) button wrapper and sized by content, growing leftward
|
|
3334
|
+
into the card -- inheriting the wrapper's width squeezes the text to one character per line.
|
|
3335
|
+
Every toast site (slip buttons, pin toggles) sits at the right edge of its row. */
|
|
3336
|
+
.ss-w-toast { position: absolute; top: calc(100% + 6px); right: 0; z-index: 1; width: max-content; max-width: 210px; font-size: 11px; font-weight: 560; border-radius: 10px; padding: 5px 10px; overflow-wrap: anywhere; box-shadow: 0 4px 14px rgba(0,0,0,.14); }
|
|
2696
3337
|
.ss-w-toast-success { color: var(--ss-w-accent); background: color-mix(in srgb, var(--ss-w-accent) 14%, var(--ss-w-panel)); border: 1px solid color-mix(in srgb, var(--ss-w-accent) 30%, var(--ss-w-line)); }
|
|
2697
3338
|
.ss-w-toast-error { color: #c0392b; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); }
|
|
2698
3339
|
|
|
3340
|
+
/* pin affordance */
|
|
3341
|
+
.ss-w-pin-wrap { position: relative; display: inline-flex; flex: none; }
|
|
3342
|
+
.ss-w-pin { flex: none; display: grid; place-items: center; width: 22px; height: 22px; padding: 0; border-radius: 50%; background: none; border: 1px solid var(--ss-w-line); color: var(--ss-w-faint); cursor: pointer; }
|
|
3343
|
+
.ss-w-pin svg { width: 12px; height: 12px; }
|
|
3344
|
+
.ss-w-pin:hover { color: var(--ss-w-ink); border-color: var(--ss-w-faint); }
|
|
3345
|
+
.ss-w-pin[data-on] { background: var(--ss-w-accent); border-color: var(--ss-w-accent); color: #fff; }
|
|
3346
|
+
.ss-w-pin[data-on]:hover { background: var(--ss-w-accent); color: #fff; }
|
|
3347
|
+
|
|
2699
3348
|
@media (prefers-reduced-motion: reduce) {
|
|
2700
3349
|
.ss-w-abtn-shimmer { animation: none; }
|
|
2701
3350
|
}
|
|
@@ -3064,10 +3713,68 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
3064
3713
|
.ss-w-fandash-live-legend-swatch { width: 10px; height: 10px; border-radius: 3px; flex: none; }
|
|
3065
3714
|
.ss-w-fandash-live-legend-swatch--home { background: var(--ss-w-home); }
|
|
3066
3715
|
.ss-w-fandash-live-legend-swatch--away { background: var(--ss-w-away); }
|
|
3716
|
+
|
|
3717
|
+
/* live monitor tab bar: underline pattern mirrors .ss-w-ecard-scope; the unread dot uses --ss-w-neg */
|
|
3718
|
+
.ss-w-tabs { display: flex; align-items: stretch; gap: 2px; border-bottom: 1px solid var(--ss-w-line); }
|
|
3719
|
+
.ss-w-tab { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 620; color: var(--ss-w-faint); background: none; border: none; cursor: pointer; padding: 9px 12px; margin-bottom: -1px; border-bottom: 2px solid transparent; }
|
|
3720
|
+
.ss-w-tab[data-on] { color: var(--ss-w-ink); border-bottom-color: var(--ss-w-accent); }
|
|
3721
|
+
.ss-w-tab-count { font-size: 10.5px; font-weight: 700; color: var(--ss-w-faint); background: var(--ss-w-bubble); border-radius: 999px; padding: 1px 6px; }
|
|
3722
|
+
.ss-w-tab[data-on] .ss-w-tab-count { color: var(--ss-w-accent); }
|
|
3723
|
+
.ss-w-tab-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ss-w-neg); flex: none; }
|
|
3724
|
+
|
|
3725
|
+
/* Matches tab match card (MonitorMatchCard): pill row, crest/score main row, per-stat split
|
|
3726
|
+
bars (venue-oriented -- home always left/blue, away always right/red, never club-oriented,
|
|
3727
|
+
the u316 bug class), a promoted-market strip for the user's pinned stat chips, and a grace
|
|
3728
|
+
note once the match has gone full time. Reuses the --ss-w-home/--ss-w-away/--ss-w-track venue
|
|
3729
|
+
tokens and .ss-w-fandash-live-pill for the Live pill so all live surfaces share one look. */
|
|
3730
|
+
.ss-w-mon { display: flex; flex-direction: column; gap: 10px; padding: 12px; border: 1px solid var(--ss-w-line); border-radius: 12px; background: var(--ss-w-panel); }
|
|
3731
|
+
.ss-w-mon-top { display: flex; align-items: center; gap: 8px; }
|
|
3732
|
+
.ss-w-mon-pill { display: inline-flex; flex: none; align-items: center; font-size: 10.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--ss-w-faint); background: var(--ss-w-bubble); border-radius: 6px; padding: 3px 8px; }
|
|
3733
|
+
.ss-w-mon-min { flex: none; font-size: 12.5px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
|
|
3734
|
+
.ss-w-mon-comp { margin-left: auto; font-size: 11px; font-weight: 650; color: var(--ss-w-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
3735
|
+
.ss-w-mon-main { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px; }
|
|
3736
|
+
.ss-w-mon-side { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
|
3737
|
+
.ss-w-mon-side--away { flex-direction: row-reverse; text-align: right; }
|
|
3738
|
+
.ss-w-mon-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13.5px; font-weight: 700; color: var(--ss-w-ink); }
|
|
3739
|
+
.ss-w-mon-vs { font-size: 12px; font-weight: 700; color: var(--ss-w-faint); text-transform: uppercase; }
|
|
3740
|
+
.ss-w-mon-score { display: flex; align-items: baseline; justify-content: center; font-size: 26px; font-weight: 850; font-variant-numeric: tabular-nums; line-height: 1; white-space: nowrap; color: var(--ss-w-ink); }
|
|
3741
|
+
.ss-w-mon-score i { font-style: normal; color: var(--ss-w-faint); font-weight: 500; margin: 0 4px; }
|
|
3742
|
+
.ss-w-mon-scorers { font-size: 11.5px; color: var(--ss-w-faint); overflow-wrap: anywhere; }
|
|
3743
|
+
.ss-w-mon-stats { display: flex; flex-direction: column; gap: 10px; }
|
|
3744
|
+
.ss-w-mon-stat { display: flex; flex-direction: column; gap: 5px; }
|
|
3745
|
+
.ss-w-mon-pstrip { padding: 6px 8px; border-radius: 8px; background: color-mix(in srgb, var(--ss-w-accent) 8%, transparent); }
|
|
3746
|
+
.ss-w-mon-stat-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: baseline; gap: 8px; }
|
|
3747
|
+
.ss-w-mon-stat-v { font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
|
|
3748
|
+
.ss-w-mon-stat-v--home { color: var(--ss-w-home); }
|
|
3749
|
+
.ss-w-mon-stat-v--away { color: var(--ss-w-away); text-align: right; }
|
|
3750
|
+
.ss-w-mon-stat-l { font-size: 10px; font-weight: 700; text-align: center; color: var(--ss-w-faint); text-transform: uppercase; letter-spacing: .03em; }
|
|
3751
|
+
.ss-w-mon-bar { position: relative; height: 6px; border-radius: 999px; background: var(--ss-w-track); overflow: hidden; display: flex; }
|
|
3752
|
+
.ss-w-mon-bar-home { height: 100%; background: var(--ss-w-home); }
|
|
3753
|
+
.ss-w-mon-bar-away { height: 100%; background: var(--ss-w-away); margin-left: auto; }
|
|
3754
|
+
.ss-w-mon-stat-mkt { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--ss-w-faint); }
|
|
3755
|
+
.ss-w-mon-mkt { background: color-mix(in srgb, var(--ss-w-accent) 10%, transparent); border-radius: 6px; padding: 3px 6px; color: var(--ss-w-ink); }
|
|
3756
|
+
.ss-w-mon-stat-mkt-right { display: flex; align-items: center; gap: 6px; margin-left: auto; }
|
|
3757
|
+
.ss-w-mon-price { font-family: ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 700; color: var(--ss-w-accent); }
|
|
3758
|
+
.ss-w-mon-susp { font-size: 10.5px; font-weight: 700; color: var(--ss-w-faint); background: var(--ss-w-bubble); border-radius: 6px; padding: 2px 6px; }
|
|
3759
|
+
.ss-w-mon-asof { display: block; font-size: 10.5px; font-weight: 600; color: var(--ss-w-cta); }
|
|
3760
|
+
.ss-w-mon-grace { font-size: 11px; color: var(--ss-w-faint); border-top: 1px solid var(--ss-w-line); padding-top: 8px; }
|
|
3761
|
+
|
|
3762
|
+
/* Matches/Odds tab panels (MonitorTabs): the shared per-market-pin context line, the empty
|
|
3763
|
+
state shown when the snapshot carries no matches/markets yet, the persistent D5 in-slip badge,
|
|
3764
|
+
and the per-market-pin wrapper card (struck price on settlement is a pure CSS hook off its
|
|
3765
|
+
[data-settled] attribute -- no separate class on the price element itself). */
|
|
3766
|
+
.ss-w-mk-ctx { display: flex; align-items: center; gap: 6px; padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid var(--ss-w-line); }
|
|
3767
|
+
.ss-w-mk-ctx-right { display: flex; align-items: center; gap: 6px; margin-left: auto; }
|
|
3768
|
+
/* flex:1 keeps the composer pinned to the panel bottom when a tab is empty */
|
|
3769
|
+
.ss-w-mon-empty { flex: 1; padding: 24px 16px; text-align: center; font-size: 12.5px; color: var(--ss-w-faint); }
|
|
3770
|
+
.ss-w-mon-inslip { display: inline-flex; flex: none; align-items: center; gap: 3px; font-size: 10.5px; font-weight: 700; color: var(--ss-w-pos); }
|
|
3771
|
+
.ss-w-mon-oddspin { display: flex; flex-direction: column; gap: 10px; padding: 12px; border: 1px solid var(--ss-w-line); border-radius: 12px; background: var(--ss-w-panel); }
|
|
3772
|
+
.ss-w-mon-oddspin[data-settled] .ss-w-mo-price,
|
|
3773
|
+
.ss-w-mon-oddspin[data-settled] .ss-w-mon-price { text-decoration: line-through; color: var(--ss-w-faint); }
|
|
3067
3774
|
`;
|
|
3068
3775
|
|
|
3069
3776
|
// src/StatsWidget.tsx
|
|
3070
|
-
var
|
|
3777
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
3071
3778
|
function buildClient(props) {
|
|
3072
3779
|
try {
|
|
3073
3780
|
if ("client" in props && props.client) {
|
|
@@ -3092,35 +3799,50 @@ function injectStyles(root) {
|
|
|
3092
3799
|
function StatsWidget(props) {
|
|
3093
3800
|
const injectedClient = "client" in props ? props.client : void 0;
|
|
3094
3801
|
const cfg = props.config;
|
|
3095
|
-
const built = (0,
|
|
3096
|
-
const ui = (0,
|
|
3097
|
-
const rootRef = (0,
|
|
3802
|
+
const built = (0, import_react21.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
|
|
3803
|
+
const ui = (0, import_react21.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
|
|
3804
|
+
const rootRef = (0, import_react21.useRef)(null);
|
|
3098
3805
|
const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0);
|
|
3099
|
-
const
|
|
3100
|
-
() => (
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3806
|
+
const monitor = useLiveMonitor({
|
|
3807
|
+
getLiveMonitor: (pins) => built ? built.conversation.getLiveMonitor(pins) : Promise.resolve(null),
|
|
3808
|
+
storageKey: `ss-w-pins:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`,
|
|
3809
|
+
isOpen: controller.state.isOpen
|
|
3810
|
+
});
|
|
3811
|
+
const slip = (0, import_react21.useMemo)(
|
|
3812
|
+
() => {
|
|
3813
|
+
const handler = props.config?.onAddToSlip;
|
|
3814
|
+
return {
|
|
3815
|
+
// I3: the D5 persistent in-slip badge must arm from ANY add path -- a chat-message
|
|
3816
|
+
// insight/market card, not just the ones rendered inside the Odds tab itself -- so the
|
|
3817
|
+
// wasAdded->markInSlip wrap lives here (once), not duplicated per consumer.
|
|
3818
|
+
onAddToSlip: handler && (async (sel) => {
|
|
3819
|
+
const result = await handler(sel);
|
|
3820
|
+
if (wasAdded(result)) monitor.markInSlip(sel.matchOddsId);
|
|
3821
|
+
return result;
|
|
3822
|
+
}),
|
|
3823
|
+
conversationId: controller.state.conversationId ?? void 0,
|
|
3824
|
+
onMarketClicked: (marketName) => {
|
|
3825
|
+
try {
|
|
3826
|
+
void built?.conversation.sendSignal({ signalType: "InsightMarketClicked", entityType: "Market", entityName: marketName }).catch(() => void 0);
|
|
3827
|
+
} catch {
|
|
3828
|
+
}
|
|
3107
3829
|
}
|
|
3108
|
-
}
|
|
3109
|
-
}
|
|
3110
|
-
[props.config?.onAddToSlip, controller.state.conversationId, built]
|
|
3830
|
+
};
|
|
3831
|
+
},
|
|
3832
|
+
[props.config?.onAddToSlip, controller.state.conversationId, built, monitor.markInSlip]
|
|
3111
3833
|
);
|
|
3112
|
-
const onDashboardTap = (0,
|
|
3834
|
+
const onDashboardTap = (0, import_react21.useMemo)(
|
|
3113
3835
|
() => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input)) : void 0,
|
|
3114
3836
|
[built]
|
|
3115
3837
|
);
|
|
3116
|
-
(0,
|
|
3838
|
+
(0, import_react21.useEffect)(() => {
|
|
3117
3839
|
if (!built || !ui.injectStyles) return;
|
|
3118
3840
|
const node = rootRef.current?.getRootNode();
|
|
3119
3841
|
if (node) injectStyles(node);
|
|
3120
3842
|
}, [built, ui.injectStyles]);
|
|
3121
3843
|
if (!built) return null;
|
|
3122
3844
|
const attrs = themeAttrs(ui);
|
|
3123
|
-
return /* @__PURE__ */ (0,
|
|
3845
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("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__ */ (0, import_jsx_runtime48.jsx)(ChatPanel, { controller, ui, slip, onDashboardTap, monitor: monitor.enabled ? monitor : void 0 }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
3124
3846
|
ChatFab,
|
|
3125
3847
|
{
|
|
3126
3848
|
label: ui.launcherLabel,
|