@sensiblestats/widget-react 0.43.1 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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 import_react24 = require("react");
39
+ var import_react26 = require("react");
40
40
  var import_widget_sdk5 = require("@sensiblestats/widget-sdk");
41
41
 
42
42
  // src/kickoff.ts
@@ -106,7 +106,7 @@ var STRINGS = {
106
106
  tomorrow: "Tomorrow",
107
107
  bettingKickoff: (kickoffUtc, now) => formatBettingKickoff(kickoffUtc, STRINGS.en, "en", now),
108
108
  tabChat: "Chat",
109
- tabMatches: "Matches",
109
+ tabFollowing: "Following",
110
110
  tabOdds: "Odds",
111
111
  pinLabel: "Track odds",
112
112
  unpinLabel: "Stop tracking odds",
@@ -125,7 +125,10 @@ var STRINGS = {
125
125
  momentumLabel: "Momentum",
126
126
  accordionValueLabel: "Value",
127
127
  accordionRetry: "Couldn't load odds \u2014 tap to retry",
128
- accordionSuspended: "Suspended"
128
+ accordionSuspended: "Suspended",
129
+ tabToday: "Today",
130
+ sectionLive: "Live",
131
+ staleStates: "Live scores can't be updated \u2014 showing the last known state."
129
132
  },
130
133
  tr: {
131
134
  launcherLabel: "SensibleStats ile sohbet et",
@@ -180,7 +183,7 @@ var STRINGS = {
180
183
  tomorrow: "Yar\u0131n",
181
184
  bettingKickoff: (kickoffUtc, now) => formatBettingKickoff(kickoffUtc, STRINGS.tr, "tr", now),
182
185
  tabChat: "Sohbet",
183
- tabMatches: "Ma\xE7lar",
186
+ tabFollowing: "Takip",
184
187
  tabOdds: "Oranlar",
185
188
  pinLabel: "Oran\u0131 takip et",
186
189
  unpinLabel: "Oran takibini b\u0131rak",
@@ -199,7 +202,10 @@ var STRINGS = {
199
202
  momentumLabel: "Momentum",
200
203
  accordionValueLabel: "De\u011Fer",
201
204
  accordionRetry: "Oranlar y\xFCklenemedi \u2014 yeniden dene",
202
- accordionSuspended: "Ask\u0131da"
205
+ accordionSuspended: "Ask\u0131da",
206
+ tabToday: "Bug\xFCn",
207
+ sectionLive: "Canl\u0131",
208
+ staleStates: "Canl\u0131 skorlar g\xFCncellenemiyor \u2014 son bilinen durum g\xF6steriliyor."
203
209
  }
204
210
  };
205
211
  function resolveLocaleStrings(locale) {
@@ -273,8 +279,11 @@ function normalizeUi(cfg) {
273
279
  tomorrow: strings.tomorrow,
274
280
  bettingKickoff: strings.bettingKickoff,
275
281
  tabChat: strings.tabChat,
276
- tabMatches: strings.tabMatches,
282
+ tabFollowing: strings.tabFollowing,
277
283
  tabOdds: strings.tabOdds,
284
+ tabToday: strings.tabToday,
285
+ sectionLive: strings.sectionLive,
286
+ staleStates: strings.staleStates,
278
287
  pinLabel: strings.pinLabel,
279
288
  unpinLabel: strings.unpinLabel,
280
289
  matchPinLabel: strings.matchPinLabel,
@@ -316,6 +325,18 @@ function isTerminal(result) {
316
325
  if (result.status === "price_changed") return result.accepted;
317
326
  return result.status === "added" || result.status === "duplicate";
318
327
  }
328
+ function slipOutcome(result) {
329
+ if (!result) return "added";
330
+ switch (result.status) {
331
+ case "added":
332
+ case "duplicate":
333
+ return result.status;
334
+ case "price_changed":
335
+ return result.accepted ? "added" : "price_changed";
336
+ case "rejected":
337
+ return result.reason;
338
+ }
339
+ }
319
340
  function resultToToast(result, shownOdds, ui) {
320
341
  if (!result) return { kind: "success", text: ui.slipAdded };
321
342
  switch (result.status) {
@@ -337,8 +358,28 @@ var import_widget_sdk = require("@sensiblestats/widget-sdk");
337
358
  function isSignalEntityType(value) {
338
359
  return Object.prototype.hasOwnProperty.call(import_widget_sdk.ENTITY_TYPE_CODES, value);
339
360
  }
340
- function createDashboardTapSignal(sendSignal) {
361
+ function toWidgetEntityType(value) {
362
+ switch (value.toLowerCase()) {
363
+ case "match":
364
+ return "match";
365
+ case "team":
366
+ return "team";
367
+ case "player":
368
+ return "player";
369
+ case "competition":
370
+ return "competition";
371
+ case "market":
372
+ return "market";
373
+ default:
374
+ return null;
375
+ }
376
+ }
377
+ function createDashboardTapSignal(sendSignal, log) {
341
378
  return (tile, index, layout) => {
379
+ const widgetEntityType = toWidgetEntityType(tile.signal.entityType);
380
+ if (widgetEntityType) {
381
+ log?.log({ name: "tile_tap", entityType: widgetEntityType, entityId: tile.signal.entityId });
382
+ }
342
383
  if (!isSignalEntityType(tile.signal.entityType)) return;
343
384
  try {
344
385
  void sendSignal({
@@ -1183,6 +1224,7 @@ function useLiveMonitor(opts) {
1183
1224
  const [chatDot, setChatDot] = (0, import_react3.useState)(false);
1184
1225
  const [matchesDot, setMatchesDot] = (0, import_react3.useState)(false);
1185
1226
  const [oddsDot, setOddsDot] = (0, import_react3.useState)(false);
1227
+ const [todayDot, setTodayDot] = (0, import_react3.useState)(false);
1186
1228
  const [lastViewedPrices, setLastViewedPrices] = (0, import_react3.useState)({});
1187
1229
  const [inSlip, setInSlip] = (0, import_react3.useState)({});
1188
1230
  const [openMarket, setOpenMarket] = (0, import_react3.useState)({});
@@ -1199,6 +1241,7 @@ function useLiveMonitor(opts) {
1199
1241
  openMarketRef.current = openMarket;
1200
1242
  const marketOddsRef = (0, import_react3.useRef)(marketOdds);
1201
1243
  marketOddsRef.current = marketOdds;
1244
+ const hasToday = opts.hasToday ?? false;
1202
1245
  const marketKey = (matchId, dev) => `${matchId}:${dev}`;
1203
1246
  const getMarketOddsRef = (0, import_react3.useRef)(opts.getMarketOdds);
1204
1247
  getMarketOddsRef.current = opts.getMarketOdds;
@@ -1253,7 +1296,7 @@ function useLiveMonitor(opts) {
1253
1296
  break;
1254
1297
  }
1255
1298
  }
1256
- if (sawNewGoalOrRed && activeTabRef.current !== "matches") setMatchesDot(true);
1299
+ if (sawNewGoalOrRed && activeTabRef.current !== "following") setMatchesDot(true);
1257
1300
  for (const m of next.matches) {
1258
1301
  if (!pinnedMatchIds.has(m.matchId)) continue;
1259
1302
  const first = m.availableMarkets?.[0];
@@ -1339,11 +1382,17 @@ function useLiveMonitor(opts) {
1339
1382
  prevPinsLengthRef.current = pins.length;
1340
1383
  if (pins.length === 0) {
1341
1384
  window.clearTimeout(timerRef.current);
1342
- setActiveTabState("chat");
1343
1385
  return;
1344
1386
  }
1345
1387
  if (wasEmpty) void tick();
1346
1388
  }, [pins.length, tick]);
1389
+ (0, import_react3.useEffect)(() => {
1390
+ const matchPins = pins.filter((p) => p.kind === "match").length;
1391
+ const marketPins = pins.length - matchPins;
1392
+ if (activeTab === "following" && matchPins === 0) setActiveTabState(hasToday ? "today" : "chat");
1393
+ if (activeTab === "odds" && marketPins === 0) setActiveTabState(hasToday ? "today" : "chat");
1394
+ if (activeTab === "today" && !hasToday) setActiveTabState("chat");
1395
+ }, [pins, activeTab, hasToday]);
1347
1396
  const prevIsOpenRef = (0, import_react3.useRef)(false);
1348
1397
  (0, import_react3.useEffect)(() => {
1349
1398
  const wasClosed = !prevIsOpenRef.current;
@@ -1364,7 +1413,8 @@ function useLiveMonitor(opts) {
1364
1413
  const setActiveTab = (0, import_react3.useCallback)((tab) => {
1365
1414
  setActiveTabState(tab);
1366
1415
  if (tab === "chat") setChatDot(false);
1367
- if (tab === "matches") {
1416
+ if (tab === "today") setTodayDot(false);
1417
+ if (tab === "following") {
1368
1418
  setMatchesDot(false);
1369
1419
  void tick();
1370
1420
  }
@@ -1384,6 +1434,9 @@ function useLiveMonitor(opts) {
1384
1434
  const togglePin = (0, import_react3.useCallback)((pin) => store.toggle(pin), [store]);
1385
1435
  const isPinned = (0, import_react3.useCallback)((key) => pinsRef.current.some((p) => p.key === key), []);
1386
1436
  const markChatActivity = (0, import_react3.useCallback)(() => setChatDot(true), []);
1437
+ const markTodayActivity = (0, import_react3.useCallback)(() => {
1438
+ if (activeTabRef.current !== "today") setTodayDot(true);
1439
+ }, []);
1387
1440
  const markInSlip = (0, import_react3.useCallback)((matchOddsId) => {
1388
1441
  setInSlip((prev) => prev[matchOddsId] ? prev : { ...prev, [matchOddsId]: true });
1389
1442
  }, []);
@@ -1399,6 +1452,8 @@ function useLiveMonitor(opts) {
1399
1452
  markChatActivity,
1400
1453
  matchesDot,
1401
1454
  oddsDot,
1455
+ todayDot,
1456
+ markTodayActivity,
1402
1457
  lastViewedPrices,
1403
1458
  inSlip,
1404
1459
  markInSlip,
@@ -1410,11 +1465,198 @@ function useLiveMonitor(opts) {
1410
1465
  };
1411
1466
  }
1412
1467
 
1413
- // src/components/ChatFab.tsx
1468
+ // src/useMatchDiscovery.ts
1469
+ var import_react4 = require("react");
1470
+
1471
+ // src/scheduleCache.ts
1472
+ var PREFIX = "ss-w-schedule:";
1473
+ var SCHEMA_VERSION = 1;
1474
+ var TTL_MS2 = 6 * 36e5;
1475
+ function scheduleCacheKey(operatorId, localDate) {
1476
+ return `${PREFIX}${operatorId}:${localDate}`;
1477
+ }
1478
+ function read(operatorId, localDate) {
1479
+ try {
1480
+ const raw = localStorage.getItem(scheduleCacheKey(operatorId, localDate));
1481
+ if (!raw) return null;
1482
+ const entry = JSON.parse(raw);
1483
+ if (entry.v !== SCHEMA_VERSION || !entry.payload) return null;
1484
+ return entry;
1485
+ } catch {
1486
+ return null;
1487
+ }
1488
+ }
1489
+ function readSchedule(operatorId, localDate, nowMs) {
1490
+ const entry = read(operatorId, localDate);
1491
+ if (!entry) return null;
1492
+ return nowMs - entry.at > TTL_MS2 ? null : entry.payload;
1493
+ }
1494
+ function readScheduleIgnoringTtl(operatorId, localDate) {
1495
+ return read(operatorId, localDate)?.payload ?? null;
1496
+ }
1497
+ function skeletonOnly(payload) {
1498
+ return {
1499
+ localDate: payload.localDate,
1500
+ groups: payload.groups.map((g) => ({
1501
+ competitionId: g.competitionId,
1502
+ competitionName: g.competitionName,
1503
+ competitionImagePath: g.competitionImagePath ?? null,
1504
+ rank: g.rank,
1505
+ expandedByDefault: g.expandedByDefault,
1506
+ matches: g.matches.map((m) => ({
1507
+ matchId: m.matchId,
1508
+ homeTeamName: m.homeTeamName,
1509
+ awayTeamName: m.awayTeamName,
1510
+ homeTeamImagePath: m.homeTeamImagePath ?? null,
1511
+ awayTeamImagePath: m.awayTeamImagePath ?? null,
1512
+ kickoffUnix: m.kickoffUnix
1513
+ }))
1514
+ }))
1515
+ };
1516
+ }
1517
+ function writeSchedule(operatorId, localDate, payload, nowMs) {
1518
+ const keep = scheduleCacheKey(operatorId, localDate);
1519
+ const mine = `${PREFIX}${operatorId}:`;
1520
+ try {
1521
+ for (let i = localStorage.length - 1; i >= 0; i--) {
1522
+ const key = localStorage.key(i);
1523
+ if (key && key.startsWith(mine) && key !== keep) localStorage.removeItem(key);
1524
+ }
1525
+ const entry = { v: SCHEMA_VERSION, at: nowMs, payload: skeletonOnly(payload) };
1526
+ localStorage.setItem(keep, JSON.stringify(entry));
1527
+ } catch {
1528
+ }
1529
+ }
1530
+
1531
+ // src/dueSet.ts
1532
+ var WINDOW_MS = 3.5 * 36e5;
1533
+ function dueMatchIds(groups, states, nowMs) {
1534
+ const due = /* @__PURE__ */ new Set();
1535
+ for (const group of groups) {
1536
+ for (const match of group.matches) {
1537
+ const sinceKickoff = nowMs - match.kickoffUnix * 1e3;
1538
+ if (sinceKickoff >= 0 && sinceKickoff <= WINDOW_MS) due.add(match.matchId);
1539
+ if (states[match.matchId]?.phase === "live") due.add(match.matchId);
1540
+ }
1541
+ }
1542
+ return [...due];
1543
+ }
1544
+
1545
+ // src/useMatchDiscovery.ts
1546
+ var POLL_MS = 6e4;
1547
+ var ROLLOVER_CHECK_MS = 6e4;
1548
+ var STALE_AFTER_FAILURES = 2;
1549
+ function localDateOf(now) {
1550
+ const y = now.getFullYear();
1551
+ const m = `${now.getMonth() + 1}`.padStart(2, "0");
1552
+ const d = `${now.getDate()}`.padStart(2, "0");
1553
+ return `${y}-${m}-${d}`;
1554
+ }
1555
+ function useMatchDiscovery(opts) {
1556
+ const [groups, setGroups] = (0, import_react4.useState)([]);
1557
+ const [states, setStates] = (0, import_react4.useState)({});
1558
+ const [failures, setFailures] = (0, import_react4.useState)(0);
1559
+ const [expanded, setExpanded] = (0, import_react4.useState)({});
1560
+ const [touched, setTouched] = (0, import_react4.useState)({});
1561
+ const groupsRef = (0, import_react4.useRef)(groups);
1562
+ groupsRef.current = groups;
1563
+ const statesRef = (0, import_react4.useRef)(states);
1564
+ statesRef.current = states;
1565
+ const getStatesRef = (0, import_react4.useRef)(opts.getStates);
1566
+ getStatesRef.current = opts.getStates;
1567
+ const pinnedKey = opts.pinnedMatchIds.join(",");
1568
+ const [localDate, setLocalDate] = (0, import_react4.useState)(() => localDateOf(/* @__PURE__ */ new Date()));
1569
+ (0, import_react4.useEffect)(() => {
1570
+ const id = setInterval(() => {
1571
+ const next = localDateOf(/* @__PURE__ */ new Date());
1572
+ setLocalDate((prev) => prev === next ? prev : next);
1573
+ }, ROLLOVER_CHECK_MS);
1574
+ return () => clearInterval(id);
1575
+ }, []);
1576
+ (0, import_react4.useEffect)(() => {
1577
+ let cancelled = false;
1578
+ const utcOffsetMinutes = -(/* @__PURE__ */ new Date()).getTimezoneOffset();
1579
+ const cached = readSchedule(opts.operatorId, localDate, Date.now());
1580
+ if (cached) {
1581
+ if (!cancelled) setGroups(cached.groups);
1582
+ return () => {
1583
+ cancelled = true;
1584
+ };
1585
+ }
1586
+ void (async () => {
1587
+ try {
1588
+ const payload = await opts.getSchedule(localDate, utcOffsetMinutes);
1589
+ if (cancelled || !payload) return;
1590
+ writeSchedule(opts.operatorId, localDate, payload, Date.now());
1591
+ setGroups(payload.groups);
1592
+ } catch {
1593
+ const fallback = readScheduleIgnoringTtl(opts.operatorId, localDate);
1594
+ if (!cancelled && fallback) setGroups(fallback.groups);
1595
+ }
1596
+ })();
1597
+ return () => {
1598
+ cancelled = true;
1599
+ };
1600
+ }, [opts.operatorId, localDate]);
1601
+ (0, import_react4.useEffect)(() => {
1602
+ setExpanded((prev) => {
1603
+ const next = {};
1604
+ for (const group of groups) {
1605
+ const hasPin = group.matches.some((m) => opts.pinnedMatchIds.includes(m.matchId));
1606
+ const seeded = group.expandedByDefault || hasPin;
1607
+ next[group.competitionId] = touched[group.competitionId] ? prev[group.competitionId] ?? seeded : seeded;
1608
+ }
1609
+ return next;
1610
+ });
1611
+ }, [groups, pinnedKey, touched]);
1612
+ const tick = (0, import_react4.useCallback)(async () => {
1613
+ const ids = dueMatchIds(groupsRef.current, statesRef.current, Date.now());
1614
+ if (ids.length === 0) return;
1615
+ try {
1616
+ const payload = await getStatesRef.current(ids);
1617
+ if (!payload) return;
1618
+ setStates((prev) => {
1619
+ const next = { ...prev };
1620
+ for (const state of payload.states) next[state.matchId] = state;
1621
+ return next;
1622
+ });
1623
+ setFailures(0);
1624
+ } catch {
1625
+ setFailures((n) => n + 1);
1626
+ }
1627
+ }, []);
1628
+ (0, import_react4.useEffect)(() => {
1629
+ if (!opts.isOpen) return;
1630
+ void tick();
1631
+ const id = setInterval(() => {
1632
+ void tick();
1633
+ }, POLL_MS);
1634
+ return () => clearInterval(id);
1635
+ }, [opts.isOpen, tick, groups]);
1636
+ const stale = failures >= STALE_AFTER_FAILURES;
1637
+ const liveCount = (0, import_react4.useMemo)(
1638
+ () => stale ? 0 : Object.values(states).filter((s) => s.phase === "live").length,
1639
+ [states, stale]
1640
+ );
1641
+ const toggleGroup = (0, import_react4.useCallback)((competitionId) => {
1642
+ setTouched((prev) => ({ ...prev, [competitionId]: true }));
1643
+ setExpanded((prev) => ({ ...prev, [competitionId]: !prev[competitionId] }));
1644
+ }, []);
1645
+ return { groups, states, liveCount, stale, expanded, toggleGroup, _tick: tick };
1646
+ }
1647
+
1648
+ // src/eventLogContext.ts
1414
1649
  var import_react5 = require("react");
1650
+ var EventLogContext = (0, import_react5.createContext)(null);
1651
+ function useEventLog() {
1652
+ return (0, import_react5.useContext)(EventLogContext);
1653
+ }
1654
+
1655
+ // src/components/ChatFab.tsx
1656
+ var import_react7 = require("react");
1415
1657
 
1416
1658
  // src/components/BrandMark.tsx
1417
- var import_react4 = require("react");
1659
+ var import_react6 = require("react");
1418
1660
 
1419
1661
  // src/assets/logo.ts
1420
1662
  var SS_LOGO_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjoAAAI6CAYAAAAuSOLAAAAAAXNSR0IArs4c6QAAAJplWElmTU0AKgAAAAgAAwESAAMAAAABAAEAAAExAAIAAAA9AAAAModpAAQAAAABAAAAcAAAAABBZG9iZSBQaG90b3Nob3AgMjYuMTAgKDIwMjUwNzMwLm0uMzE2NiAwN2IxMjM0KSAgKE1hY2ludG9zaCkAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAI6oAMABAAAAAEAAAI6AAAAACwGtVwAAAQwaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgICAgICAgICB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpEb2N1bWVudElEPnhtcC5kaWQ6QzBGRTM5NjM5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkRvY3VtZW50SUQ+CiAgICAgICAgIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6QzBGRTM5NjI5NEJEMTFGMEJGNjZEMjUyN0U0MzU5RUM8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0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";
@@ -1463,7 +1705,7 @@ function DashboardIcon({ name }) {
1463
1705
  // src/components/BrandMark.tsx
1464
1706
  var import_jsx_runtime2 = require("react/jsx-runtime");
1465
1707
  function BrandMark({ logoUrl, className }) {
1466
- const [failed, setFailed] = (0, import_react4.useState)(false);
1708
+ const [failed, setFailed] = (0, import_react6.useState)(false);
1467
1709
  if (!logoUrl || failed) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SsMark, { className });
1468
1710
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { className, src: logoUrl, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
1469
1711
  }
@@ -1488,9 +1730,9 @@ function GreetingBubble({ text, onOpen, onDismiss, dismissLabel = "Dismiss" }) {
1488
1730
  var import_jsx_runtime4 = require("react/jsx-runtime");
1489
1731
  function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup, dismissLabel = "Dismiss", introAllowed = false, onIntroStart }) {
1490
1732
  const bubble = popupText ?? greeting;
1491
- const [intro, setIntro] = (0, import_react5.useState)(false);
1492
- const armedRef = (0, import_react5.useRef)(introAllowed);
1493
- (0, import_react5.useEffect)(() => {
1733
+ const [intro, setIntro] = (0, import_react7.useState)(false);
1734
+ const armedRef = (0, import_react7.useRef)(introAllowed);
1735
+ (0, import_react7.useEffect)(() => {
1494
1736
  if (armedRef.current && bubble) {
1495
1737
  armedRef.current = false;
1496
1738
  setIntro(true);
@@ -1504,10 +1746,10 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
1504
1746
  }
1505
1747
 
1506
1748
  // src/components/ChatPanel.tsx
1507
- var import_react23 = require("react");
1749
+ var import_react25 = require("react");
1508
1750
 
1509
1751
  // src/components/ChatHeader.tsx
1510
- var import_react6 = require("react");
1752
+ var import_react8 = require("react");
1511
1753
  var import_jsx_runtime5 = require("react/jsx-runtime");
1512
1754
  function ChatHeader({
1513
1755
  onClose,
@@ -1519,15 +1761,15 @@ function ChatHeader({
1519
1761
  newConversationLabel = "New conversation",
1520
1762
  moreOptionsLabel = "More options"
1521
1763
  }) {
1522
- const [menuOpen, setMenuOpen] = (0, import_react6.useState)(false);
1523
- const wrapRef = (0, import_react6.useRef)(null);
1524
- const kebabRef = (0, import_react6.useRef)(null);
1525
- const firstItemRef = (0, import_react6.useRef)(null);
1764
+ const [menuOpen, setMenuOpen] = (0, import_react8.useState)(false);
1765
+ const wrapRef = (0, import_react8.useRef)(null);
1766
+ const kebabRef = (0, import_react8.useRef)(null);
1767
+ const firstItemRef = (0, import_react8.useRef)(null);
1526
1768
  const hasMenu = !!(canReset && onNewConversation);
1527
- (0, import_react6.useEffect)(() => {
1769
+ (0, import_react8.useEffect)(() => {
1528
1770
  if (menuOpen) firstItemRef.current?.focus();
1529
1771
  }, [menuOpen]);
1530
- (0, import_react6.useEffect)(() => {
1772
+ (0, import_react8.useEffect)(() => {
1531
1773
  if (!menuOpen) return;
1532
1774
  const onPointer = (e) => {
1533
1775
  if (!wrapRef.current?.contains(e.target)) setMenuOpen(false);
@@ -1583,7 +1825,7 @@ function ChatHeader({
1583
1825
  }
1584
1826
 
1585
1827
  // src/components/MessageList.tsx
1586
- var import_react21 = require("react");
1828
+ var import_react23 = require("react");
1587
1829
 
1588
1830
  // src/components/Markdown.tsx
1589
1831
  var import_react_markdown = __toESM(require("react-markdown"), 1);
@@ -1601,7 +1843,7 @@ function Markdown({ text }) {
1601
1843
  }
1602
1844
 
1603
1845
  // src/components/EntityCardList.tsx
1604
- var import_react7 = require("react");
1846
+ var import_react9 = require("react");
1605
1847
  var import_jsx_runtime7 = require("react/jsx-runtime");
1606
1848
  var MAX_VISIBLE = 3;
1607
1849
  var RECORD_RE = /^(\d+)-(\d+)-(\d+)$/;
@@ -1685,7 +1927,7 @@ function ScopeTabs({ scopes, active, onSelect }) {
1685
1927
  )) });
1686
1928
  }
1687
1929
  function EntityCardItem({ c }) {
1688
- const [active, setActive] = (0, import_react7.useState)(0);
1930
+ const [active, setActive] = (0, import_react9.useState)(0);
1689
1931
  const hasBody = c.scopes.length > 0;
1690
1932
  if (!hasBody) {
1691
1933
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ss-w-ecard ss-w-ecard-bare", "data-kind": c.kind, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CardHeader, { c, showScopeCrest: false }) });
@@ -1699,7 +1941,7 @@ function EntityCardItem({ c }) {
1699
1941
  ] });
1700
1942
  }
1701
1943
  function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMoreLabel = (n) => `Show ${n} more` }) {
1702
- const [expanded, setExpanded] = (0, import_react7.useState)(false);
1944
+ const [expanded, setExpanded] = (0, import_react9.useState)(false);
1703
1945
  if (cards.length === 0) return null;
1704
1946
  const visible = expanded ? cards : cards.slice(0, MAX_VISIBLE);
1705
1947
  const overflow = cards.length - MAX_VISIBLE;
@@ -1710,18 +1952,18 @@ function EntityCardList({ cards, disabled, showLessLabel = "Show less", showMore
1710
1952
  }
1711
1953
 
1712
1954
  // src/components/BettingInsightList.tsx
1713
- var import_react12 = require("react");
1955
+ var import_react14 = require("react");
1714
1956
 
1715
1957
  // src/components/AddToSlipButton.tsx
1716
- var import_react9 = require("react");
1958
+ var import_react11 = require("react");
1717
1959
  var import_widget_sdk4 = require("@sensiblestats/widget-sdk");
1718
1960
 
1719
1961
  // src/components/Toast.tsx
1720
- var import_react8 = require("react");
1962
+ var import_react10 = require("react");
1721
1963
  var import_jsx_runtime8 = require("react/jsx-runtime");
1722
1964
  var DISMISS_MS = 4e3;
1723
1965
  function Toast({ toast, onDismiss }) {
1724
- (0, import_react8.useEffect)(() => {
1966
+ (0, import_react10.useEffect)(() => {
1725
1967
  if (!toast) return;
1726
1968
  const timer = setTimeout(onDismiss, DISMISS_MS);
1727
1969
  return () => clearTimeout(timer);
@@ -1738,19 +1980,32 @@ function withTimeout(value) {
1738
1980
  new Promise((_, reject) => setTimeout(() => reject(new Error("add-to-slip timed out")), ADD_TO_SLIP_TIMEOUT_MS))
1739
1981
  ]);
1740
1982
  }
1741
- function SlipButton({ selection, shownOdds, marketName, slip, ui }) {
1742
- const [pending, setPending] = (0, import_react9.useState)(false);
1743
- const [settled, setSettled] = (0, import_react9.useState)(false);
1744
- const [toast, setToast] = (0, import_react9.useState)(null);
1745
- const dismiss = (0, import_react9.useCallback)(() => setToast(null), []);
1983
+ function SlipButton({ selection, shownOdds, marketName, marketDeveloperName, slip, ui }) {
1984
+ const [pending, setPending] = (0, import_react11.useState)(false);
1985
+ const [settled, setSettled] = (0, import_react11.useState)(false);
1986
+ const [toast, setToast] = (0, import_react11.useState)(null);
1987
+ const dismiss = (0, import_react11.useCallback)(() => setToast(null), []);
1988
+ const log = useEventLog();
1746
1989
  const handler = slip.onAddToSlip;
1747
1990
  if (!ui || !handler || !selection) return null;
1748
1991
  const onClick = async () => {
1749
1992
  setPending(true);
1993
+ if (marketDeveloperName !== void 0) {
1994
+ log?.log({ name: "slip_click", entityType: "market", marketDeveloperName, entityId: marketDeveloperName });
1995
+ }
1750
1996
  try {
1751
1997
  const raw = await withTimeout(Promise.resolve(handler(selection)));
1752
1998
  if (raw != null && !(0, import_widget_sdk4.isAddToSlipResult)(raw)) throw new Error("malformed add-to-slip result");
1753
1999
  const result = raw ?? void 0;
2000
+ if (marketDeveloperName !== void 0) {
2001
+ log?.log({
2002
+ name: "slip_result",
2003
+ entityType: "market",
2004
+ marketDeveloperName,
2005
+ entityId: marketDeveloperName,
2006
+ outcome: slipOutcome(result)
2007
+ });
2008
+ }
1754
2009
  setToast(resultToToast(result, shownOdds || selection.oddsDecimal.toFixed(2), ui));
1755
2010
  setSettled(isTerminal(result));
1756
2011
  if (wasAdded(result) && slip.onMarketClicked) {
@@ -1760,6 +2015,9 @@ function SlipButton({ selection, shownOdds, marketName, slip, ui }) {
1760
2015
  }
1761
2016
  }
1762
2017
  } catch {
2018
+ if (marketDeveloperName !== void 0) {
2019
+ log?.log({ name: "slip_result", entityType: "market", marketDeveloperName, entityId: marketDeveloperName, outcome: "timeout" });
2020
+ }
1763
2021
  setToast({ kind: "error", text: ui.slipFailed });
1764
2022
  } finally {
1765
2023
  setPending(false);
@@ -1781,7 +2039,17 @@ function SlipButton({ selection, shownOdds, marketName, slip, ui }) {
1781
2039
  }
1782
2040
  function AddToSlipButton({ it, slip, ui }) {
1783
2041
  const selection = it.addToSlipEnabled ? toSlipSelection(it, slip.conversationId) : null;
1784
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SlipButton, { selection, shownOdds: it.odds ?? "", marketName: it.market, slip, ui });
2042
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2043
+ SlipButton,
2044
+ {
2045
+ selection,
2046
+ shownOdds: it.odds ?? "",
2047
+ marketName: it.market,
2048
+ marketDeveloperName: it.marketDeveloperName,
2049
+ slip,
2050
+ ui
2051
+ }
2052
+ );
1785
2053
  }
1786
2054
 
1787
2055
  // src/components/OddsMovementBadge.tsx
@@ -1806,14 +2074,14 @@ function OddsMovementBadge({
1806
2074
  }
1807
2075
 
1808
2076
  // src/components/Crest.tsx
1809
- var import_react10 = require("react");
2077
+ var import_react12 = require("react");
1810
2078
  var import_jsx_runtime11 = require("react/jsx-runtime");
1811
2079
  function initials2(name) {
1812
2080
  return (name ?? "").trim().slice(0, 1).toUpperCase() || "?";
1813
2081
  }
1814
2082
  function Crest2({ url, name, kind }) {
1815
2083
  const cls = kind === "comp" ? "ss-w-bi-comp-logo" : "ss-w-bi-crest";
1816
- const [failed, setFailed] = (0, import_react10.useState)(false);
2084
+ const [failed, setFailed] = (0, import_react12.useState)(false);
1817
2085
  if (url && !failed) {
1818
2086
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
1819
2087
  }
@@ -1821,7 +2089,7 @@ function Crest2({ url, name, kind }) {
1821
2089
  }
1822
2090
 
1823
2091
  // src/components/PinToggle.tsx
1824
- var import_react11 = require("react");
2092
+ var import_react13 = require("react");
1825
2093
  var import_jsx_runtime12 = require("react/jsx-runtime");
1826
2094
  var PIN_GLYPHS = {
1827
2095
  pin: { viewBox: "0 0 24 24", strokeWidth: 1.4, transform: "scale(1.5)", 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" },
@@ -1829,15 +2097,23 @@ var PIN_GLYPHS = {
1829
2097
  bookmark: { viewBox: "0 0 24 24", strokeWidth: 2, d: "M7 3h10a1.5 1.5 0 0 1 1.5 1.5V21l-6.5-3.6L5.5 21V4.5A1.5 1.5 0 0 1 7 3z" }
1830
2098
  };
1831
2099
  function PinToggle({ pin, monitor, ui }) {
1832
- const [toast, setToast] = (0, import_react11.useState)(null);
1833
- const dismiss = (0, import_react11.useCallback)(() => setToast(null), []);
2100
+ const [toast, setToast] = (0, import_react13.useState)(null);
2101
+ const dismiss = (0, import_react13.useCallback)(() => setToast(null), []);
2102
+ const log = useEventLog();
1834
2103
  if (!monitor || !monitor.enabled) return null;
1835
2104
  const key = pinKey(pin);
1836
2105
  const pinned = monitor.isPinned(key);
1837
2106
  const labels = pin.kind === "match" ? { pin: ui.matchPinLabel, unpin: ui.matchUnpinLabel } : { pin: ui.pinLabel, unpin: ui.unpinLabel };
1838
2107
  const onClick = () => {
1839
2108
  const result = monitor.togglePin({ ...pin, key });
1840
- if (result === "match_limit") {
2109
+ if ((result === "added" || result === "removed") && (pin.kind === "match" || pin.marketDeveloperName !== void 0)) {
2110
+ log?.log({
2111
+ name: result === "added" ? "pin_add" : "pin_remove",
2112
+ entityType: pin.kind === "match" ? "match" : "market",
2113
+ entityId: pin.kind === "match" ? String(pin.matchId) : pin.marketDeveloperName,
2114
+ marketDeveloperName: pin.marketDeveloperName
2115
+ });
2116
+ } else if (result === "match_limit") {
1841
2117
  setToast({ kind: "error", text: ui.matchLimitToast });
1842
2118
  } else if (result === "market_limit") {
1843
2119
  setToast({ kind: "error", text: ui.marketLimitToast });
@@ -1882,7 +2158,7 @@ function StatRows({ stats }) {
1882
2158
  ] }, `${s.label}:${s.value}`)) });
1883
2159
  }
1884
2160
  function ScopedStats({ scopes }) {
1885
- const [active, setActive] = (0, import_react12.useState)(0);
2161
+ const [active, setActive] = (0, import_react14.useState)(0);
1886
2162
  const current = scopes[active] ?? scopes[0] ?? { key: "", label: "", stats: [] };
1887
2163
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-bi-scoped", children: [
1888
2164
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ss-w-bi-scopes", role: "group", children: scopes.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "ss-w-bi-chip", "aria-pressed": i === active, onClick: () => setActive(i), children: s.label }, s.key)) }),
@@ -1893,12 +2169,20 @@ function hasStatsContent(it) {
1893
2169
  return !!it.scopes && it.scopes.length >= 2 || it.stats.length > 0;
1894
2170
  }
1895
2171
  function ReasonStrip({ it, ui }) {
1896
- const [open, setOpen] = (0, import_react12.useState)(false);
2172
+ const [open, setOpen] = (0, import_react14.useState)(false);
2173
+ const log = useEventLog();
1897
2174
  const hasScopes = !!it.scopes && it.scopes.length >= 2;
1898
2175
  const hasStats = hasStatsContent(it);
1899
2176
  const hasText = !!it.text;
1900
2177
  if (!hasText && !hasStats) return null;
1901
2178
  const expandable = hasStats || (it.text?.length ?? 0) > 90;
2179
+ const onToggle = () => {
2180
+ setOpen((v) => {
2181
+ const next = !v;
2182
+ if (next) log?.log({ name: "insight_expand", entityType: "match", entityId: String(it.matchId) });
2183
+ return next;
2184
+ });
2185
+ };
1902
2186
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-bi-reason", children: [
1903
2187
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ss-w-bi-chart", "aria-hidden": "true" }),
1904
2188
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ss-w-bi-reason-body", children: [
@@ -1912,7 +2196,7 @@ function ReasonStrip({ it, ui }) {
1912
2196
  className: "ss-w-bi-expand",
1913
2197
  "aria-expanded": open,
1914
2198
  "aria-label": open ? ui?.hideStats ?? "Hide stats" : ui?.showStats ?? "Show stats",
1915
- onClick: () => setOpen((v) => !v),
2199
+ onClick: onToggle,
1916
2200
  children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: `ss-w-bi-arrow${open ? " ss-w-bi-arrow-open" : ""}`, "aria-hidden": "true" })
1917
2201
  }
1918
2202
  ) : null
@@ -2005,7 +2289,7 @@ function BettingInsightList({ insights, ui, slip, monitor }) {
2005
2289
  }
2006
2290
 
2007
2291
  // src/components/MarketOddsCardList.tsx
2008
- var import_react13 = require("react");
2292
+ var import_react15 = require("react");
2009
2293
  var import_jsx_runtime14 = require("react/jsx-runtime");
2010
2294
  function OddsRow({ vm, row, ui, slip, inSlipIds }) {
2011
2295
  const selection = vm.addToSlipEnabled ? marketOddsRowToSlipSelection(vm, row, slip.conversationId) : null;
@@ -2018,11 +2302,11 @@ function OddsRow({ vm, row, ui, slip, inSlipIds }) {
2018
2302
  "\u2713 ",
2019
2303
  ui.inSlipLabel
2020
2304
  ] }) : null,
2021
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SlipButton, { selection, shownOdds: row.odds, marketName: vm.market, slip, ui })
2305
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SlipButton, { selection, shownOdds: row.odds, marketName: vm.market, marketDeveloperName: vm.marketDeveloperName, slip, ui })
2022
2306
  ] });
2023
2307
  }
2024
2308
  function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader, pinRef }) {
2025
- const [open, setOpen] = (0, import_react13.useState)(false);
2309
+ const [open, setOpen] = (0, import_react15.useState)(false);
2026
2310
  const kickoffFallback = vm.kickoffUtc && ui?.bettingKickoff ? ui.bettingKickoff(vm.kickoffUtc) : void 0;
2027
2311
  const kickoff = vm.kickoffLabel ?? (kickoffFallback ? `${kickoffFallback.dayLabel} ${kickoffFallback.time}` : void 0);
2028
2312
  const hasNamedTeams = !!vm.homeTeamName && !!vm.awayTeamName;
@@ -2325,7 +2609,7 @@ function FixtureCard({ card }) {
2325
2609
  }
2326
2610
 
2327
2611
  // src/components/dashboard/CountdownCard.tsx
2328
- var import_react14 = require("react");
2612
+ var import_react16 = require("react");
2329
2613
  var import_jsx_runtime20 = require("react/jsx-runtime");
2330
2614
  var DAY_MS = 864e5;
2331
2615
  function remainingSegments(kickoffUnix, nowMs, withSeconds) {
@@ -2344,12 +2628,12 @@ function remainingSegments(kickoffUnix, nowMs, withSeconds) {
2344
2628
  function CountdownCard({ card }) {
2345
2629
  const { data } = card;
2346
2630
  const unitLabel = { d: data.daysUnit, h: data.hoursUnit, m: data.minutesUnit, s: data.secondsUnit };
2347
- const [nowMs, setNowMs] = (0, import_react14.useState)(() => Date.now());
2348
- const [reduced] = (0, import_react14.useState)(
2631
+ const [nowMs, setNowMs] = (0, import_react16.useState)(() => Date.now());
2632
+ const [reduced] = (0, import_react16.useState)(
2349
2633
  () => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
2350
2634
  );
2351
2635
  const withinDay = data.kickoffUnix * 1e3 - nowMs < DAY_MS;
2352
- (0, import_react14.useEffect)(() => {
2636
+ (0, import_react16.useEffect)(() => {
2353
2637
  if (reduced) return;
2354
2638
  const id = window.setInterval(() => setNowMs(Date.now()), withinDay ? 1e3 : 6e4);
2355
2639
  return () => window.clearInterval(id);
@@ -2357,7 +2641,7 @@ function CountdownCard({ card }) {
2357
2641
  const segments = remainingSegments(data.kickoffUnix, nowMs, withinDay && !reduced);
2358
2642
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "ss-w-fandash-card ss-w-fandash-countdown", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "ss-w-fandash-countdown-top", children: [
2359
2643
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-eyebrow", children: card.title ?? "Kick-off in" }),
2360
- segments ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-countdown-clock", children: segments.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react14.Fragment, { children: [
2644
+ segments ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-countdown-clock", children: segments.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react16.Fragment, { children: [
2361
2645
  i > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-countdown-colon", children: ":" }) : null,
2362
2646
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "ss-w-fandash-countdown-seg", children: [
2363
2647
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "ss-w-fandash-countdown-value", children: s.value }),
@@ -2368,7 +2652,7 @@ function CountdownCard({ card }) {
2368
2652
  }
2369
2653
 
2370
2654
  // src/components/dashboard/InjuriesCard.tsx
2371
- var import_react15 = require("react");
2655
+ var import_react17 = require("react");
2372
2656
  var import_jsx_runtime21 = require("react/jsx-runtime");
2373
2657
  var SHOWN = 3;
2374
2658
  function ColHead({ name, crestUrl }) {
@@ -2391,7 +2675,7 @@ function InjuryList({ rows, emptyLabel, limit }) {
2391
2675
  }
2392
2676
  function InjuriesCard({ card, ui }) {
2393
2677
  const { data } = card;
2394
- const [expanded, setExpanded] = (0, import_react15.useState)(false);
2678
+ const [expanded, setExpanded] = (0, import_react17.useState)(false);
2395
2679
  const hidden = Math.max(0, data.ours.length - SHOWN) + Math.max(0, data.theirs.length - SHOWN);
2396
2680
  const limit = expanded ? void 0 : SHOWN;
2397
2681
  const showMore = ui?.showMore ?? ((n) => `Show ${n} more`);
@@ -2495,7 +2779,7 @@ function LinksCard({ card }) {
2495
2779
  }
2496
2780
 
2497
2781
  // src/components/dashboard/PostMatchResultCard.tsx
2498
- var import_react16 = require("react");
2782
+ var import_react18 = require("react");
2499
2783
  var import_jsx_runtime27 = require("react/jsx-runtime");
2500
2784
  function initials3(name) {
2501
2785
  return name.trim().slice(0, 3).toUpperCase();
@@ -2505,7 +2789,7 @@ function PostMatchCrest({
2505
2789
  name,
2506
2790
  side
2507
2791
  }) {
2508
- const [failed, setFailed] = (0, import_react16.useState)(false);
2792
+ const [failed, setFailed] = (0, import_react18.useState)(false);
2509
2793
  const cls = `ss-w-fandash-postmatch-crest ss-w-fandash-postmatch-crest--${side}`;
2510
2794
  if (url && !failed) {
2511
2795
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
@@ -2704,10 +2988,10 @@ function RestingFormCard({ card }) {
2704
2988
  }
2705
2989
 
2706
2990
  // src/components/dashboard/LiveScoreCard.tsx
2707
- var import_react18 = require("react");
2991
+ var import_react20 = require("react");
2708
2992
 
2709
2993
  // src/useLiveClock.ts
2710
- var import_react17 = require("react");
2994
+ var import_react19 = require("react");
2711
2995
  var TICK_MS = 6e4;
2712
2996
  var MAX_LIVE_TICK_MINUTES = 15;
2713
2997
  function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
@@ -2716,10 +3000,10 @@ function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
2716
3000
  return minute + Math.min(Math.max(0, elapsedMinutes), MAX_LIVE_TICK_MINUTES);
2717
3001
  }
2718
3002
  function useLiveClock(minute, clockRunning, receivedAtMs) {
2719
- const [displayMinute, setDisplayMinute] = (0, import_react17.useState)(
3003
+ const [displayMinute, setDisplayMinute] = (0, import_react19.useState)(
2720
3004
  () => computeDisplayMinute(minute, clockRunning, receivedAtMs)
2721
3005
  );
2722
- (0, import_react17.useEffect)(() => {
3006
+ (0, import_react19.useEffect)(() => {
2723
3007
  setDisplayMinute(computeDisplayMinute(minute, clockRunning, receivedAtMs));
2724
3008
  if (!clockRunning) return;
2725
3009
  const id = window.setInterval(() => {
@@ -2736,7 +3020,7 @@ function initials5(name) {
2736
3020
  return name.trim().slice(0, 3).toUpperCase();
2737
3021
  }
2738
3022
  function LiveCrest({ url, name, side }) {
2739
- const [failed, setFailed] = (0, import_react18.useState)(false);
3023
+ const [failed, setFailed] = (0, import_react20.useState)(false);
2740
3024
  const cls = `ss-w-fandash-live-crest ss-w-fandash-live-crest--${side}`;
2741
3025
  if (url && !failed) {
2742
3026
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("img", { className: cls, src: url, alt: "", "aria-hidden": "true", onError: () => setFailed(true) });
@@ -2755,7 +3039,7 @@ function LiveScoreCard({
2755
3039
  }) {
2756
3040
  const { data } = card;
2757
3041
  const seedKey = `${data.minute}:${data.homeScore}:${data.awayScore}`;
2758
- const seedRef = (0, import_react18.useRef)(null);
3042
+ const seedRef = (0, import_react20.useRef)(null);
2759
3043
  if (!seedRef.current || seedRef.current.key !== seedKey) {
2760
3044
  seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
2761
3045
  }
@@ -2795,7 +3079,7 @@ function LiveScoreCard({
2795
3079
  }
2796
3080
 
2797
3081
  // src/components/dashboard/LiveTimelineCard.tsx
2798
- var import_react19 = require("react");
3082
+ var import_react21 = require("react");
2799
3083
  var import_jsx_runtime37 = require("react/jsx-runtime");
2800
3084
  var SHOWN2 = 3;
2801
3085
  function EventIcon({ type }) {
@@ -2837,7 +3121,7 @@ function EventRow({ e }) {
2837
3121
  ] });
2838
3122
  }
2839
3123
  function LiveTimelineCard({ card, ui }) {
2840
- const [expanded, setExpanded] = (0, import_react19.useState)(false);
3124
+ const [expanded, setExpanded] = (0, import_react21.useState)(false);
2841
3125
  const events = card.data.events;
2842
3126
  if (!events || events.length === 0) return null;
2843
3127
  const sorted = [...events].sort((a, b) => b.minute - a.minute);
@@ -2862,7 +3146,7 @@ function LiveTimelineCard({ card, ui }) {
2862
3146
  }
2863
3147
 
2864
3148
  // src/components/dashboard/MomentumWave.tsx
2865
- var import_react20 = require("react");
3149
+ var import_react22 = require("react");
2866
3150
  var import_jsx_runtime38 = require("react/jsx-runtime");
2867
3151
  var WIDTH = 270;
2868
3152
  var HEIGHT = 56;
@@ -2886,7 +3170,7 @@ function MomentumWave({
2886
3170
  }) {
2887
3171
  if (points.length === 0) return null;
2888
3172
  const { area, line, lastLeftPct, lastTopPx } = buildPaths(points);
2889
- const clipId = (0, import_react20.useId)();
3173
+ const clipId = (0, import_react22.useId)();
2890
3174
  const topClipId = `${clipId}-top`;
2891
3175
  const bottomClipId = `${clipId}-bottom`;
2892
3176
  const topClass = clubIsHome ? "ss-w-fandash-live-mom-home" : "ss-w-fandash-live-mom-away";
@@ -3077,11 +3361,11 @@ function turnAnchor(messages) {
3077
3361
  }
3078
3362
  function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
3079
3363
  const { state, send } = controller;
3080
- const listRef = (0, import_react21.useRef)(null);
3081
- const endRef = (0, import_react21.useRef)(null);
3082
- const pinnedRef = (0, import_react21.useRef)(true);
3083
- const anchoredTurnRef = (0, import_react21.useRef)(null);
3084
- (0, import_react21.useEffect)(() => {
3364
+ const listRef = (0, import_react23.useRef)(null);
3365
+ const endRef = (0, import_react23.useRef)(null);
3366
+ const pinnedRef = (0, import_react23.useRef)(true);
3367
+ const anchoredTurnRef = (0, import_react23.useRef)(null);
3368
+ (0, import_react23.useEffect)(() => {
3085
3369
  const anchor = turnAnchor(state.messages);
3086
3370
  const list = listRef.current;
3087
3371
  if (anchor && anchor.turnId !== anchoredTurnRef.current) {
@@ -3137,10 +3421,10 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
3137
3421
  }
3138
3422
 
3139
3423
  // src/components/ChatInput.tsx
3140
- var import_react22 = require("react");
3424
+ var import_react24 = require("react");
3141
3425
  var import_jsx_runtime44 = require("react/jsx-runtime");
3142
3426
  function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message" }) {
3143
- const [value, setValue] = (0, import_react22.useState)("");
3427
+ const [value, setValue] = (0, import_react24.useState)("");
3144
3428
  const submit = () => {
3145
3429
  const t = value.trim();
3146
3430
  if (!t) return;
@@ -3161,22 +3445,16 @@ function ChatInput({ placeholder, streaming, onSend, onStop, stopLabel = "Stop r
3161
3445
 
3162
3446
  // src/components/TabBar.tsx
3163
3447
  var import_jsx_runtime45 = require("react/jsx-runtime");
3164
- var TABS = [
3165
- { tab: "chat", labelKey: "tabChat" },
3166
- { tab: "matches", labelKey: "tabMatches" },
3167
- { tab: "odds", labelKey: "tabOdds" }
3168
- ];
3169
- function TabBar({ monitor, ui, matchCount, oddsCount }) {
3170
- if (monitor.pins.length === 0) return null;
3171
- const counts = { chat: 0, matches: matchCount, odds: oddsCount };
3172
- const dots = {
3173
- chat: monitor.chatDot && monitor.activeTab !== "chat",
3174
- matches: monitor.matchesDot && monitor.activeTab !== "matches",
3175
- odds: monitor.oddsDot && monitor.activeTab !== "odds"
3176
- };
3177
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "ss-w-tabs", role: "tablist", children: TABS.map(({ tab, labelKey }) => {
3448
+ function TabBar({ monitor, ui, matchCount, oddsCount, todayCount, hasToday }) {
3449
+ const tabs = [
3450
+ { tab: "chat", label: ui.tabChat, count: 0, dot: monitor.chatDot },
3451
+ ...hasToday ? [{ tab: "today", label: ui.tabToday, count: todayCount, dot: monitor.todayDot }] : [],
3452
+ ...matchCount > 0 ? [{ tab: "following", label: ui.tabFollowing, count: matchCount, dot: monitor.matchesDot }] : [],
3453
+ ...oddsCount > 0 ? [{ tab: "odds", label: ui.tabOdds, count: oddsCount, dot: monitor.oddsDot }] : []
3454
+ ];
3455
+ if (tabs.length < 2) return null;
3456
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "ss-w-tabs", role: "tablist", children: tabs.map(({ tab, label, count, dot }) => {
3178
3457
  const active = monitor.activeTab === tab;
3179
- const count = counts[tab];
3180
3458
  return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
3181
3459
  "button",
3182
3460
  {
@@ -3187,9 +3465,9 @@ function TabBar({ monitor, ui, matchCount, oddsCount }) {
3187
3465
  className: "ss-w-tab",
3188
3466
  onClick: () => monitor.setActiveTab(tab),
3189
3467
  children: [
3190
- ui[labelKey],
3468
+ label,
3191
3469
  count > 0 && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-tab-count", children: count }),
3192
- dots[tab] && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-tab-dot", "aria-hidden": "true" })
3470
+ dot && !active && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "ss-w-tab-dot", "aria-hidden": "true" })
3193
3471
  ]
3194
3472
  },
3195
3473
  tab
@@ -3350,6 +3628,7 @@ function MonitorMatchCard({ match, promotedPins, monitor, ui, slip }) {
3350
3628
  selection,
3351
3629
  shownOdds: typeof row.market.price === "number" ? row.market.price.toFixed(2) : "",
3352
3630
  marketName: row.market.marketLabel,
3631
+ marketDeveloperName: row.market.marketDeveloperName,
3353
3632
  slip,
3354
3633
  ui
3355
3634
  }
@@ -3444,12 +3723,96 @@ function OddsPanel({ monitor, ui, slip }) {
3444
3723
  }) });
3445
3724
  }
3446
3725
 
3447
- // src/components/ChatPanel.tsx
3726
+ // src/components/FixtureRow.tsx
3448
3727
  var import_jsx_runtime49 = require("react/jsx-runtime");
3728
+ function kickoffLabel(kickoffUnix) {
3729
+ const d = new Date(kickoffUnix * 1e3);
3730
+ return `${`${d.getHours()}`.padStart(2, "0")}:${`${d.getMinutes()}`.padStart(2, "0")}`;
3731
+ }
3732
+ function Side({ name, crest }) {
3733
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: "ss-w-drow-side", children: [
3734
+ crest ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("img", { className: "ss-w-drow-crest", src: crest, alt: "" }) : null,
3735
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "ss-w-drow-nm", children: name })
3736
+ ] });
3737
+ }
3738
+ function FixtureRow({ match, state, stale, ui, monitor }) {
3739
+ const isLive = state?.phase === "live" && !stale;
3740
+ const hasScore = (state?.phase === "live" || state?.phase === "fullTime") && typeof state.homeScore === "number" && typeof state.awayScore === "number";
3741
+ const when = stale && state?.phase === "live" ? "\u2014" : isLive ? state?.minuteLabel ?? "\u2014" : kickoffLabel(match.kickoffUnix);
3742
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: isLive ? "ss-w-drow ss-w-drow--live" : "ss-w-drow", children: [
3743
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: isLive ? "ss-w-drow-when ss-w-drow-when--live" : "ss-w-drow-when", children: when }),
3744
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: "ss-w-drow-fx", children: [
3745
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Side, { name: match.homeTeamName, crest: match.homeTeamImagePath }),
3746
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "ss-w-drow-dash", children: "\u2013" }),
3747
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Side, { name: match.awayTeamName, crest: match.awayTeamImagePath })
3748
+ ] }),
3749
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: hasScore ? "ss-w-drow-sc" : "ss-w-drow-sc ss-w-drow-sc--idle", children: hasScore ? `${state.homeScore}\u2013${state.awayScore}` : "\u2013" }),
3750
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(PinToggle, { ui, monitor, pin: { kind: "match", matchId: match.matchId } })
3751
+ ] });
3752
+ }
3753
+
3754
+ // src/components/CompetitionGroup.tsx
3755
+ var import_jsx_runtime50 = require("react/jsx-runtime");
3756
+ function CompetitionGroup({ group, open, onToggle, states, stale, ui, monitor }) {
3757
+ const own = group.matches.filter((m) => states[m.matchId]?.phase !== "live" || stale);
3758
+ const hasLive = own.length !== group.matches.length;
3759
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "ss-w-grp", children: [
3760
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("button", { type: "button", className: "ss-w-grp-head", "aria-expanded": open, onClick: onToggle, children: [
3761
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "ss-w-grp-chev", children: open ? "\u25BE" : "\u25B8" }),
3762
+ hasLive && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "ss-w-sec-dot", "aria-hidden": "true" }),
3763
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "ss-w-grp-name", children: group.competitionName }),
3764
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "ss-w-grp-count", children: own.length })
3765
+ ] }),
3766
+ open && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "ss-w-grp-body", children: own.map((m) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(FixtureRow, { match: m, state: states[m.matchId], stale, ui, monitor }, m.matchId)) })
3767
+ ] });
3768
+ }
3769
+
3770
+ // src/components/TodayPanel.tsx
3771
+ var import_jsx_runtime51 = require("react/jsx-runtime");
3772
+ function TodayPanel({ discovery, ui, monitor }) {
3773
+ const { groups, states, stale, expanded, toggleGroup } = discovery;
3774
+ const liveRows = stale ? [] : groups.flatMap((group) => group.matches.filter((m) => states[m.matchId]?.phase === "live").map((match) => ({ match, rank: group.rank }))).sort((a, b) => a.rank - b.rank);
3775
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "ss-w-mon-list", children: [
3776
+ stale && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "ss-w-stale", children: ui.staleStates }),
3777
+ liveRows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
3778
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "ss-w-sec-head", children: [
3779
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "ss-w-sec-dot", "aria-hidden": "true" }),
3780
+ ui.sectionLive
3781
+ ] }),
3782
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "ss-w-today-live", children: liveRows.map(({ match }) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3783
+ FixtureRow,
3784
+ {
3785
+ match,
3786
+ state: states[match.matchId],
3787
+ stale,
3788
+ ui,
3789
+ monitor
3790
+ },
3791
+ match.matchId
3792
+ )) })
3793
+ ] }),
3794
+ groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
3795
+ CompetitionGroup,
3796
+ {
3797
+ group,
3798
+ open: expanded[group.competitionId] ?? group.expandedByDefault,
3799
+ onToggle: () => toggleGroup(group.competitionId),
3800
+ states,
3801
+ stale,
3802
+ ui,
3803
+ monitor
3804
+ },
3805
+ group.competitionId
3806
+ ))
3807
+ ] });
3808
+ }
3809
+
3810
+ // src/components/ChatPanel.tsx
3811
+ var import_jsx_runtime52 = require("react/jsx-runtime");
3449
3812
  var FULLSCREEN_QUERY = "(max-width: 639px)";
3450
3813
  function useIsModal() {
3451
- const [modal, setModal] = (0, import_react23.useState)(false);
3452
- (0, import_react23.useEffect)(() => {
3814
+ const [modal, setModal] = (0, import_react25.useState)(false);
3815
+ (0, import_react25.useEffect)(() => {
3453
3816
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
3454
3817
  const mql = window.matchMedia(FULLSCREEN_QUERY);
3455
3818
  const sync = () => setModal(mql.matches);
@@ -3459,10 +3822,10 @@ function useIsModal() {
3459
3822
  }, []);
3460
3823
  return modal;
3461
3824
  }
3462
- function ChatPanel({ controller, ui, slip, onDashboardTap, monitor }) {
3825
+ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery }) {
3463
3826
  const { state, close, stop, send, reset } = controller;
3464
3827
  const isModal = useIsModal();
3465
- (0, import_react23.useEffect)(() => {
3828
+ (0, import_react25.useEffect)(() => {
3466
3829
  const onKey = (e) => {
3467
3830
  if (e.key === "Escape") close();
3468
3831
  };
@@ -3473,11 +3836,11 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor }) {
3473
3836
  monitor?.setActiveTab("chat");
3474
3837
  send(text);
3475
3838
  };
3476
- (0, import_react23.useEffect)(() => {
3839
+ (0, import_react25.useEffect)(() => {
3477
3840
  if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
3478
3841
  }, [monitor, state.isStreaming, state.messages.length]);
3479
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
3480
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3842
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "ss-w-panel", role: "dialog", "aria-modal": isModal, "aria-label": ui.chatDialogLabel, children: [
3843
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3481
3844
  ChatHeader,
3482
3845
  {
3483
3846
  onClose: close,
@@ -3490,25 +3853,28 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor }) {
3490
3853
  moreOptionsLabel: ui.moreOptions
3491
3854
  }
3492
3855
  ),
3493
- monitor && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3856
+ monitor && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3494
3857
  TabBar,
3495
3858
  {
3496
3859
  monitor,
3497
3860
  ui,
3498
3861
  matchCount: monitor.pins.filter((p) => p.kind === "match").length,
3499
- oddsCount: monitor.pins.filter((p) => p.kind !== "match").length
3862
+ oddsCount: monitor.pins.filter((p) => p.kind !== "match").length,
3863
+ todayCount: discovery?.liveCount ?? 0,
3864
+ hasToday: (discovery?.groups.length ?? 0) > 0
3500
3865
  }
3501
3866
  ),
3502
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3867
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
3503
3868
  "div",
3504
3869
  {
3505
3870
  style: !monitor || monitor.activeTab === "chat" ? { display: "contents" } : { position: "absolute", inset: 0, visibility: "hidden", display: "flex", flexDirection: "column" },
3506
- children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(MessageList, { controller, ui, slip, onDashboardTap, monitor })
3871
+ children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(MessageList, { controller, ui, slip, onDashboardTap, monitor })
3507
3872
  }
3508
3873
  ),
3509
- monitor && monitor.activeTab === "matches" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(MatchesPanel, { monitor, ui, slip }),
3510
- monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(OddsPanel, { monitor, ui, slip }),
3511
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: handleSend, onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
3874
+ monitor && discovery && monitor.activeTab === "today" && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(TodayPanel, { discovery, ui, monitor }),
3875
+ monitor && monitor.activeTab === "following" && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(MatchesPanel, { monitor, ui, slip }),
3876
+ monitor && monitor.activeTab === "odds" && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(OddsPanel, { monitor, ui, slip }),
3877
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(ChatInput, { placeholder: ui.placeholder, streaming: state.isStreaming, onSend: handleSend, onStop: stop, stopLabel: ui.stopResponse, sendLabel: ui.sendMessage })
3512
3878
  ] });
3513
3879
  }
3514
3880
 
@@ -4245,8 +4611,9 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
4245
4611
  .ss-w-fandash-live-legend-swatch--away { background: var(--ss-w-away); }
4246
4612
 
4247
4613
  /* live monitor tab bar: underline pattern mirrors .ss-w-ecard-scope; the unread dot uses --ss-w-neg */
4248
- .ss-w-tabs { display: flex; align-items: stretch; gap: 2px; border-bottom: 1px solid var(--ss-w-line); }
4249
- .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; }
4614
+ .ss-w-tabs { display: flex; align-items: stretch; gap: 2px; border-bottom: 1px solid var(--ss-w-line); overflow-x: auto; scrollbar-width: none; }
4615
+ .ss-w-tabs::-webkit-scrollbar { display: none; }
4616
+ .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; flex: none; white-space: nowrap; }
4250
4617
  .ss-w-tab[data-on] { color: var(--ss-w-ink); border-bottom-color: var(--ss-w-accent); }
4251
4618
  .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; }
4252
4619
  .ss-w-tab[data-on] .ss-w-tab-count { color: var(--ss-w-accent); }
@@ -4335,10 +4702,41 @@ var WIDGET_CSS = `.ss-w-root { all: revert; }
4335
4702
  .ss-w-acc-panel { padding: 0 11px 10px; display: flex; flex-direction: column; gap: 8px; }
4336
4703
  .ss-w-acc-insight { font-size: 12px; color: var(--ss-w-ink); background: color-mix(in srgb, var(--ss-w-accent) 9%, var(--ss-w-panel)); border-radius: 8px; padding: 7px 9px; }
4337
4704
  .ss-w-acc-retry { font-size: 12px; color: var(--ss-w-neg); cursor: pointer; padding: 6px 0; }
4705
+
4706
+ /* ---- Today tab (u355) ---- */
4707
+ .ss-w-sec-head { display: flex; align-items: center; gap: 7px; padding: 2px 2px 0; font-size: 10px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--ss-w-faint); }
4708
+ .ss-w-sec-head::after { content: ""; flex: 1; height: 1px; background: var(--ss-w-line); }
4709
+ .ss-w-sec-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ss-w-neg); flex: none; }
4710
+ .ss-w-today-live { display: flex; flex-direction: column; gap: 2px; }
4711
+
4712
+ .ss-w-grp { border: 1px solid var(--ss-w-line); border-radius: 12px; overflow: hidden; }
4713
+ .ss-w-grp-head { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 11px; background: var(--ss-w-bubble); border: none; font: inherit; color: var(--ss-w-ink); cursor: pointer; text-align: left; }
4714
+ .ss-w-grp-head:focus-visible { outline: 2px solid var(--ss-w-accent); outline-offset: -2px; }
4715
+ .ss-w-grp-chev { color: var(--ss-w-faint); font-size: 10px; flex: none; }
4716
+ .ss-w-grp-name { font-size: 12px; font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
4717
+ .ss-w-grp-count { margin-left: auto; flex: none; font-size: 10.5px; font-weight: 700; color: var(--ss-w-faint); background: var(--ss-w-panel); border: 1px solid var(--ss-w-line); border-radius: 999px; padding: 1px 7px; font-variant-numeric: tabular-nums; }
4718
+ .ss-w-grp-body { display: flex; flex-direction: column; padding: 2px 11px 6px; }
4719
+
4720
+ .ss-w-drow { display: grid; grid-template-columns: 42px minmax(0,1fr) auto 22px; align-items: center; gap: 9px; padding: 7px 0; border-bottom: 1px solid var(--ss-w-line); }
4721
+ .ss-w-drow:last-child { border-bottom: none; }
4722
+ .ss-w-drow-when { font-size: 11px; font-weight: 700; color: var(--ss-w-faint); font-variant-numeric: tabular-nums; }
4723
+ .ss-w-drow-when--live { color: var(--ss-w-neg); }
4724
+ /* Each side ellipsises independently: a single joined string truncates the away team off the end,
4725
+ which is the u350 betting-card truncation one layer down. */
4726
+ .ss-w-drow-fx { display: flex; align-items: center; gap: 6px; min-width: 0; }
4727
+ .ss-w-drow-side { display: flex; align-items: center; gap: 5px; min-width: 0; flex: 1 1 0; }
4728
+ .ss-w-drow-nm { font-size: 12.5px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
4729
+ .ss-w-drow-dash { flex: none; color: var(--ss-w-faint); font-size: 11px; }
4730
+ .ss-w-drow-sc { font-size: 12.5px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ss-w-ink); }
4731
+ .ss-w-drow-sc--idle { color: var(--ss-w-faint); font-weight: 600; }
4732
+ .ss-w-drow--live { background: color-mix(in srgb, var(--ss-w-neg) 5%, transparent); border-radius: 8px; padding: 7px 6px; margin: 0 -6px; border-bottom: none; }
4733
+ .ss-w-drow-crest { width: 16px; height: 16px; flex: none; border-radius: 50%; object-fit: contain; background: var(--ss-w-bubble); }
4734
+
4735
+ .ss-w-stale { font-size: 11px; font-weight: 600; color: var(--ss-w-cta); background: color-mix(in srgb, var(--ss-w-cta) 12%, var(--ss-w-panel)); border-radius: 8px; padding: 6px 9px; }
4338
4736
  `;
4339
4737
 
4340
4738
  // src/StatsWidget.tsx
4341
- var import_jsx_runtime50 = require("react/jsx-runtime");
4739
+ var import_jsx_runtime53 = require("react/jsx-runtime");
4342
4740
  function buildClient(props) {
4343
4741
  try {
4344
4742
  if ("client" in props && props.client) {
@@ -4363,22 +4761,61 @@ function injectStyles(root) {
4363
4761
  function StatsWidget(props) {
4364
4762
  const injectedClient = "client" in props ? props.client : void 0;
4365
4763
  const cfg = props.config;
4366
- const built = (0, import_react24.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
4367
- const ui = (0, import_react24.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
4368
- const rootRef = (0, import_react24.useRef)(null);
4369
- const introDoneRef = (0, import_react24.useRef)(false);
4370
- const markIntroDone = (0, import_react24.useCallback)(() => {
4764
+ const built = (0, import_react26.useMemo)(() => buildClient(props), [injectedClient, cfg?.operatorId, cfg?.publicKey, cfg?.baseUrl]);
4765
+ const logger = (0, import_react26.useMemo)(
4766
+ () => built ? built.client.createEventLogger({
4767
+ operatorUserId: cfg?.userContext?.operatorUserId,
4768
+ anonymousUserId: cfg?.userContext?.anonymousUserId
4769
+ }) : null,
4770
+ [built?.client]
4771
+ );
4772
+ const ui = (0, import_react26.useMemo)(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
4773
+ const rootRef = (0, import_react26.useRef)(null);
4774
+ const introDoneRef = (0, import_react26.useRef)(false);
4775
+ const markIntroDone = (0, import_react26.useCallback)(() => {
4371
4776
  introDoneRef.current = true;
4372
4777
  }, []);
4373
4778
  const convStorageKey = `ss-w-conv:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`;
4374
4779
  const controller = useChatStream(built?.conversation ?? emptyConversation(), ui.starters, built ? ui.greetingMessage : void 0, convStorageKey);
4780
+ const [hasToday, setHasToday] = (0, import_react26.useState)(false);
4375
4781
  const monitor = useLiveMonitor({
4376
4782
  getLiveMonitor: (pins) => built ? built.conversation.getLiveMonitor(pins) : Promise.resolve(null),
4377
4783
  getMarketOdds: (matchId, dev) => built ? built.conversation.getMarketOdds(matchId, dev) : Promise.resolve(null),
4378
4784
  storageKey: `ss-w-pins:${cfg?.operatorId ?? ""}:${cfg?.userContext?.operatorUserId ?? "anon"}`,
4379
- isOpen: controller.state.isOpen
4785
+ isOpen: controller.state.isOpen,
4786
+ hasToday
4787
+ });
4788
+ const getSchedule = (0, import_react26.useCallback)(
4789
+ (localDate, utcOffsetMinutes) => built ? built.conversation.getSchedule(localDate, utcOffsetMinutes) : Promise.resolve(null),
4790
+ [built]
4791
+ );
4792
+ const getStates = (0, import_react26.useCallback)(
4793
+ (matchIds) => built ? built.conversation.getStates(matchIds) : Promise.resolve(null),
4794
+ [built]
4795
+ );
4796
+ const pinnedMatchIds = (0, import_react26.useMemo)(
4797
+ () => monitor.pins.filter((p) => p.kind === "match").map((p) => p.matchId),
4798
+ [monitor.pins]
4799
+ );
4800
+ const discovery = useMatchDiscovery({
4801
+ getSchedule,
4802
+ getStates,
4803
+ operatorId: cfg?.operatorId ?? "",
4804
+ isOpen: controller.state.isOpen,
4805
+ pinnedMatchIds
4380
4806
  });
4381
- const slip = (0, import_react24.useMemo)(
4807
+ const todayHasContent = discovery.groups.length > 0;
4808
+ (0, import_react26.useEffect)(() => {
4809
+ setHasToday(todayHasContent);
4810
+ }, [todayHasContent]);
4811
+ const markTodayActivity = monitor.markTodayActivity;
4812
+ const prevLiveCountRef = (0, import_react26.useRef)(0);
4813
+ (0, import_react26.useEffect)(() => {
4814
+ const rose = prevLiveCountRef.current === 0 && discovery.liveCount > 0;
4815
+ prevLiveCountRef.current = discovery.liveCount;
4816
+ if (rose) markTodayActivity();
4817
+ }, [discovery.liveCount, markTodayActivity]);
4818
+ const slip = (0, import_react26.useMemo)(
4382
4819
  () => {
4383
4820
  const handler = props.config?.onAddToSlip;
4384
4821
  return {
@@ -4401,18 +4838,42 @@ function StatsWidget(props) {
4401
4838
  },
4402
4839
  [props.config?.onAddToSlip, controller.state.conversationId, built, monitor.markInSlip]
4403
4840
  );
4404
- const onDashboardTap = (0, import_react24.useMemo)(
4405
- () => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input)) : void 0,
4406
- [built]
4841
+ const onDashboardTap = (0, import_react26.useMemo)(
4842
+ () => built ? createDashboardTapSignal((input) => built.conversation.sendSignal(input), logger) : void 0,
4843
+ [built, logger]
4407
4844
  );
4408
- (0, import_react24.useEffect)(() => {
4845
+ const operatorUserId = cfg?.userContext?.operatorUserId;
4846
+ const anonymousUserId = cfg?.userContext?.anonymousUserId;
4847
+ const conversationId = controller.state.conversationId ?? void 0;
4848
+ (0, import_react26.useEffect)(() => {
4849
+ if (!logger) return;
4850
+ logger.setIdentity({ operatorUserId, anonymousUserId, conversationId });
4851
+ }, [logger, operatorUserId, anonymousUserId, conversationId]);
4852
+ (0, import_react26.useEffect)(() => {
4853
+ if (!logger) return;
4854
+ const onHide = () => {
4855
+ logger.flushOnHide();
4856
+ };
4857
+ const onVisibilityHide = () => {
4858
+ if (document.visibilityState === "hidden") logger.flushOnHide();
4859
+ };
4860
+ window.addEventListener("pagehide", onHide);
4861
+ document.addEventListener("visibilitychange", onVisibilityHide);
4862
+ return () => {
4863
+ window.removeEventListener("pagehide", onHide);
4864
+ document.removeEventListener("visibilitychange", onVisibilityHide);
4865
+ logger.flushOnHide();
4866
+ logger.dispose();
4867
+ };
4868
+ }, [logger]);
4869
+ (0, import_react26.useEffect)(() => {
4409
4870
  if (!built || !ui.injectStyles) return;
4410
4871
  const node = rootRef.current?.getRootNode();
4411
4872
  if (node) injectStyles(node);
4412
4873
  }, [built, ui.injectStyles]);
4413
4874
  if (!built) return null;
4414
4875
  const attrs = themeAttrs(ui);
4415
- return /* @__PURE__ */ (0, import_jsx_runtime50.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_runtime50.jsx)(ChatPanel, { controller, ui, slip, onDashboardTap, monitor: monitor.enabled ? monitor : void 0 }) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
4876
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(EventLogContext.Provider, { value: logger, children: /* @__PURE__ */ (0, import_jsx_runtime53.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_runtime53.jsx)(ChatPanel, { controller, ui, slip, onDashboardTap, monitor: monitor.enabled ? monitor : void 0, discovery }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
4416
4877
  ChatFab,
4417
4878
  {
4418
4879
  label: ui.launcherLabel,
@@ -4425,7 +4886,7 @@ function StatsWidget(props) {
4425
4886
  introAllowed: !introDoneRef.current,
4426
4887
  onIntroStart: markIntroDone
4427
4888
  }
4428
- ) });
4889
+ ) }) });
4429
4890
  }
4430
4891
  function emptyConversation() {
4431
4892
  return { send: () => {