@sensiblestats/widget-react 0.77.0 → 0.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/StatsWidget.tsx
2
- import { useCallback as useCallback14, useEffect as useEffect26, useMemo as useMemo5, useRef as useRef22, useState as useState44 } from "react";
2
+ import { useCallback as useCallback14, useEffect as useEffect27, useMemo as useMemo5, useRef as useRef23, useState as useState44 } from "react";
3
3
  import { StatsWidgetClient } from "@sensiblestats/widget-sdk";
4
4
 
5
5
  // src/kickoff.ts
@@ -3106,8 +3106,23 @@ function usePopupTelemetry(log, isOpen, popupText, dismissPopup) {
3106
3106
  }, [log, dismissPopup]);
3107
3107
  }
3108
3108
 
3109
+ // src/openTelemetry.ts
3110
+ import { useEffect as useEffect10, useRef as useRef10 } from "react";
3111
+ function useOpenTelemetry(log, isOpen) {
3112
+ const openLoggedRef = useRef10(false);
3113
+ useEffect10(() => {
3114
+ if (!isOpen) {
3115
+ openLoggedRef.current = false;
3116
+ return;
3117
+ }
3118
+ if (openLoggedRef.current || !log) return;
3119
+ openLoggedRef.current = true;
3120
+ log.log({ name: "widget_open" });
3121
+ }, [log, isOpen]);
3122
+ }
3123
+
3109
3124
  // src/components/ChatFab.tsx
3110
- import { useEffect as useEffect10, useRef as useRef10, useState as useState9 } from "react";
3125
+ import { useEffect as useEffect11, useRef as useRef11, useState as useState9 } from "react";
3111
3126
 
3112
3127
  // src/components/BrandMark.tsx
3113
3128
  import { useState as useState8 } from "react";
