@sensiblestats/widget-react 0.29.5 → 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 +22 -0
- package/dist/index.cjs +1335 -590
- 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 +1329 -584
- package/dist/index.js.map +1 -1
- package/dist/styles.css +93 -11
- 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,98 +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
|
|
1463
|
-
function
|
|
1464
|
-
|
|
1465
|
-
if (
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
}
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
}
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
/* @__PURE__ */ (0,
|
|
1475
|
-
|
|
1476
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ss-w-fandash-formrow-name", children: name })
|
|
1477
|
-
] }),
|
|
1478
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FormStrip, { form })
|
|
1864
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1865
|
+
function teamFormResultClass(result) {
|
|
1866
|
+
if (result === "W") return "ss-w-fandash-teamform-cell--win";
|
|
1867
|
+
if (result === "L") return "ss-w-fandash-teamform-cell--loss";
|
|
1868
|
+
return "ss-w-fandash-teamform-cell--draw";
|
|
1869
|
+
}
|
|
1870
|
+
function TeamFormCell({ m, subjectCrestUrl, subjectName }) {
|
|
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" });
|
|
1873
|
+
const score = m.teamIsHome ? `${m.teamScore} - ${m.oppScore}` : `${m.oppScore} - ${m.teamScore}`;
|
|
1874
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `ss-w-fandash-teamform-cell ${teamFormResultClass(m.result)}`, children: [
|
|
1875
|
+
m.teamIsHome ? subjectCrest : opponentCrest,
|
|
1876
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-teamform-score", children: score }),
|
|
1877
|
+
m.teamIsHome ? opponentCrest : subjectCrest
|
|
1479
1878
|
] });
|
|
1480
1879
|
}
|
|
1880
|
+
var TEAM_FORM_ROWS = 5;
|
|
1881
|
+
function teamFormRows(data) {
|
|
1882
|
+
return Array.from({ length: TEAM_FORM_ROWS }, (_, i) => i).flatMap((i) => [
|
|
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}`)
|
|
1885
|
+
]);
|
|
1886
|
+
}
|
|
1481
1887
|
function FixtureCard({ card }) {
|
|
1482
1888
|
const { data } = card;
|
|
1483
1889
|
const h2h = data.h2H;
|
|
1484
|
-
return /* @__PURE__ */ (0,
|
|
1485
|
-
/* @__PURE__ */ (0,
|
|
1486
|
-
/* @__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: [
|
|
1487
1893
|
card.title,
|
|
1488
1894
|
" \xB7 ",
|
|
1489
1895
|
data.competition
|
|
1490
1896
|
] }),
|
|
1491
|
-
/* @__PURE__ */ (0,
|
|
1492
|
-
/* @__PURE__ */ (0,
|
|
1493
|
-
/* @__PURE__ */ (0,
|
|
1494
|
-
/* @__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 })
|
|
1495
1901
|
] }),
|
|
1496
|
-
/* @__PURE__ */ (0,
|
|
1497
|
-
/* @__PURE__ */ (0,
|
|
1498
|
-
/* @__PURE__ */ (0,
|
|
1499
|
-
/* @__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" })
|
|
1500
1906
|
] })
|
|
1501
1907
|
] }),
|
|
1502
|
-
/* @__PURE__ */ (0,
|
|
1503
|
-
/* @__PURE__ */ (0,
|
|
1504
|
-
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: [
|
|
1505
1911
|
" \xB7 ",
|
|
1506
1912
|
data.venue
|
|
1507
1913
|
] }) : null
|
|
1508
1914
|
] })
|
|
1509
1915
|
] }),
|
|
1510
|
-
/* @__PURE__ */ (0,
|
|
1511
|
-
/* @__PURE__ */ (0,
|
|
1512
|
-
/* @__PURE__ */ (0,
|
|
1513
|
-
/* @__PURE__ */ (0,
|
|
1514
|
-
|
|
1515
|
-
|
|
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 })
|
|
1922
|
+
] }),
|
|
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 })
|
|
1926
|
+
] })
|
|
1927
|
+
] }),
|
|
1928
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "ss-w-fandash-teamform-rows", children: teamFormRows(data) })
|
|
1516
1929
|
] }),
|
|
1517
|
-
h2h || data.fact ? /* @__PURE__ */ (0,
|
|
1518
|
-
h2h ? /* @__PURE__ */ (0,
|
|
1519
|
-
/* @__PURE__ */ (0,
|
|
1520
|
-
/* @__PURE__ */ (0,
|
|
1521
|
-
/* @__PURE__ */ (0,
|
|
1522
|
-
/* @__PURE__ */ (0,
|
|
1523
|
-
/* @__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 })
|
|
1524
1937
|
] }),
|
|
1525
|
-
/* @__PURE__ */ (0,
|
|
1526
|
-
/* @__PURE__ */ (0,
|
|
1527
|
-
/* @__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 })
|
|
1528
1941
|
] }),
|
|
1529
|
-
/* @__PURE__ */ (0,
|
|
1530
|
-
/* @__PURE__ */ (0,
|
|
1531
|
-
/* @__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 })
|
|
1532
1945
|
] })
|
|
1533
1946
|
] })
|
|
1534
1947
|
] }) : null,
|
|
1535
|
-
data.fact ? /* @__PURE__ */ (0,
|
|
1948
|
+
data.fact ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "ss-w-fandash-fact", children: data.fact }) : null
|
|
1536
1949
|
] }) : null
|
|
1537
1950
|
] });
|
|
1538
1951
|
}
|
|
1539
1952
|
|
|
1540
1953
|
// src/components/dashboard/CountdownCard.tsx
|
|
1541
|
-
var
|
|
1542
|
-
var
|
|
1954
|
+
var import_react11 = require("react");
|
|
1955
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1543
1956
|
var DAY_MS = 864e5;
|
|
1544
1957
|
function remainingSegments(kickoffUnix, nowMs, withSeconds) {
|
|
1545
1958
|
const totalSeconds = Math.floor((kickoffUnix * 1e3 - nowMs) / 1e3);
|
|
@@ -1557,72 +1970,72 @@ function remainingSegments(kickoffUnix, nowMs, withSeconds) {
|
|
|
1557
1970
|
function CountdownCard({ card }) {
|
|
1558
1971
|
const { data } = card;
|
|
1559
1972
|
const unitLabel = { d: data.daysUnit, h: data.hoursUnit, m: data.minutesUnit, s: data.secondsUnit };
|
|
1560
|
-
const [nowMs, setNowMs] = (0,
|
|
1561
|
-
const [reduced] = (0,
|
|
1973
|
+
const [nowMs, setNowMs] = (0, import_react11.useState)(() => Date.now());
|
|
1974
|
+
const [reduced] = (0, import_react11.useState)(
|
|
1562
1975
|
() => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
|
|
1563
1976
|
);
|
|
1564
1977
|
const withinDay = data.kickoffUnix * 1e3 - nowMs < DAY_MS;
|
|
1565
|
-
(0,
|
|
1978
|
+
(0, import_react11.useEffect)(() => {
|
|
1566
1979
|
if (reduced) return;
|
|
1567
1980
|
const id = window.setInterval(() => setNowMs(Date.now()), withinDay ? 1e3 : 6e4);
|
|
1568
1981
|
return () => window.clearInterval(id);
|
|
1569
1982
|
}, [reduced, withinDay]);
|
|
1570
1983
|
const segments = remainingSegments(data.kickoffUnix, nowMs, withinDay && !reduced);
|
|
1571
|
-
return /* @__PURE__ */ (0,
|
|
1572
|
-
/* @__PURE__ */ (0,
|
|
1573
|
-
segments ? /* @__PURE__ */ (0,
|
|
1574
|
-
i > 0 ? /* @__PURE__ */ (0,
|
|
1575
|
-
/* @__PURE__ */ (0,
|
|
1576
|
-
/* @__PURE__ */ (0,
|
|
1577
|
-
/* @__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] })
|
|
1578
1991
|
] })
|
|
1579
1992
|
] }, s.unit)) }) : null
|
|
1580
1993
|
] }) });
|
|
1581
1994
|
}
|
|
1582
1995
|
|
|
1583
1996
|
// src/components/dashboard/InjuriesCard.tsx
|
|
1584
|
-
var
|
|
1585
|
-
var
|
|
1997
|
+
var import_react12 = require("react");
|
|
1998
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1586
1999
|
var SHOWN = 3;
|
|
1587
2000
|
function ColHead({ name, crestUrl }) {
|
|
1588
|
-
return /* @__PURE__ */ (0,
|
|
1589
|
-
/* @__PURE__ */ (0,
|
|
1590
|
-
/* @__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 })
|
|
1591
2004
|
] });
|
|
1592
2005
|
}
|
|
1593
2006
|
function InjuryList({ rows, emptyLabel, limit }) {
|
|
1594
|
-
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 });
|
|
1595
2008
|
const shown = limit === void 0 ? rows : rows.slice(0, limit);
|
|
1596
|
-
return /* @__PURE__ */ (0,
|
|
1597
|
-
/* @__PURE__ */ (0,
|
|
1598
|
-
/* @__PURE__ */ (0,
|
|
1599
|
-
/* @__PURE__ */ (0,
|
|
1600
|
-
r.injuryType ? /* @__PURE__ */ (0,
|
|
1601
|
-
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
|
|
1602
2015
|
] })
|
|
1603
2016
|
] }, `${r.playerName}-${i}`)) });
|
|
1604
2017
|
}
|
|
1605
2018
|
function InjuriesCard({ card, ui }) {
|
|
1606
2019
|
const { data } = card;
|
|
1607
|
-
const [expanded, setExpanded] = (0,
|
|
2020
|
+
const [expanded, setExpanded] = (0, import_react12.useState)(false);
|
|
1608
2021
|
const hidden = Math.max(0, data.ours.length - SHOWN) + Math.max(0, data.theirs.length - SHOWN);
|
|
1609
2022
|
const limit = expanded ? void 0 : SHOWN;
|
|
1610
2023
|
const showMore = ui?.showMore ?? ((n) => `Show ${n} more`);
|
|
1611
2024
|
const showLess = ui?.showLess ?? "Show less";
|
|
1612
|
-
return /* @__PURE__ */ (0,
|
|
1613
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1614
|
-
/* @__PURE__ */ (0,
|
|
1615
|
-
/* @__PURE__ */ (0,
|
|
1616
|
-
/* @__PURE__ */ (0,
|
|
1617
|
-
/* @__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 })
|
|
1618
2031
|
] }),
|
|
1619
|
-
/* @__PURE__ */ (0,
|
|
1620
|
-
/* @__PURE__ */ (0,
|
|
1621
|
-
/* @__PURE__ */ (0,
|
|
1622
|
-
/* @__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 })
|
|
1623
2036
|
] })
|
|
1624
2037
|
] }),
|
|
1625
|
-
hidden > 0 ? /* @__PURE__ */ (0,
|
|
2038
|
+
hidden > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1626
2039
|
"button",
|
|
1627
2040
|
{
|
|
1628
2041
|
type: "button",
|
|
@@ -1636,80 +2049,80 @@ function InjuriesCard({ card, ui }) {
|
|
|
1636
2049
|
}
|
|
1637
2050
|
|
|
1638
2051
|
// src/components/dashboard/ReasonToBetCard.tsx
|
|
1639
|
-
var
|
|
2052
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1640
2053
|
function ReasonToBetCard({ card }) {
|
|
1641
|
-
return /* @__PURE__ */ (0,
|
|
1642
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1643
|
-
/* @__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}`)) })
|
|
1644
2057
|
] });
|
|
1645
2058
|
}
|
|
1646
2059
|
|
|
1647
2060
|
// src/components/dashboard/WhereToWatchCard.tsx
|
|
1648
|
-
var
|
|
2061
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1649
2062
|
function WhereToWatchCard({ card }) {
|
|
1650
|
-
return /* @__PURE__ */ (0,
|
|
1651
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1652
|
-
/* @__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}`)) })
|
|
1653
2066
|
] });
|
|
1654
2067
|
}
|
|
1655
2068
|
|
|
1656
2069
|
// src/components/dashboard/CongestedWeekCard.tsx
|
|
1657
|
-
var
|
|
2070
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1658
2071
|
function CongestedWeekCard({ card, onTap }) {
|
|
1659
|
-
return /* @__PURE__ */ (0,
|
|
1660
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1661
|
-
/* @__PURE__ */ (0,
|
|
1662
|
-
/* @__PURE__ */ (0,
|
|
1663
|
-
/* @__PURE__ */ (0,
|
|
1664
|
-
/* @__PURE__ */ (0,
|
|
1665
|
-
/* @__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 })
|
|
1666
2079
|
] }, `${entry.opponent}-${i}`)) }),
|
|
1667
|
-
/* @__PURE__ */ (0,
|
|
2080
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1668
2081
|
] });
|
|
1669
2082
|
}
|
|
1670
2083
|
|
|
1671
2084
|
// src/components/dashboard/TransfersCard.tsx
|
|
1672
|
-
var
|
|
2085
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1673
2086
|
function TransferList({ rows }) {
|
|
1674
|
-
if (rows.length === 0) return /* @__PURE__ */ (0,
|
|
1675
|
-
return /* @__PURE__ */ (0,
|
|
1676
|
-
/* @__PURE__ */ (0,
|
|
1677
|
-
/* @__PURE__ */ (0,
|
|
1678
|
-
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
|
|
1679
2092
|
] }, `${r.playerName}-${i}`)) });
|
|
1680
2093
|
}
|
|
1681
2094
|
function TransfersCard({ card }) {
|
|
1682
2095
|
const { data } = card;
|
|
1683
|
-
return /* @__PURE__ */ (0,
|
|
1684
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1685
|
-
/* @__PURE__ */ (0,
|
|
1686
|
-
/* @__PURE__ */ (0,
|
|
1687
|
-
/* @__PURE__ */ (0,
|
|
1688
|
-
/* @__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 })
|
|
1689
2102
|
] }),
|
|
1690
|
-
/* @__PURE__ */ (0,
|
|
1691
|
-
/* @__PURE__ */ (0,
|
|
1692
|
-
/* @__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 })
|
|
1693
2106
|
] })
|
|
1694
2107
|
] })
|
|
1695
2108
|
] });
|
|
1696
2109
|
}
|
|
1697
2110
|
|
|
1698
2111
|
// src/components/dashboard/LinksCard.tsx
|
|
1699
|
-
var
|
|
2112
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1700
2113
|
function LinksCard({ card }) {
|
|
1701
|
-
return /* @__PURE__ */ (0,
|
|
1702
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1703
|
-
/* @__PURE__ */ (0,
|
|
1704
|
-
/* @__PURE__ */ (0,
|
|
1705
|
-
/* @__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, {}) })
|
|
1706
2119
|
] }, `${link.url}-${i}`)) })
|
|
1707
2120
|
] });
|
|
1708
2121
|
}
|
|
1709
2122
|
|
|
1710
2123
|
// src/components/dashboard/PostMatchResultCard.tsx
|
|
1711
|
-
var
|
|
1712
|
-
var
|
|
2124
|
+
var import_react13 = require("react");
|
|
2125
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1713
2126
|
function initials3(name) {
|
|
1714
2127
|
return name.trim().slice(0, 3).toUpperCase();
|
|
1715
2128
|
}
|
|
@@ -1718,37 +2131,37 @@ function PostMatchCrest({
|
|
|
1718
2131
|
name,
|
|
1719
2132
|
side
|
|
1720
2133
|
}) {
|
|
1721
|
-
const [failed, setFailed] = (0,
|
|
2134
|
+
const [failed, setFailed] = (0, import_react13.useState)(false);
|
|
1722
2135
|
const cls = `ss-w-fandash-postmatch-crest ss-w-fandash-postmatch-crest--${side}`;
|
|
1723
2136
|
if (url && !failed) {
|
|
1724
|
-
return /* @__PURE__ */ (0,
|
|
2137
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
1725
2138
|
}
|
|
1726
|
-
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) });
|
|
1727
2140
|
}
|
|
1728
2141
|
function PostMatchResultCard({ card }) {
|
|
1729
2142
|
const { data } = card;
|
|
1730
2143
|
const homeWon = data.homeScore >= data.awayScore;
|
|
1731
2144
|
const awayWon = data.awayScore >= data.homeScore;
|
|
1732
|
-
return /* @__PURE__ */ (0,
|
|
1733
|
-
/* @__PURE__ */ (0,
|
|
1734
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1735
|
-
/* @__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 })
|
|
1736
2149
|
] }),
|
|
1737
|
-
/* @__PURE__ */ (0,
|
|
1738
|
-
/* @__PURE__ */ (0,
|
|
1739
|
-
/* @__PURE__ */ (0,
|
|
1740
|
-
/* @__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 })
|
|
1741
2154
|
] }),
|
|
1742
|
-
/* @__PURE__ */ (0,
|
|
1743
|
-
/* @__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)(
|
|
1744
2157
|
"span",
|
|
1745
2158
|
{
|
|
1746
2159
|
className: `ss-w-fandash-postmatch-score-value ss-w-fandash-postmatch-score-value--${homeWon ? "win" : "lose"}`,
|
|
1747
2160
|
children: data.homeScore
|
|
1748
2161
|
}
|
|
1749
2162
|
),
|
|
1750
|
-
/* @__PURE__ */ (0,
|
|
1751
|
-
/* @__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)(
|
|
1752
2165
|
"span",
|
|
1753
2166
|
{
|
|
1754
2167
|
className: `ss-w-fandash-postmatch-score-value ss-w-fandash-postmatch-score-value--${awayWon ? "win" : "lose"}`,
|
|
@@ -1756,12 +2169,12 @@ function PostMatchResultCard({ card }) {
|
|
|
1756
2169
|
}
|
|
1757
2170
|
)
|
|
1758
2171
|
] }),
|
|
1759
|
-
/* @__PURE__ */ (0,
|
|
1760
|
-
/* @__PURE__ */ (0,
|
|
1761
|
-
/* @__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 })
|
|
1762
2175
|
] })
|
|
1763
2176
|
] }),
|
|
1764
|
-
/* @__PURE__ */ (0,
|
|
2177
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "ss-w-fandash-postmatch-meta", children: [
|
|
1765
2178
|
data.kickoffLabel,
|
|
1766
2179
|
data.competition ? ` \xB7 ${data.competition}` : ""
|
|
1767
2180
|
] })
|
|
@@ -1769,20 +2182,20 @@ function PostMatchResultCard({ card }) {
|
|
|
1769
2182
|
}
|
|
1770
2183
|
|
|
1771
2184
|
// src/components/dashboard/PostMatchGoalsCard.tsx
|
|
1772
|
-
var
|
|
2185
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1773
2186
|
function PostMatchGoalsCard({ card, onTap }) {
|
|
1774
|
-
return /* @__PURE__ */ (0,
|
|
1775
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1776
|
-
/* @__PURE__ */ (0,
|
|
1777
|
-
/* @__PURE__ */ (0,
|
|
1778
|
-
/* @__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 })
|
|
1779
2192
|
] }, `${g.text}-${i}`)) }),
|
|
1780
|
-
/* @__PURE__ */ (0,
|
|
2193
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1781
2194
|
] });
|
|
1782
2195
|
}
|
|
1783
2196
|
|
|
1784
2197
|
// src/components/dashboard/PostMatchStatsCard.tsx
|
|
1785
|
-
var
|
|
2198
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1786
2199
|
function splitWidths(homeNum, awayNum) {
|
|
1787
2200
|
const total = homeNum + awayNum;
|
|
1788
2201
|
if (total <= 0) return { home: "50%", away: "50%" };
|
|
@@ -1791,42 +2204,42 @@ function splitWidths(homeNum, awayNum) {
|
|
|
1791
2204
|
}
|
|
1792
2205
|
function PostMatchStatsCard({ card, onTap }) {
|
|
1793
2206
|
const { data } = card;
|
|
1794
|
-
return /* @__PURE__ */ (0,
|
|
1795
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1796
|
-
/* @__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) => {
|
|
1797
2210
|
const leftValue = data.clubIsHome ? r.clubValue : r.oppValue;
|
|
1798
2211
|
const rightValue = data.clubIsHome ? r.oppValue : r.clubValue;
|
|
1799
2212
|
const homeNum = data.clubIsHome ? r.clubNum : r.oppNum;
|
|
1800
2213
|
const awayNum = data.clubIsHome ? r.oppNum : r.clubNum;
|
|
1801
2214
|
const { home, away } = splitWidths(homeNum, awayNum);
|
|
1802
|
-
return /* @__PURE__ */ (0,
|
|
1803
|
-
/* @__PURE__ */ (0,
|
|
1804
|
-
/* @__PURE__ */ (0,
|
|
1805
|
-
/* @__PURE__ */ (0,
|
|
1806
|
-
/* @__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 })
|
|
1807
2220
|
] }),
|
|
1808
|
-
/* @__PURE__ */ (0,
|
|
1809
|
-
/* @__PURE__ */ (0,
|
|
1810
|
-
/* @__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 } })
|
|
1811
2224
|
] })
|
|
1812
2225
|
] }, `${r.label}-${i}`);
|
|
1813
2226
|
}) }),
|
|
1814
|
-
data.rows.length > 0 ? /* @__PURE__ */ (0,
|
|
1815
|
-
/* @__PURE__ */ (0,
|
|
1816
|
-
/* @__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" }),
|
|
1817
2230
|
data.homeName
|
|
1818
2231
|
] }),
|
|
1819
|
-
/* @__PURE__ */ (0,
|
|
1820
|
-
/* @__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" }),
|
|
1821
2234
|
data.awayName
|
|
1822
2235
|
] })
|
|
1823
2236
|
] }) : null,
|
|
1824
|
-
/* @__PURE__ */ (0,
|
|
2237
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1825
2238
|
] });
|
|
1826
2239
|
}
|
|
1827
2240
|
|
|
1828
2241
|
// src/components/dashboard/PostMatchTopPerformerCard.tsx
|
|
1829
|
-
var
|
|
2242
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1830
2243
|
function initials4(playerName) {
|
|
1831
2244
|
const words = playerName.trim().split(/\s+/).filter(Boolean);
|
|
1832
2245
|
if (words.length === 0) return "?";
|
|
@@ -1836,73 +2249,73 @@ function initials4(playerName) {
|
|
|
1836
2249
|
}
|
|
1837
2250
|
function PostMatchTopPerformerCard({ card, onTap }) {
|
|
1838
2251
|
const { data } = card;
|
|
1839
|
-
return /* @__PURE__ */ (0,
|
|
1840
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1841
|
-
/* @__PURE__ */ (0,
|
|
1842
|
-
/* @__PURE__ */ (0,
|
|
1843
|
-
/* @__PURE__ */ (0,
|
|
1844
|
-
/* @__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 })
|
|
1845
2258
|
] }),
|
|
1846
|
-
/* @__PURE__ */ (0,
|
|
2259
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1847
2260
|
] });
|
|
1848
2261
|
}
|
|
1849
2262
|
|
|
1850
2263
|
// src/components/dashboard/PostMatchNextCard.tsx
|
|
1851
|
-
var
|
|
2264
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1852
2265
|
function PostMatchNextCard({ card }) {
|
|
1853
2266
|
const { data } = card;
|
|
1854
|
-
return /* @__PURE__ */ (0,
|
|
1855
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1856
|
-
/* @__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 }) })
|
|
1857
2270
|
] });
|
|
1858
2271
|
}
|
|
1859
2272
|
|
|
1860
2273
|
// src/components/dashboard/RestingNextCard.tsx
|
|
1861
|
-
var
|
|
2274
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
1862
2275
|
function RestingNextCard({ card, onTap }) {
|
|
1863
2276
|
const { data } = card;
|
|
1864
|
-
return /* @__PURE__ */ (0,
|
|
1865
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1866
|
-
/* @__PURE__ */ (0,
|
|
1867
|
-
/* @__PURE__ */ (0,
|
|
1868
|
-
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
|
|
1869
2282
|
] }),
|
|
1870
|
-
/* @__PURE__ */ (0,
|
|
2283
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1871
2284
|
] });
|
|
1872
2285
|
}
|
|
1873
2286
|
|
|
1874
2287
|
// src/components/dashboard/RestingStandingsCard.tsx
|
|
1875
|
-
var
|
|
2288
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
1876
2289
|
function RestingStandingsCard({ card, onTap }) {
|
|
1877
2290
|
const { data } = card;
|
|
1878
|
-
return /* @__PURE__ */ (0,
|
|
1879
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1880
|
-
/* @__PURE__ */ (0,
|
|
1881
|
-
/* @__PURE__ */ (0,
|
|
1882
|
-
/* @__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 })
|
|
1883
2296
|
] }),
|
|
1884
|
-
/* @__PURE__ */ (0,
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1885
2298
|
] });
|
|
1886
2299
|
}
|
|
1887
2300
|
|
|
1888
2301
|
// src/components/dashboard/RestingSeasonCard.tsx
|
|
1889
|
-
var
|
|
2302
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
1890
2303
|
function RestingSeasonCard({ card, onTap }) {
|
|
1891
2304
|
const { data } = card;
|
|
1892
|
-
return /* @__PURE__ */ (0,
|
|
1893
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1894
|
-
/* @__PURE__ */ (0,
|
|
1895
|
-
data.scorerLabel ? /* @__PURE__ */ (0,
|
|
1896
|
-
data.playerLabel ? /* @__PURE__ */ (0,
|
|
1897
|
-
/* @__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 })
|
|
1898
2311
|
] }),
|
|
1899
|
-
/* @__PURE__ */ (0,
|
|
2312
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "ss-w-fandash-card-cta", children: card.actionLabel })
|
|
1900
2313
|
] });
|
|
1901
2314
|
}
|
|
1902
2315
|
|
|
1903
2316
|
// src/components/dashboard/RestingFormCard.tsx
|
|
1904
|
-
var
|
|
1905
|
-
function
|
|
2317
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
2318
|
+
function resultClass(result) {
|
|
1906
2319
|
const upper = result.toUpperCase();
|
|
1907
2320
|
if (upper === "W") return "ss-w-fandash-form-pill--win";
|
|
1908
2321
|
if (upper === "L") return "ss-w-fandash-form-pill--loss";
|
|
@@ -1910,17 +2323,17 @@ function resultClass2(result) {
|
|
|
1910
2323
|
}
|
|
1911
2324
|
function RestingFormCard({ card }) {
|
|
1912
2325
|
const { data } = card;
|
|
1913
|
-
return /* @__PURE__ */ (0,
|
|
1914
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1915
|
-
/* @__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}`)) })
|
|
1916
2329
|
] });
|
|
1917
2330
|
}
|
|
1918
2331
|
|
|
1919
2332
|
// src/components/dashboard/LiveScoreCard.tsx
|
|
1920
|
-
var
|
|
2333
|
+
var import_react15 = require("react");
|
|
1921
2334
|
|
|
1922
2335
|
// src/useLiveClock.ts
|
|
1923
|
-
var
|
|
2336
|
+
var import_react14 = require("react");
|
|
1924
2337
|
var TICK_MS = 6e4;
|
|
1925
2338
|
var MAX_LIVE_TICK_MINUTES = 15;
|
|
1926
2339
|
function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
@@ -1929,10 +2342,10 @@ function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
|
|
|
1929
2342
|
return minute + Math.min(Math.max(0, elapsedMinutes), MAX_LIVE_TICK_MINUTES);
|
|
1930
2343
|
}
|
|
1931
2344
|
function useLiveClock(minute, clockRunning, receivedAtMs) {
|
|
1932
|
-
const [displayMinute, setDisplayMinute] = (0,
|
|
2345
|
+
const [displayMinute, setDisplayMinute] = (0, import_react14.useState)(
|
|
1933
2346
|
() => computeDisplayMinute(minute, clockRunning, receivedAtMs)
|
|
1934
2347
|
);
|
|
1935
|
-
(0,
|
|
2348
|
+
(0, import_react14.useEffect)(() => {
|
|
1936
2349
|
setDisplayMinute(computeDisplayMinute(minute, clockRunning, receivedAtMs));
|
|
1937
2350
|
if (!clockRunning) return;
|
|
1938
2351
|
const id = window.setInterval(() => {
|
|
@@ -1944,17 +2357,17 @@ function useLiveClock(minute, clockRunning, receivedAtMs) {
|
|
|
1944
2357
|
}
|
|
1945
2358
|
|
|
1946
2359
|
// src/components/dashboard/LiveScoreCard.tsx
|
|
1947
|
-
var
|
|
2360
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
1948
2361
|
function initials5(name) {
|
|
1949
2362
|
return name.trim().slice(0, 3).toUpperCase();
|
|
1950
2363
|
}
|
|
1951
2364
|
function LiveCrest({ url, name, side }) {
|
|
1952
|
-
const [failed, setFailed] = (0,
|
|
2365
|
+
const [failed, setFailed] = (0, import_react15.useState)(false);
|
|
1953
2366
|
const cls = `ss-w-fandash-live-crest ss-w-fandash-live-crest--${side}`;
|
|
1954
2367
|
if (url && !failed) {
|
|
1955
|
-
return /* @__PURE__ */ (0,
|
|
2368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
|
|
1956
2369
|
}
|
|
1957
|
-
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) });
|
|
1958
2371
|
}
|
|
1959
2372
|
function scorersLine(goalEvents) {
|
|
1960
2373
|
if (!goalEvents || goalEvents.length === 0) return null;
|
|
@@ -1968,72 +2381,72 @@ function LiveScoreCard({
|
|
|
1968
2381
|
}) {
|
|
1969
2382
|
const { data } = card;
|
|
1970
2383
|
const seedKey = `${data.minute}:${data.homeScore}:${data.awayScore}`;
|
|
1971
|
-
const seedRef = (0,
|
|
2384
|
+
const seedRef = (0, import_react15.useRef)(null);
|
|
1972
2385
|
if (!seedRef.current || seedRef.current.key !== seedKey) {
|
|
1973
2386
|
seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
|
|
1974
2387
|
}
|
|
1975
2388
|
const displayMinute = useLiveClock(data.minute, data.clockRunning, seedRef.current.receivedAtMs);
|
|
1976
2389
|
const minuteSuffix = data.minuteLabel.replace(/^\d+/, "");
|
|
1977
2390
|
const scorers = scorersLine(goalEvents);
|
|
1978
|
-
return /* @__PURE__ */ (0,
|
|
1979
|
-
card.title ? /* @__PURE__ */ (0,
|
|
1980
|
-
/* @__PURE__ */ (0,
|
|
1981
|
-
/* @__PURE__ */ (0,
|
|
1982
|
-
/* @__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" }),
|
|
1983
2396
|
data.statusLabel
|
|
1984
2397
|
] }),
|
|
1985
|
-
/* @__PURE__ */ (0,
|
|
1986
|
-
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
|
|
1987
2400
|
] }),
|
|
1988
|
-
/* @__PURE__ */ (0,
|
|
1989
|
-
/* @__PURE__ */ (0,
|
|
1990
|
-
/* @__PURE__ */ (0,
|
|
1991
|
-
/* @__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 })
|
|
1992
2405
|
] }),
|
|
1993
|
-
/* @__PURE__ */ (0,
|
|
1994
|
-
/* @__PURE__ */ (0,
|
|
1995
|
-
/* @__PURE__ */ (0,
|
|
1996
|
-
/* @__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 })
|
|
1997
2410
|
] }),
|
|
1998
|
-
/* @__PURE__ */ (0,
|
|
1999
|
-
/* @__PURE__ */ (0,
|
|
2000
|
-
/* @__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 })
|
|
2001
2414
|
] })
|
|
2002
2415
|
] }),
|
|
2003
|
-
scorers ? /* @__PURE__ */ (0,
|
|
2004
|
-
/* @__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" }),
|
|
2005
2418
|
scorers
|
|
2006
2419
|
] }) : null
|
|
2007
2420
|
] });
|
|
2008
2421
|
}
|
|
2009
2422
|
|
|
2010
2423
|
// src/components/dashboard/LiveTimelineCard.tsx
|
|
2011
|
-
var
|
|
2012
|
-
var
|
|
2424
|
+
var import_react16 = require("react");
|
|
2425
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
2013
2426
|
var SHOWN2 = 3;
|
|
2014
2427
|
function EventIcon({ type }) {
|
|
2015
2428
|
if (type === "goal") {
|
|
2016
|
-
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" }) });
|
|
2017
2430
|
}
|
|
2018
2431
|
if (type === "yellow" || type === "red") {
|
|
2019
|
-
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}` }) });
|
|
2020
2433
|
}
|
|
2021
2434
|
if (type === "sub") {
|
|
2022
|
-
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" }) });
|
|
2023
2436
|
}
|
|
2024
|
-
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" }) });
|
|
2025
2438
|
}
|
|
2026
2439
|
function EventLabel({ e }) {
|
|
2027
2440
|
if (e.type === "sub") {
|
|
2028
|
-
return /* @__PURE__ */ (0,
|
|
2441
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "ss-w-fandash-live-tl-who", children: [
|
|
2029
2442
|
e.player ?? e.text,
|
|
2030
|
-
e.playerOff ? /* @__PURE__ */ (0,
|
|
2443
|
+
e.playerOff ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "ss-w-fandash-live-tl-off", children: [
|
|
2031
2444
|
" for ",
|
|
2032
2445
|
e.playerOff
|
|
2033
2446
|
] }) : null
|
|
2034
2447
|
] });
|
|
2035
2448
|
}
|
|
2036
|
-
return /* @__PURE__ */ (0,
|
|
2449
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-live-tl-who", children: e.player ?? e.text });
|
|
2037
2450
|
}
|
|
2038
2451
|
function EventRow({ e }) {
|
|
2039
2452
|
const cls = [
|
|
@@ -2041,16 +2454,16 @@ function EventRow({ e }) {
|
|
|
2041
2454
|
e.side === "home" ? "ss-w-fandash-live-tl-ev--home" : "ss-w-fandash-live-tl-ev--away",
|
|
2042
2455
|
e.type === "goal" ? "ss-w-fandash-live-tl-ev--goal" : ""
|
|
2043
2456
|
].filter(Boolean).join(" ");
|
|
2044
|
-
return /* @__PURE__ */ (0,
|
|
2045
|
-
/* @__PURE__ */ (0,
|
|
2046
|
-
/* @__PURE__ */ (0,
|
|
2047
|
-
/* @__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 })
|
|
2048
2461
|
] }),
|
|
2049
|
-
/* @__PURE__ */ (0,
|
|
2462
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "ss-w-fandash-live-tl-badge", children: e.minuteLabel })
|
|
2050
2463
|
] });
|
|
2051
2464
|
}
|
|
2052
2465
|
function LiveTimelineCard({ card, ui }) {
|
|
2053
|
-
const [expanded, setExpanded] = (0,
|
|
2466
|
+
const [expanded, setExpanded] = (0, import_react16.useState)(false);
|
|
2054
2467
|
const events = card.data.events;
|
|
2055
2468
|
if (!events || events.length === 0) return null;
|
|
2056
2469
|
const sorted = [...events].sort((a, b) => b.minute - a.minute);
|
|
@@ -2058,10 +2471,10 @@ function LiveTimelineCard({ card, ui }) {
|
|
|
2058
2471
|
const shown = expanded ? sorted : sorted.slice(0, SHOWN2);
|
|
2059
2472
|
const showMore = ui?.showMore ?? ((n) => `Show ${n} more`);
|
|
2060
2473
|
const showLess = ui?.showLess ?? "Show less";
|
|
2061
|
-
return /* @__PURE__ */ (0,
|
|
2062
|
-
card.title ? /* @__PURE__ */ (0,
|
|
2063
|
-
/* @__PURE__ */ (0,
|
|
2064
|
-
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)(
|
|
2065
2478
|
"button",
|
|
2066
2479
|
{
|
|
2067
2480
|
type: "button",
|
|
@@ -2075,8 +2488,8 @@ function LiveTimelineCard({ card, ui }) {
|
|
|
2075
2488
|
}
|
|
2076
2489
|
|
|
2077
2490
|
// src/components/dashboard/MomentumWave.tsx
|
|
2078
|
-
var
|
|
2079
|
-
var
|
|
2491
|
+
var import_react17 = require("react");
|
|
2492
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
2080
2493
|
var WIDTH = 270;
|
|
2081
2494
|
var HEIGHT = 56;
|
|
2082
2495
|
var BASELINE = HEIGHT / 2;
|
|
@@ -2098,14 +2511,14 @@ function MomentumWave({
|
|
|
2098
2511
|
}) {
|
|
2099
2512
|
if (points.length === 0) return null;
|
|
2100
2513
|
const { area, line, lastX, lastY } = buildPaths(points);
|
|
2101
|
-
const clipId = (0,
|
|
2514
|
+
const clipId = (0, import_react17.useId)();
|
|
2102
2515
|
const topClipId = `${clipId}-top`;
|
|
2103
2516
|
const bottomClipId = `${clipId}-bottom`;
|
|
2104
2517
|
const topClass = clubIsHome ? "ss-w-fandash-live-mom-home" : "ss-w-fandash-live-mom-away";
|
|
2105
2518
|
const bottomClass = clubIsHome ? "ss-w-fandash-live-mom-away" : "ss-w-fandash-live-mom-home";
|
|
2106
|
-
return /* @__PURE__ */ (0,
|
|
2107
|
-
caption ? /* @__PURE__ */ (0,
|
|
2108
|
-
/* @__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)(
|
|
2109
2522
|
"svg",
|
|
2110
2523
|
{
|
|
2111
2524
|
className: "ss-w-fandash-live-mom-svg",
|
|
@@ -2114,15 +2527,15 @@ function MomentumWave({
|
|
|
2114
2527
|
role: "img",
|
|
2115
2528
|
"aria-label": caption ?? "Momentum",
|
|
2116
2529
|
children: [
|
|
2117
|
-
/* @__PURE__ */ (0,
|
|
2118
|
-
/* @__PURE__ */ (0,
|
|
2119
|
-
/* @__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 }) })
|
|
2120
2533
|
] }),
|
|
2121
|
-
/* @__PURE__ */ (0,
|
|
2122
|
-
/* @__PURE__ */ (0,
|
|
2123
|
-
/* @__PURE__ */ (0,
|
|
2124
|
-
/* @__PURE__ */ (0,
|
|
2125
|
-
/* @__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" })
|
|
2126
2539
|
]
|
|
2127
2540
|
}
|
|
2128
2541
|
)
|
|
@@ -2130,7 +2543,7 @@ function MomentumWave({
|
|
|
2130
2543
|
}
|
|
2131
2544
|
|
|
2132
2545
|
// src/components/dashboard/LiveStatsCard.tsx
|
|
2133
|
-
var
|
|
2546
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
2134
2547
|
function splitWidths2(homeNum, awayNum) {
|
|
2135
2548
|
const total = homeNum + awayNum;
|
|
2136
2549
|
if (total <= 0) return { home: "50%", away: "50%" };
|
|
@@ -2139,34 +2552,34 @@ function splitWidths2(homeNum, awayNum) {
|
|
|
2139
2552
|
}
|
|
2140
2553
|
function LiveStatsCard({ card }) {
|
|
2141
2554
|
const { data } = card;
|
|
2142
|
-
return /* @__PURE__ */ (0,
|
|
2143
|
-
card.title ? /* @__PURE__ */ (0,
|
|
2144
|
-
/* @__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) => {
|
|
2145
2558
|
const homeValue = data.clubIsHome ? r.clubValue : r.oppValue;
|
|
2146
2559
|
const awayValue = data.clubIsHome ? r.oppValue : r.clubValue;
|
|
2147
2560
|
const homeNum = data.clubIsHome ? r.clubNum : r.oppNum;
|
|
2148
2561
|
const awayNum = data.clubIsHome ? r.oppNum : r.clubNum;
|
|
2149
2562
|
const { home, away } = splitWidths2(homeNum, awayNum);
|
|
2150
|
-
return /* @__PURE__ */ (0,
|
|
2151
|
-
/* @__PURE__ */ (0,
|
|
2152
|
-
/* @__PURE__ */ (0,
|
|
2153
|
-
/* @__PURE__ */ (0,
|
|
2154
|
-
/* @__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 })
|
|
2155
2568
|
] }),
|
|
2156
|
-
/* @__PURE__ */ (0,
|
|
2157
|
-
/* @__PURE__ */ (0,
|
|
2158
|
-
/* @__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 } })
|
|
2159
2572
|
] })
|
|
2160
2573
|
] }, `${r.label}-${i}`);
|
|
2161
2574
|
}) }),
|
|
2162
|
-
data.momentum.length > 0 ? /* @__PURE__ */ (0,
|
|
2163
|
-
data.rows.length > 0 ? /* @__PURE__ */ (0,
|
|
2164
|
-
/* @__PURE__ */ (0,
|
|
2165
|
-
/* @__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" }),
|
|
2166
2579
|
data.homeName
|
|
2167
2580
|
] }),
|
|
2168
|
-
/* @__PURE__ */ (0,
|
|
2169
|
-
/* @__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" }),
|
|
2170
2583
|
data.awayName
|
|
2171
2584
|
] })
|
|
2172
2585
|
] }) : null
|
|
@@ -2174,7 +2587,7 @@ function LiveStatsCard({ card }) {
|
|
|
2174
2587
|
}
|
|
2175
2588
|
|
|
2176
2589
|
// src/components/dashboard/ClubFanDashboard.tsx
|
|
2177
|
-
var
|
|
2590
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
2178
2591
|
function ClubFanDashboard({ dashboard, onTap, ui }) {
|
|
2179
2592
|
const orderedCards = [
|
|
2180
2593
|
...dashboard.cards.filter((c) => c.cardType === "countdown"),
|
|
@@ -2184,84 +2597,84 @@ function ClubFanDashboard({ dashboard, onTap, ui }) {
|
|
|
2184
2597
|
(c) => c.cardType === "liveTimeline"
|
|
2185
2598
|
);
|
|
2186
2599
|
const goalEvents = timelineCard?.data.events.filter((e) => e.type === "goal");
|
|
2187
|
-
return /* @__PURE__ */ (0,
|
|
2188
|
-
dashboard.greeting ? /* @__PURE__ */ (0,
|
|
2189
|
-
/* @__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}`)) })
|
|
2190
2603
|
] });
|
|
2191
2604
|
}
|
|
2192
2605
|
function FanDashboardCard({ card, onTap, ui, goalEvents }) {
|
|
2193
2606
|
switch (card.cardType) {
|
|
2194
2607
|
case "fixture":
|
|
2195
|
-
return /* @__PURE__ */ (0,
|
|
2608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(FixtureCard, { card });
|
|
2196
2609
|
case "countdown":
|
|
2197
|
-
return /* @__PURE__ */ (0,
|
|
2610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(CountdownCard, { card });
|
|
2198
2611
|
case "injuries":
|
|
2199
|
-
return /* @__PURE__ */ (0,
|
|
2612
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(InjuriesCard, { card, ui });
|
|
2200
2613
|
case "reasonToBet":
|
|
2201
|
-
return /* @__PURE__ */ (0,
|
|
2614
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ReasonToBetCard, { card });
|
|
2202
2615
|
case "whereToWatch":
|
|
2203
|
-
return /* @__PURE__ */ (0,
|
|
2616
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(WhereToWatchCard, { card });
|
|
2204
2617
|
case "congestedWeek":
|
|
2205
|
-
return /* @__PURE__ */ (0,
|
|
2618
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(CongestedWeekCard, { card, onTap });
|
|
2206
2619
|
case "transfers":
|
|
2207
|
-
return /* @__PURE__ */ (0,
|
|
2620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(TransfersCard, { card });
|
|
2208
2621
|
case "links":
|
|
2209
|
-
return /* @__PURE__ */ (0,
|
|
2622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LinksCard, { card });
|
|
2210
2623
|
case "postMatchResult":
|
|
2211
|
-
return /* @__PURE__ */ (0,
|
|
2624
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PostMatchResultCard, { card });
|
|
2212
2625
|
case "postMatchGoals":
|
|
2213
|
-
return /* @__PURE__ */ (0,
|
|
2626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PostMatchGoalsCard, { card, onTap });
|
|
2214
2627
|
case "postMatchStats":
|
|
2215
|
-
return /* @__PURE__ */ (0,
|
|
2628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PostMatchStatsCard, { card, onTap });
|
|
2216
2629
|
case "postMatchTopPerformer":
|
|
2217
|
-
return /* @__PURE__ */ (0,
|
|
2630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PostMatchTopPerformerCard, { card, onTap });
|
|
2218
2631
|
case "postMatchNext":
|
|
2219
|
-
return /* @__PURE__ */ (0,
|
|
2632
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PostMatchNextCard, { card });
|
|
2220
2633
|
case "restingNext":
|
|
2221
|
-
return /* @__PURE__ */ (0,
|
|
2634
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RestingNextCard, { card, onTap });
|
|
2222
2635
|
case "restingStandings":
|
|
2223
|
-
return /* @__PURE__ */ (0,
|
|
2636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RestingStandingsCard, { card, onTap });
|
|
2224
2637
|
case "restingSeason":
|
|
2225
|
-
return /* @__PURE__ */ (0,
|
|
2638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RestingSeasonCard, { card, onTap });
|
|
2226
2639
|
case "restingForm":
|
|
2227
|
-
return /* @__PURE__ */ (0,
|
|
2640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RestingFormCard, { card });
|
|
2228
2641
|
case "liveScore":
|
|
2229
|
-
return /* @__PURE__ */ (0,
|
|
2642
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LiveScoreCard, { card, goalEvents });
|
|
2230
2643
|
case "liveTimeline":
|
|
2231
|
-
return /* @__PURE__ */ (0,
|
|
2644
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LiveTimelineCard, { card, ui });
|
|
2232
2645
|
case "liveStats":
|
|
2233
|
-
return /* @__PURE__ */ (0,
|
|
2646
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LiveStatsCard, { card });
|
|
2234
2647
|
default:
|
|
2235
2648
|
return null;
|
|
2236
2649
|
}
|
|
2237
2650
|
}
|
|
2238
2651
|
|
|
2239
2652
|
// src/components/ChatMessage.tsx
|
|
2240
|
-
var
|
|
2241
|
-
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 }) {
|
|
2242
2655
|
if (message.role === "user") {
|
|
2243
|
-
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 }) });
|
|
2244
2657
|
}
|
|
2245
2658
|
const onFanDashboardTap = (card) => {
|
|
2246
2659
|
onAct({ message: card.actionLabel, actionRef: card.actionRef, label: card.actionLabel || card.title || "" });
|
|
2247
2660
|
};
|
|
2248
|
-
return /* @__PURE__ */ (0,
|
|
2249
|
-
message.text && !message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0,
|
|
2250
|
-
message.greetingDashboard && !message.clubFanDashboard ? /* @__PURE__ */ (0,
|
|
2251
|
-
message.clubFanDashboard ? /* @__PURE__ */ (0,
|
|
2252
|
-
/* @__PURE__ */ (0,
|
|
2253
|
-
/* @__PURE__ */ (0,
|
|
2254
|
-
/* @__PURE__ */ (0,
|
|
2255
|
-
/* @__PURE__ */ (0,
|
|
2256
|
-
/* @__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 })
|
|
2257
2670
|
] });
|
|
2258
2671
|
}
|
|
2259
2672
|
|
|
2260
2673
|
// src/components/IntentChips.tsx
|
|
2261
|
-
var
|
|
2674
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
2262
2675
|
function IntentChips({ chips, onPick }) {
|
|
2263
2676
|
if (chips.length === 0) return null;
|
|
2264
|
-
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}`)) });
|
|
2265
2678
|
}
|
|
2266
2679
|
|
|
2267
2680
|
// src/scroll.ts
|
|
@@ -2271,20 +2684,20 @@ function isPinnedToBottom(el, threshold = PIN_THRESHOLD) {
|
|
|
2271
2684
|
}
|
|
2272
2685
|
|
|
2273
2686
|
// src/components/MessageList.tsx
|
|
2274
|
-
var
|
|
2687
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
2275
2688
|
function turnAnchor(messages) {
|
|
2276
2689
|
const last = messages[messages.length - 1];
|
|
2277
2690
|
if (!last || last.role !== "assistant") return null;
|
|
2278
2691
|
const prev = messages[messages.length - 2];
|
|
2279
2692
|
return { turnId: last.id, anchorId: prev && prev.role === "user" ? prev.id : last.id };
|
|
2280
2693
|
}
|
|
2281
|
-
function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
2694
|
+
function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
2282
2695
|
const { state, send } = controller;
|
|
2283
|
-
const listRef = (0,
|
|
2284
|
-
const endRef = (0,
|
|
2285
|
-
const pinnedRef = (0,
|
|
2286
|
-
const anchoredTurnRef = (0,
|
|
2287
|
-
(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)(() => {
|
|
2288
2701
|
const anchor = turnAnchor(state.messages);
|
|
2289
2702
|
const list = listRef.current;
|
|
2290
2703
|
if (anchor && anchor.turnId !== anchoredTurnRef.current) {
|
|
@@ -2299,7 +2712,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
2299
2712
|
}, [state.messages, state.status, state.isStreaming]);
|
|
2300
2713
|
const hasUserMessage = state.messages.some((m) => m.role === "user");
|
|
2301
2714
|
const hasDashboard = state.messages.some((m) => m.role === "assistant" && (m.greetingDashboard || m.clubFanDashboard));
|
|
2302
|
-
return /* @__PURE__ */ (0,
|
|
2715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
2303
2716
|
"div",
|
|
2304
2717
|
{
|
|
2305
2718
|
className: "ss-w-list",
|
|
@@ -2309,7 +2722,7 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
2309
2722
|
if (listRef.current) pinnedRef.current = isPinnedToBottom(listRef.current);
|
|
2310
2723
|
},
|
|
2311
2724
|
children: [
|
|
2312
|
-
state.messages.map((m) => /* @__PURE__ */ (0,
|
|
2725
|
+
state.messages.map((m) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2313
2726
|
ChatMessage,
|
|
2314
2727
|
{
|
|
2315
2728
|
message: m,
|
|
@@ -2320,29 +2733,30 @@ function MessageList({ controller, ui, slip, onDashboardTap }) {
|
|
|
2320
2733
|
if (m.role === "assistant" && m.greetingDashboard) onDashboardTap?.(tile, index, m.greetingDashboard.layout);
|
|
2321
2734
|
},
|
|
2322
2735
|
ui,
|
|
2323
|
-
slip
|
|
2736
|
+
slip,
|
|
2737
|
+
monitor
|
|
2324
2738
|
},
|
|
2325
2739
|
m.id
|
|
2326
2740
|
)),
|
|
2327
|
-
state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0,
|
|
2741
|
+
state.isStreaming && state.actionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ActionButtons, { actions: [], loading: true, onAct: () => {
|
|
2328
2742
|
} }) : null,
|
|
2329
|
-
state.status ? /* @__PURE__ */ (0,
|
|
2330
|
-
state.error ? /* @__PURE__ */ (0,
|
|
2331
|
-
/* @__PURE__ */ (0,
|
|
2332
|
-
/* @__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 })
|
|
2333
2747
|
] }) : null,
|
|
2334
|
-
!hasUserMessage && !hasDashboard ? /* @__PURE__ */ (0,
|
|
2335
|
-
/* @__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" })
|
|
2336
2750
|
]
|
|
2337
2751
|
}
|
|
2338
2752
|
);
|
|
2339
2753
|
}
|
|
2340
2754
|
|
|
2341
2755
|
// src/components/ChatInput.tsx
|
|
2342
|
-
var
|
|
2343
|
-
var
|
|
2756
|
+
var import_react19 = require("react");
|
|
2757
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
2344
2758
|
function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
|
|
2345
|
-
const [value, setValue] = (0,
|
|
2759
|
+
const [value, setValue] = (0, import_react19.useState)("");
|
|
2346
2760
|
const submit = () => {
|
|
2347
2761
|
const t = value.trim();
|
|
2348
2762
|
if (!t) return;
|
|
@@ -2355,18 +2769,228 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
|
|
|
2355
2769
|
submit();
|
|
2356
2770
|
}
|
|
2357
2771
|
};
|
|
2358
|
-
return /* @__PURE__ */ (0,
|
|
2359
|
-
/* @__PURE__ */ (0,
|
|
2360
|
-
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, {}) })
|
|
2361
2775
|
] });
|
|
2362
2776
|
}
|
|
2363
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 })
|
|
2914
|
+
] });
|
|
2915
|
+
}
|
|
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
|
+
|
|
2364
2988
|
// src/components/ChatPanel.tsx
|
|
2365
|
-
var
|
|
2989
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
2366
2990
|
var FULLSCREEN_QUERY = "(max-width: 639px)";
|
|
2367
2991
|
function useIsModal() {
|
|
2368
|
-
const [modal, setModal] = (0,
|
|
2369
|
-
(0,
|
|
2992
|
+
const [modal, setModal] = (0, import_react20.useState)(false);
|
|
2993
|
+
(0, import_react20.useEffect)(() => {
|
|
2370
2994
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
2371
2995
|
const mql = window.matchMedia(FULLSCREEN_QUERY);
|
|
2372
2996
|
const sync = () => setModal(mql.matches);
|
|
@@ -2376,20 +3000,44 @@ function useIsModal() {
|
|
|
2376
3000
|
}, []);
|
|
2377
3001
|
return modal;
|
|
2378
3002
|
}
|
|
2379
|
-
function ChatPanel({ controller, ui, slip, onDashboardTap }) {
|
|
3003
|
+
function ChatPanel({ controller, ui, slip, onDashboardTap, monitor }) {
|
|
2380
3004
|
const { state, close, stop, send } = controller;
|
|
2381
3005
|
const isModal = useIsModal();
|
|
2382
|
-
(0,
|
|
3006
|
+
(0, import_react20.useEffect)(() => {
|
|
2383
3007
|
const onKey = (e) => {
|
|
2384
3008
|
if (e.key === "Escape") close();
|
|
2385
3009
|
};
|
|
2386
3010
|
window.addEventListener("keydown", onKey);
|
|
2387
3011
|
return () => window.removeEventListener("keydown", onKey);
|
|
2388
3012
|
}, [close]);
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
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 })
|
|
2393
3041
|
] });
|
|
2394
3042
|
}
|
|
2395
3043
|
|
|
@@ -2457,7 +3105,10 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
2457
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; }
|
|
2458
3106
|
|
|
2459
3107
|
/* messages */
|
|
2460
|
-
.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; }
|
|
2461
3112
|
/* Transient bottom spacer: reserves a viewport of room below a new turn so its
|
|
2462
3113
|
top can be scrolled into view while the reply is still streaming in. Height is
|
|
2463
3114
|
set imperatively and flex must not shrink it away. */
|
|
@@ -2573,8 +3224,6 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
2573
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; }
|
|
2574
3225
|
.ss-w-bi-book { font-size: 9.5px; color: var(--ss-w-faint); }
|
|
2575
3226
|
.ss-w-bi-action-row .ss-w-slip { flex: none; }
|
|
2576
|
-
/* let the slip toast size to its own text and anchor to the card's right edge, not the button width */
|
|
2577
|
-
.ss-w-bi-action-row .ss-w-toast { left: auto; right: 0; width: max-content; max-width: 210px; white-space: normal; }
|
|
2578
3227
|
|
|
2579
3228
|
/* row 3: bar-chart glyph + reasoning prose + stats-expander chevron, in a subtle strip */
|
|
2580
3229
|
.ss-w-bi-reason { display: flex; align-items: flex-start; gap: 8px; background: var(--ss-w-bubble); border-radius: 10px; padding: 8px 10px; }
|
|
@@ -2681,10 +3330,21 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
2681
3330
|
.ss-w-slip { position: relative; display: flex; }
|
|
2682
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; }
|
|
2683
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); }
|
|
2684
|
-
|
|
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); }
|
|
2685
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)); }
|
|
2686
3338
|
.ss-w-toast-error { color: #c0392b; background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); }
|
|
2687
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
|
+
|
|
2688
3348
|
@media (prefers-reduced-motion: reduce) {
|
|
2689
3349
|
.ss-w-abtn-shimmer { animation: none; }
|
|
2690
3350
|
}
|
|
@@ -2801,13 +3461,25 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
2801
3461
|
/* extra breathing room between the tally row and the fact beyond the card's own gap */
|
|
2802
3462
|
.ss-w-fandash-h2h .ss-w-fandash-fact { margin-top: 4px; }
|
|
2803
3463
|
|
|
2804
|
-
/*
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
.ss-w-fandash-
|
|
2808
|
-
.ss-w-fandash-
|
|
2809
|
-
.ss-w-fandash-
|
|
2810
|
-
.ss-w-fandash-
|
|
3464
|
+
/* Team form: a two-column result-card grid, left = home team's last 5, right = away team's last 5,
|
|
3465
|
+
most-recent first. The head row carries each column's crest + name; the rows grid is filled
|
|
3466
|
+
home-cell/away-cell per index so the 2-col grid lays out pairs without extra JS bookkeeping. */
|
|
3467
|
+
.ss-w-fandash-teamform-head { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px; }
|
|
3468
|
+
.ss-w-fandash-teamform-head-team { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 11.5px; font-weight: 750; }
|
|
3469
|
+
.ss-w-fandash-teamform-head-team .ss-w-bi-crest { width: 18px; height: 18px; }
|
|
3470
|
+
.ss-w-fandash-teamform-head-team .ss-w-bi-crest-mono { font-size: 8px; }
|
|
3471
|
+
.ss-w-fandash-teamform-head-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
3472
|
+
.ss-w-fandash-teamform-rows { display: grid; grid-template-columns: 1fr 1fr; gap: 5px 6px; }
|
|
3473
|
+
.ss-w-fandash-teamform-slot { display: block; min-width: 0; }
|
|
3474
|
+
.ss-w-fandash-teamform-cell {
|
|
3475
|
+
display: flex; align-items: center; gap: 4px; border-radius: 7px; padding: 4px 5px; color: #fff;
|
|
3476
|
+
}
|
|
3477
|
+
.ss-w-fandash-teamform-cell--win { background: var(--ss-w-pos); }
|
|
3478
|
+
.ss-w-fandash-teamform-cell--loss { background: var(--ss-w-neg); }
|
|
3479
|
+
.ss-w-fandash-teamform-cell--draw { background: var(--ss-w-faint); }
|
|
3480
|
+
.ss-w-fandash-teamform-cell .ss-w-bi-crest { width: 16px; height: 16px; flex: none; background: rgba(255, 255, 255, .22); }
|
|
3481
|
+
.ss-w-fandash-teamform-cell .ss-w-bi-crest-mono { font-size: 7px; color: #fff; }
|
|
3482
|
+
.ss-w-fandash-teamform-score { flex: 1; text-align: center; font-size: 12.5px; font-weight: 750; font-variant-numeric: tabular-nums; }
|
|
2811
3483
|
.ss-w-fandash-injuries-more { margin-top: 10px; width: 100%; background: var(--ss-w-bubble); border: 1px solid var(--ss-w-line); border-radius: 9px; padding: 7px; font: inherit; font-size: 11.5px; font-weight: 700; color: var(--ss-w-accent); cursor: pointer; }
|
|
2812
3484
|
.ss-w-fandash-injuries-more:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: 2px; }
|
|
2813
3485
|
.ss-w-fandash-form { display: inline-flex; gap: 3px; flex: none; }
|
|
@@ -3041,10 +3713,68 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
|
|
|
3041
3713
|
.ss-w-fandash-live-legend-swatch { width: 10px; height: 10px; border-radius: 3px; flex: none; }
|
|
3042
3714
|
.ss-w-fandash-live-legend-swatch--home { background: var(--ss-w-home); }
|
|
3043
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); }
|
|
3044
3774
|
`;
|
|
3045
3775
|
|
|
3046
3776
|
// src/StatsWidget.tsx
|
|
3047
|
-
var
|
|
3777
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
3048
3778
|
function buildClient(props) {
|
|
3049
3779
|
try {
|
|
3050
3780
|
if ("client" in props && props.client) {
|
|
@@ -3069,35 +3799,50 @@ function injectStyles(root) {
|
|
|
3069
3799
|
function StatsWidget(props) {
|
|
3070
3800
|
const injectedClient = "client" in props ? props.client : void 0;
|
|
3071
3801
|
const cfg = props.config;
|
|
3072
|
-
const built = (0,
|
|
3073
|
-
const ui = (0,
|
|
3074
|
-
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);
|
|
3075
3805
|
const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0);
|
|
3076
|
-
const
|
|
3077
|
-
() => (
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
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
|
+
}
|
|
3084
3829
|
}
|
|
3085
|
-
}
|
|
3086
|
-
}
|
|
3087
|
-
[props.config?.onAddToSlip, controller.state.conversationId, built]
|
|
3830
|
+
};
|
|
3831
|
+
},
|
|
3832
|
+
[props.config?.onAddToSlip, controller.state.conversationId, built, monitor.markInSlip]
|
|
3088
3833
|
);
|
|
3089
|
-
const onDashboardTap = (0,
|
|
3834
|
+
const onDashboardTap = (0, import_react21.useMemo)(
|
|
3090
3835
|
() => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input)) : void 0,
|
|
3091
3836
|
[built]
|
|
3092
3837
|
);
|
|
3093
|
-
(0,
|
|
3838
|
+
(0, import_react21.useEffect)(() => {
|
|
3094
3839
|
if (!built || !ui.injectStyles) return;
|
|
3095
3840
|
const node = rootRef.current?.getRootNode();
|
|
3096
3841
|
if (node) injectStyles(node);
|
|
3097
3842
|
}, [built, ui.injectStyles]);
|
|
3098
3843
|
if (!built) return null;
|
|
3099
3844
|
const attrs = themeAttrs(ui);
|
|
3100
|
-
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)(
|
|
3101
3846
|
ChatFab,
|
|
3102
3847
|
{
|
|
3103
3848
|
label: ui.launcherLabel,
|