@@ -3210,8 +3225,8 @@ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
3210
3225
  function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup, dismissLabel = "Dismiss", introAllowed = false, onIntroStart, asks }) {
3211
3226
  const bubble = popupText ?? greeting;
3212
3227
  const [intro, setIntro] = useState9(false);
3213
- const armedRef = useRef10(introAllowed);
3214
- useEffect10(() => {
3228
+ const armedRef = useRef11(introAllowed);
3229
+ useEffect11(() => {
3215
3230
  if (armedRef.current && bubble) {
3216
3231
  armedRef.current = false;
3217
3232
  setIntro(true);
@@ -3225,10 +3240,10 @@ function ChatFab({ label, greeting, popupText, logoUrl, onOpen, onDismissPopup,
3225
3240
  }
3226
3241
 
3227
3242
  // src/components/ChatPanel.tsx
3228
- import { useCallback as useCallback13, useEffect as useEffect25, useMemo as useMemo4, useRef as useRef21, useState as useState43 } from "react";
3243
+ import { useCallback as useCallback13, useEffect as useEffect26, useMemo as useMemo4, useRef as useRef22, useState as useState43 } from "react";
3229
3244
 
3230
3245
  // src/components/ChatHeader.tsx
3231
- import { useEffect as useEffect11, useRef as useRef11, useState as useState10 } from "react";
3246
+ import { useEffect as useEffect12, useRef as useRef12, useState as useState10 } from "react";
3232
3247
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
3233
3248
  function ChatHeader({
3234
3249
  onClose,
@@ -3241,14 +3256,14 @@ function ChatHeader({
3241
3256
  moreOptionsLabel = "More options"
3242
3257
  }) {
3243
3258
  const [menuOpen, setMenuOpen] = useState10(false);
3244
- const wrapRef = useRef11(null);
3245
- const kebabRef = useRef11(null);
3246
- const firstItemRef = useRef11(null);
3259
+ const wrapRef = useRef12(null);
3260
+ const kebabRef = useRef12(null);
3261
+ const firstItemRef = useRef12(null);
3247
3262
  const hasMenu = !!(canReset && onNewConversation);
3248
- useEffect11(() => {
3263
+ useEffect12(() => {
3249
3264
  if (menuOpen) firstItemRef.current?.focus();
3250
3265
  }, [menuOpen]);
3251
- useEffect11(() => {
3266
+ useEffect12(() => {
3252
3267
  if (!menuOpen) return;
3253
3268
  const onPointer = (e) => {
3254
3269
  if (!wrapRef.current?.contains(e.target)) setMenuOpen(false);
@@ -3304,7 +3319,7 @@ function ChatHeader({
3304
3319
  }
3305
3320
 
3306
3321
  // src/components/MessageList.tsx
3307
- import { useEffect as useEffect17, useRef as useRef14 } from "react";
3322
+ import { useEffect as useEffect18, useRef as useRef15 } from "react";
3308
3323
 
3309
3324
  // src/components/Markdown.tsx
3310
3325
  import ReactMarkdown from "react-markdown";
@@ -3442,11 +3457,11 @@ function useSlipState() {
3442
3457
  }
3443
3458
 
3444
3459
  // src/components/Toast.tsx
3445
- import { useEffect as useEffect12 } from "react";
3460
+ import { useEffect as useEffect13 } from "react";
3446
3461
  import { jsx as jsx8 } from "react/jsx-runtime";
3447
3462
  var DISMISS_MS = 4e3;
3448
3463
  function Toast({ toast, onDismiss }) {
3449
- useEffect12(() => {
3464
+ useEffect13(() => {
3450
3465
  if (!toast) return;
3451
3466
  const timer = setTimeout(onDismiss, DISMISS_MS);
3452
3467
  return () => clearTimeout(timer);
@@ -3845,7 +3860,7 @@ function ComboCardList({ cards, ui, slip, monitor }) {
3845
3860
  }
3846
3861
 
3847
3862
  // src/components/MarketOddsCardList.tsx
3848
- import { useEffect as useEffect13, useState as useState16 } from "react";
3863
+ import { useEffect as useEffect14, useState as useState16 } from "react";
3849
3864
 
3850
3865
  // src/components/AllMarketsButton.tsx
3851
3866
  import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
@@ -3920,7 +3935,7 @@ function MarketOddsCard({ vm, ui, slip, monitor, inSlipIds, hideHeader, pinRef }
3920
3935
  const staleTime = isStale && live ? fmtHhMm(live.asOfUtc, ui?.locale ?? "en") : null;
3921
3936
  const [, setStaleTick] = useState16(0);
3922
3937
  const watchStale = live != null && !isClosed && !isStale;
3923
- useEffect13(() => {
3938
+ useEffect14(() => {
3924
3939
  if (!watchStale) return;
3925
3940
  const id = window.setTimeout(() => setStaleTick((n) => n + 1), Math.max(0, asOfMs + STALE_AFTER_MS - Date.now()) + 1);
3926
3941
  return () => window.clearTimeout(id);
@@ -3999,7 +4014,7 @@ function MarketOddsCardList({ cards, ui, slip, monitor, inSlipIds, hideHeader, p
3999
4014
  }
4000
4015
 
4001
4016
  // src/components/CompactOddsList.tsx
4002
- import { useEffect as useEffect14, useRef as useRef12, useState as useState17 } from "react";
4017
+ import { useEffect as useEffect15, useRef as useRef13, useState as useState17 } from "react";
4003
4018
 
4004
4019
  // src/compactList.ts
4005
4020
  var COMPACT_MIN_CARDS = 3;
@@ -4116,8 +4131,8 @@ function CompactOddsList({ list, ui, slip, monitor }) {
4116
4131
  const [shown, setShown] = useState17(COMPACT_PAGE);
4117
4132
  const hidden = list.rowCount - shown;
4118
4133
  const [focusIndex, setFocusIndex] = useState17(null);
4119
- const focusRef = useRef12(null);
4120
- useEffect14(() => {
4134
+ const focusRef = useRef13(null);
4135
+ useEffect15(() => {
4121
4136
  if (focusIndex !== null) focusRef.current?.focus();
4122
4137
  }, [focusIndex]);
4123
4138
  let left = shown;
@@ -4422,7 +4437,7 @@ function FixtureCard({ card }) {
4422
4437
  }
4423
4438
 
4424
4439
  // src/components/dashboard/CountdownCard.tsx
4425
- import { Fragment as Fragment6, useEffect as useEffect15, useState as useState18 } from "react";
4440
+ import { Fragment as Fragment6, useEffect as useEffect16, useState as useState18 } from "react";
4426
4441
  import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
4427
4442
  var DAY_MS = 864e5;
4428
4443
  function remainingSegments(kickoffUnix, nowMs, withSeconds) {
@@ -4446,7 +4461,7 @@ function CountdownCard({ card }) {
4446
4461
  () => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches
4447
4462
  );
4448
4463
  const withinDay = data.kickoffUnix * 1e3 - nowMs < DAY_MS;
4449
- useEffect15(() => {
4464
+ useEffect16(() => {
4450
4465
  if (reduced) return;
4451
4466
  const id = window.setInterval(() => setNowMs(Date.now()), withinDay ? 1e3 : 6e4);
4452
4467
  return () => window.clearInterval(id);
@@ -4803,10 +4818,10 @@ function RestingFormCard({ card }) {
4803
4818
  }
4804
4819
 
4805
4820
  // src/components/dashboard/LiveScoreCard.tsx
4806
- import { useRef as useRef13, useState as useState22 } from "react";
4821
+ import { useRef as useRef14, useState as useState22 } from "react";
4807
4822
 
4808
4823
  // src/useLiveClock.ts
4809
- import { useEffect as useEffect16, useState as useState21 } from "react";
4824
+ import { useEffect as useEffect17, useState as useState21 } from "react";
4810
4825
  var TICK_MS = 6e4;
4811
4826
  var MAX_LIVE_TICK_MINUTES = 15;
4812
4827
  function computeDisplayMinute(minute, clockRunning, receivedAtMs) {
@@ -4818,7 +4833,7 @@ function useLiveClock(minute, clockRunning, receivedAtMs) {
4818
4833
  const [displayMinute, setDisplayMinute] = useState21(
4819
4834
  () => computeDisplayMinute(minute, clockRunning, receivedAtMs)
4820
4835
  );
4821
- useEffect16(() => {
4836
+ useEffect17(() => {
4822
4837
  setDisplayMinute(computeDisplayMinute(minute, clockRunning, receivedAtMs));
4823
4838
  if (!clockRunning) return;
4824
4839
  const id = window.setInterval(() => {
@@ -4854,7 +4869,7 @@ function LiveScoreCard({
4854
4869
  }) {
4855
4870
  const { data } = card;
4856
4871
  const seedKey = `${data.minute}:${data.homeScore}:${data.awayScore}`;
4857
- const seedRef = useRef13(null);
4872
+ const seedRef = useRef14(null);
4858
4873
  if (!seedRef.current || seedRef.current.key !== seedKey) {
4859
4874
  seedRef.current = { key: seedKey, receivedAtMs: Date.now() };
4860
4875
  }
@@ -5178,11 +5193,11 @@ function turnAnchor(messages) {
5178
5193
  }
5179
5194
  function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
5180
5195
  const { state, send } = controller;
5181
- const listRef = useRef14(null);
5182
- const endRef = useRef14(null);
5183
- const pinnedRef = useRef14(true);
5184
- const anchoredTurnRef = useRef14(null);
5185
- useEffect17(() => {
5196
+ const listRef = useRef15(null);
5197
+ const endRef = useRef15(null);
5198
+ const pinnedRef = useRef15(true);
5199
+ const anchoredTurnRef = useRef15(null);
5200
+ useEffect18(() => {
5186
5201
  const anchor = turnAnchor(state.messages);
5187
5202
  const list = listRef.current;
5188
5203
  if (anchor && anchor.turnId !== anchoredTurnRef.current) {
@@ -5239,13 +5254,13 @@ function MessageList({ controller, ui, slip, onDashboardTap, monitor }) {
5239
5254
  }
5240
5255
 
5241
5256
  // src/components/ChatInput.tsx
5242
- import { forwardRef, useEffect as useEffect18, useImperativeHandle, useRef as useRef15, useState as useState24 } from "react";
5257
+ import { forwardRef, useEffect as useEffect19, useImperativeHandle, useRef as useRef16, useState as useState24 } from "react";
5243
5258
  import { jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
5244
5259
  var ChatInput = forwardRef(function ChatInput2({ placeholder, streaming, onSend, onStop, stopLabel = "Stop response", sendLabel = "Send message", disabled = false, onType }, ref) {
5245
5260
  const [value, setValue] = useState24("");
5246
- const textareaRef = useRef15(null);
5247
- const stopRef = useRef15(null);
5248
- const textBoxWantsFocusRef = useRef15(false);
5261
+ const textareaRef = useRef16(null);
5262
+ const stopRef = useRef16(null);
5263
+ const textBoxWantsFocusRef = useRef16(false);
5249
5264
  const submit = () => {
5250
5265
  if (disabled) return;
5251
5266
  const t = value.trim();
@@ -5271,7 +5286,7 @@ var ChatInput = forwardRef(function ChatInput2({ placeholder, streaming, onSend,
5271
5286
  stopRef.current?.focus();
5272
5287
  }
5273
5288
  }), []);
5274
- useEffect18(() => {
5289
+ useEffect19(() => {
5275
5290
  if (streaming || disabled || !textBoxWantsFocusRef.current) return;
5276
5291
  textBoxWantsFocusRef.current = false;
5277
5292
  const box = textareaRef.current;
@@ -5763,7 +5778,7 @@ function TodayPanel({ discovery, ui, monitor }) {
5763
5778
  }
5764
5779
 
5765
5780
  // src/components/GamesPanel.tsx
5766
- import { useEffect as useEffect22, useState as useState39 } from "react";
5781
+ import { useEffect as useEffect23, useState as useState39 } from "react";
5767
5782
 
5768
5783
  // src/components/GamesLoginWall.tsx
5769
5784
  import { jsx as jsx57 } from "react/jsx-runtime";
@@ -5772,7 +5787,7 @@ function GamesLoginWall({ ui }) {
5772
5787
  }
5773
5788
 
5774
5789
  // src/components/GamesHub.tsx
5775
- import { useEffect as useEffect19, useState as useState26 } from "react";
5790
+ import { useEffect as useEffect20, useState as useState26 } from "react";
5776
5791
 
5777
5792
  // src/components/games/ui/gameMeta.ts
5778
5793
  function prettifyGameId(gameId) {
@@ -5958,7 +5973,7 @@ function pickHeroGame(games) {
5958
5973
  var tileKey = (g) => `${g.gameId}-${g.gameDay}-${g.fixtureId}`;
5959
5974
  function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
5960
5975
  const [, setTick] = useState26(0);
5961
- useEffect19(() => {
5976
+ useEffect20(() => {
5962
5977
  const id = setInterval(() => setTick((t) => t + 1), 6e4);
5963
5978
  return () => clearInterval(id);
5964
5979
  }, []);
@@ -6018,10 +6033,10 @@ function GamesHub({ games, myWeeklyRow, weeklyPrize, onOpen, ui }) {
6018
6033
  }
6019
6034
 
6020
6035
  // src/components/GameScreenHost.tsx
6021
- import { useEffect as useEffect21, useRef as useRef18, useState as useState38 } from "react";
6036
+ import { useEffect as useEffect22, useRef as useRef19, useState as useState38 } from "react";
6022
6037
 
6023
6038
  // src/useGamePlay.ts
6024
- import { useCallback as useCallback11, useRef as useRef16, useState as useState27 } from "react";
6039
+ import { useCallback as useCallback11, useRef as useRef17, useState as useState27 } from "react";
6025
6040
  function toSubmitResult(payload) {
6026
6041
  return {
6027
6042
  // 'pending' means the play is recorded but awaiting resolution (fixture games)
@@ -6036,12 +6051,12 @@ function useGamePlay(conversation, { gameId, gameDay, fixtureId, locale, refresh
6036
6051
  const [result, setResult] = useState27(null);
6037
6052
  const [submitting, setSubmitting] = useState27(false);
6038
6053
  const [rawStatus, setRawStatus] = useState27(null);
6039
- const inFlightRef = useRef16(false);
6040
- const convRef = useRef16(conversation);
6054
+ const inFlightRef = useRef17(false);
6055
+ const convRef = useRef17(conversation);
6041
6056
  convRef.current = conversation;
6042
- const optsRef = useRef16({ gameId, gameDay, fixtureId, locale, refresh });
6057
+ const optsRef = useRef17({ gameId, gameDay, fixtureId, locale, refresh });
6043
6058
  optsRef.current = { gameId, gameDay, fixtureId, locale, refresh };
6044
- const resultRef = useRef16(null);
6059
+ const resultRef = useRef17(null);
6045
6060
  resultRef.current = result;
6046
6061
  const refetch = useCallback11(async () => {
6047
6062
  const conv = convRef.current;
@@ -6995,7 +7010,7 @@ function CareerPathGame({
6995
7010
  }
6996
7011
 
6997
7012
  // src/components/games/BeatTheGridGame.tsx
6998
- import React, { useEffect as useEffect20, useId as useId4, useRef as useRef17, useState as useState32 } from "react";
7013
+ import React, { useEffect as useEffect21, useId as useId4, useRef as useRef18, useState as useState32 } from "react";
6999
7014
 
7000
7015
  // src/components/games/ui/OptionList.tsx
7001
7016
  import { jsx as jsx77 } from "react/jsx-runtime";
@@ -7086,8 +7101,8 @@ function SearchSheet({
7086
7101
  const s = ui.games.beatTheGrid;
7087
7102
  const [query, setQuery] = useState32("");
7088
7103
  const inputId = useId4();
7089
- const inputRef = useRef17(null);
7090
- useEffect20(() => {
7104
+ const inputRef = useRef18(null);
7105
+ useEffect21(() => {
7091
7106
  inputRef.current?.focus();
7092
7107
  }, [row, col]);
7093
7108
  const filtered = playerPool.filter(
@@ -8391,7 +8406,7 @@ function GameScreenHost({
8391
8406
  }) {
8392
8407
  const { gameId, fixtureId, gameDay = "", lockAtUtc = null } = selected;
8393
8408
  const [configJson, setConfigJson] = useState38(null);
8394
- useEffect21(() => {
8409
+ useEffect22(() => {
8395
8410
  setConfigJson(null);
8396
8411
  if (!conversation) return;
8397
8412
  let cancelled = false;
@@ -8414,12 +8429,12 @@ function GameScreenHost({
8414
8429
  fixtureId: fixtureId || void 0,
8415
8430
  locale: ui.games.lang
8416
8431
  });
8417
- useEffect21(() => {
8432
+ useEffect22(() => {
8418
8433
  if (conversation) hydrate();
8419
8434
  }, [conversation, gameId]);
8420
- const hydrateRef = useRef18(hydrate);
8435
+ const hydrateRef = useRef19(hydrate);
8421
8436
  hydrateRef.current = hydrate;
8422
- useEffect21(() => {
8437
+ useEffect22(() => {
8423
8438
  if (!FIXTURE_GAME_IDS.has(gameId)) return;
8424
8439
  if (rawStatus !== "pending") return;
8425
8440
  const timerId = setInterval(() => {
@@ -8555,7 +8570,7 @@ function GamesPanel({
8555
8570
  refreshHub
8556
8571
  }) {
8557
8572
  const [selected, setSelected] = useState39(null);
8558
- useEffect22(() => {
8573
+ useEffect23(() => {
8559
8574
  ensureGamesFonts();
8560
8575
  }, []);
8561
8576
  if (!loggedIn) return /* @__PURE__ */ jsx87(GamesLoginWall, { ui });
@@ -8788,16 +8803,16 @@ function PresetSpeedDial({ expanded, showDot, strings, onToggle, onOpen, rootRef
8788
8803
  }
8789
8804
 
8790
8805
  // src/components/PresetTools.tsx
8791
- import { Fragment as Fragment21, useEffect as useEffect23, useId as useId10, useRef as useRef19, useState as useState41 } from "react";
8806
+ import { Fragment as Fragment21, useEffect as useEffect24, useId as useId10, useRef as useRef20, useState as useState41 } from "react";
8792
8807
  import { Fragment as Fragment22, jsx as jsx93, jsxs as jsxs78 } from "react/jsx-runtime";
8793
8808
  var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
8794
8809
  function PresetToolModal({ title, closeLabel, onClose, children, footer }) {
8795
- const dialogRef = useRef19(null);
8810
+ const dialogRef = useRef20(null);
8796
8811
  const titleId = useId10();
8797
- useEffect23(() => {
8812
+ useEffect24(() => {
8798
8813
  dialogRef.current?.focus();
8799
8814
  }, []);
8800
- useEffect23(() => {
8815
+ useEffect24(() => {
8801
8816
  const onKey = (e) => {
8802
8817
  if (e.key !== "Escape") return;
8803
8818
  e.stopPropagation();
@@ -9081,7 +9096,7 @@ function BuildComboTool({ grid, strings, streaming, formatKickoff, initialTotal,
9081
9096
  }
9082
9097
 
9083
9098
  // src/usePresetDial.ts
9084
- import { useCallback as useCallback12, useEffect as useEffect24, useRef as useRef20, useState as useState42 } from "react";
9099
+ import { useCallback as useCallback12, useEffect as useEffect25, useRef as useRef21, useState as useState42 } from "react";
9085
9100
  function sendInFlight(messages, isStreaming) {
9086
9101
  const last = messages[messages.length - 1];
9087
9102
  return isStreaming && !!last && last.role === "assistant" && !last.done && !last.isGreeting;
@@ -9099,21 +9114,21 @@ function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming
9099
9114
  const fold = useCallback12(() => setExpanded(false), []);
9100
9115
  const toggle = useCallback12(() => setExpanded((e) => !e), []);
9101
9116
  const currentUserId = lastUserId(messages);
9102
- const userIdRef = useRef20(currentUserId);
9103
- useEffect24(() => {
9117
+ const userIdRef = useRef21(currentUserId);
9118
+ useEffect25(() => {
9104
9119
  if (currentUserId === userIdRef.current) return;
9105
9120
  userIdRef.current = currentUserId;
9106
9121
  setExpanded(false);
9107
9122
  }, [currentUserId]);
9108
- const tabRef = useRef20(activeTab);
9109
- useEffect24(() => {
9123
+ const tabRef = useRef21(activeTab);
9124
+ useEffect25(() => {
9110
9125
  if (activeTab === tabRef.current) return;
9111
9126
  tabRef.current = activeTab;
9112
9127
  setExpanded(false);
9113
9128
  }, [activeTab]);
9114
- const expandedRef = useRef20(expanded);
9129
+ const expandedRef = useRef21(expanded);
9115
9130
  expandedRef.current = expanded;
9116
- useEffect24(() => {
9131
+ useEffect25(() => {
9117
9132
  const onEscape = (e) => {
9118
9133
  const dial = dialRef.current;
9119
9134
  if (e.key !== "Escape" || !dial || !e.composedPath().includes(dial)) return;
@@ -9126,7 +9141,7 @@ function usePresetDial({ layerRef, dialRef, dialButtonRef, messages, isStreaming
9126
9141
  window.addEventListener("keydown", onEscape, true);
9127
9142
  return () => window.removeEventListener("keydown", onEscape, true);
9128
9143
  }, [dialRef, dialButtonRef]);
9129
- useEffect24(() => {
9144
+ useEffect25(() => {
9130
9145
  if (!expanded) return;
9131
9146
  const layer = layerRef.current;
9132
9147
  const inDial = (e) => {
@@ -9182,7 +9197,7 @@ import { jsx as jsx94, jsxs as jsxs79 } from "react/jsx-runtime";
9182
9197
  var FULLSCREEN_QUERY = "(max-width: 639px)";
9183
9198
  function useIsModal() {
9184
9199
  const [modal, setModal] = useState43(false);
9185
- useEffect25(() => {
9200
+ useEffect26(() => {
9186
9201
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
9187
9202
  const mql = window.matchMedia(FULLSCREEN_QUERY);
9188
9203
  const sync = () => setModal(mql.matches);
@@ -9196,7 +9211,7 @@ var HIDDEN_LAYER_STYLE = { position: "absolute", inset: 0, visibility: "hidden",
9196
9211
  function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, gamesResult, leaderboardResult, loggedIn, conversation, presetGrid }) {
9197
9212
  const { state, close, stop, send, reset } = controller;
9198
9213
  const isModal = useIsModal();
9199
- useEffect25(() => {
9214
+ useEffect26(() => {
9200
9215
  const onKey = (e) => {
9201
9216
  if (e.key === "Escape") close();
9202
9217
  };
@@ -9211,15 +9226,15 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9211
9226
  monitor?.setActiveTab("chat");
9212
9227
  send(text, { grounding });
9213
9228
  };
9214
- useEffect25(() => {
9229
+ useEffect26(() => {
9215
9230
  if (monitor && monitor.activeTab !== "chat" && state.isStreaming) monitor.markChatActivity();
9216
9231
  }, [monitor, state.isStreaming, state.messages.length]);
9217
9232
  const onChatTab = !monitor || monitor.activeTab === "chat";
9218
- const layerRef = useRef21(null);
9219
- const dialRef = useRef21(null);
9220
- const dialButtonRef = useRef21(null);
9221
- const inputRef = useRef21(null);
9222
- const focusAfterCloseRef = useRef21(null);
9233
+ const layerRef = useRef22(null);
9234
+ const dialRef = useRef22(null);
9235
+ const dialButtonRef = useRef22(null);
9236
+ const inputRef = useRef22(null);
9237
+ const focusAfterCloseRef = useRef22(null);
9223
9238
  const [tool, setTool] = useState43(null);
9224
9239
  const [toolSeen, setToolSeen] = useState43(readToolSeen);
9225
9240
  const dial = usePresetDial({
@@ -9257,14 +9272,14 @@ function ChatPanel({ controller, ui, slip, onDashboardTap, monitor, discovery, g
9257
9272
  const k = ui.bettingKickoff(kickoffUtc);
9258
9273
  return `${k.dayLabel} ${k.time}`;
9259
9274
  }, [ui]);
9260
- useEffect25(() => {
9275
+ useEffect26(() => {
9261
9276
  if (tool) return;
9262
9277
  const target = focusAfterCloseRef.current;
9263
9278
  focusAfterCloseRef.current = null;
9264
9279
  if (target === "dial") dialButtonRef.current?.focus();
9265
9280
  else if (target === "composer") inputRef.current?.focus();
9266
9281
  }, [tool]);
9267
- useEffect25(() => {
9282
+ useEffect26(() => {
9268
9283
  if (!tool || onChatTab && presetGrid) return;
9269
9284
  focusAfterCloseRef.current = "composer";
9270
9285
  setTool(null);
@@ -11071,8 +11086,8 @@ function StatsWidget(props) {
11071
11086
  [built?.client]
11072
11087
  );
11073
11088
  const ui = useMemo5(() => normalizeUi(props.config ?? { operatorId: "", publicKey: "" }), [props.config]);
11074
- const rootRef = useRef22(null);
11075
- const introDoneRef = useRef22(false);
11089
+ const rootRef = useRef23(null);
11090
+ const introDoneRef = useRef23(false);
11076
11091
  const markIntroDone = useCallback14(() => {
11077
11092
  introDoneRef.current = true;
11078
11093
  }, []);
@@ -11121,11 +11136,11 @@ function StatsWidget(props) {
11121
11136
  pinnedMatchIds
11122
11137
  });
11123
11138
  const todayHasContent = visibleGroupsOf(discovery.groups, discovery.states).length > 0;
11124
- useEffect26(() => {
11139
+ useEffect27(() => {
11125
11140
  setHasToday(todayHasContent);
11126
11141
  }, [todayHasContent]);
11127
- const prevLiveSnapshotRef = useRef22(monitor.snapshot);
11128
- useEffect26(() => {
11142
+ const prevLiveSnapshotRef = useRef23(monitor.snapshot);
11143
+ useEffect27(() => {
11129
11144
  const snap = monitor.snapshot;
11130
11145
  if (!snap || snap === prevLiveSnapshotRef.current) return;
11131
11146
  prevLiveSnapshotRef.current = snap;
@@ -11167,8 +11182,8 @@ function StatsWidget(props) {
11167
11182
  );
11168
11183
  const presetGrid = usePresetGrid({ getPricePresets, isOpen: controller.state.isOpen, locale: ui.presets.lang });
11169
11184
  const markTodayActivity = monitor.markTodayActivity;
11170
- const prevLiveCountRef = useRef22(0);
11171
- useEffect26(() => {
11185
+ const prevLiveCountRef = useRef23(0);
11186
+ useEffect27(() => {
11172
11187
  const rose = prevLiveCountRef.current === 0 && discovery.liveCount > 0;
11173
11188
  prevLiveCountRef.current = discovery.liveCount;
11174
11189
  if (rose) markTodayActivity();
@@ -11206,6 +11221,7 @@ function StatsWidget(props) {
11206
11221
  [built, logger]
11207
11222
  );
11208
11223
  const dismissPopup = usePopupTelemetry(logger, controller.state.isOpen, controller.state.popupText, controller.dismissPopup);
11224
+ useOpenTelemetry(logger, controller.state.isOpen);
11209
11225
  const asks = bubbleAsks(controller.state.messages, ui.presets.standoutAsk).map((ask) => ({
11210
11226
  label: ask.label,
11211
11227
  onTap: () => runBubbleAsk(ask, {
@@ -11219,11 +11235,11 @@ function StatsWidget(props) {
11219
11235
  const operatorUserId = cfg?.userContext?.operatorUserId;
11220
11236
  const anonymousUserId = cfg?.userContext?.anonymousUserId;
11221
11237
  const conversationId = controller.state.conversationId ?? void 0;
11222
- useEffect26(() => {
11238
+ useEffect27(() => {
11223
11239
  if (!logger) return;
11224
11240
  logger.setIdentity({ operatorUserId, anonymousUserId, conversationId });
11225
11241
  }, [logger, operatorUserId, anonymousUserId, conversationId]);
11226
- useEffect26(() => {
11242
+ useEffect27(() => {
11227
11243
  if (!logger) return;
11228
11244
  logger.resume();
11229
11245
  const onHide = () => {
@@ -11241,7 +11257,7 @@ function StatsWidget(props) {
11241
11257
  logger.dispose();
11242
11258
  };
11243
11259
  }, [logger]);
11244
- useEffect26(() => {
11260
+ useEffect27(() => {
11245
11261
  if (!built || !ui.injectStyles) return;
11246
11262
  const node = rootRef.current?.getRootNode();
11247
11263
  if (node) injectStyles(node);