@camstack/ui-library 1.2.182 → 1.2.183
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/composites/stream-debug/stream-debug-overlay.d.ts +10 -0
- package/dist/index.cjs +56 -46
- package/dist/index.js +56 -46
- package/package.json +1 -1
|
@@ -17,6 +17,16 @@ import { WebrtcDebugStats } from './webrtc-debug-stats.js';
|
|
|
17
17
|
* (D393). In a tool whose whole job is telling a stalled decoder from a
|
|
18
18
|
* stalled transport, "nobody measured" and "measured nothing" are
|
|
19
19
|
* opposite conclusions.
|
|
20
|
+
* 4. It must not cover the picture, or the operator turns it off and the tool
|
|
21
|
+
* is worth nothing. So it is a one-line PILL by default — the verdict and
|
|
22
|
+
* the three numbers that carry it — and the full panel only when asked.
|
|
23
|
+
* Collapsed it is small enough to live alongside the app's own overlays
|
|
24
|
+
* (the audio meter, the box layer), which the operator positions freely
|
|
25
|
+
* and which this used to sit on top of.
|
|
26
|
+
*
|
|
27
|
+
* Density follows from the same rule: a cumulative counter and its window
|
|
28
|
+
* share ONE row (`12345 +30`), because two rows saying almost the same thing
|
|
29
|
+
* is how a panel grows until it covers the video it is describing.
|
|
20
30
|
*/
|
|
21
31
|
export interface StreamDebugOverlayProps {
|
|
22
32
|
/** The client half. Null before the first successful poll. */
|
package/dist/index.cjs
CHANGED
|
@@ -27236,15 +27236,21 @@ var VERDICT_CLASS = {
|
|
|
27236
27236
|
"transport-stall": "bg-rose-500/30 text-rose-100",
|
|
27237
27237
|
"frozen-unknown": "bg-white/15 text-white/70"
|
|
27238
27238
|
};
|
|
27239
|
-
function Row({ label, value, strong = false }) {
|
|
27239
|
+
function Row({ label, value, window, strong = false }) {
|
|
27240
27240
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
27241
|
-
className: "flex items-baseline justify-between gap-
|
|
27241
|
+
className: "flex items-baseline justify-between gap-2 leading-[1.25]",
|
|
27242
27242
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
27243
27243
|
className: "text-white/55 shrink-0",
|
|
27244
27244
|
children: label
|
|
27245
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
27246
|
-
className:
|
|
27247
|
-
children:
|
|
27245
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
27246
|
+
className: "flex items-baseline gap-1 text-right",
|
|
27247
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
27248
|
+
className: strong ? "text-white font-semibold tabular-nums" : "text-white/90 tabular-nums",
|
|
27249
|
+
children: value
|
|
27250
|
+
}), window !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
27251
|
+
className: "text-sky-300/80 tabular-nums",
|
|
27252
|
+
children: window
|
|
27253
|
+
})]
|
|
27248
27254
|
})]
|
|
27249
27255
|
});
|
|
27250
27256
|
}
|
|
@@ -27261,16 +27267,45 @@ function SectionHeader({ title, measuredAt, now }) {
|
|
|
27261
27267
|
})]
|
|
27262
27268
|
});
|
|
27263
27269
|
}
|
|
27270
|
+
/** The pill's dot: the verdict, in the one place that is always visible. */
|
|
27271
|
+
var VERDICT_DOT = {
|
|
27272
|
+
unknown: "bg-white/50",
|
|
27273
|
+
decoding: "bg-emerald-400",
|
|
27274
|
+
"decoder-stall": "bg-amber-400",
|
|
27275
|
+
"transport-stall": "bg-rose-400",
|
|
27276
|
+
"frozen-unknown": "bg-white/50"
|
|
27277
|
+
};
|
|
27264
27278
|
function StreamDebugOverlay(props) {
|
|
27265
27279
|
const { stats, server, serverError, serverWired, now, sessionId } = props;
|
|
27266
27280
|
const verdict = freezeVerdict(stats);
|
|
27267
27281
|
const win = stats?.window;
|
|
27282
|
+
const [expanded, setExpanded] = (0, react$1.useState)(false);
|
|
27283
|
+
const stale = stats !== null && now - stats.at > STALE_AFTER_MS;
|
|
27284
|
+
if (!expanded) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
27285
|
+
type: "button",
|
|
27286
|
+
onClick: () => setExpanded(true),
|
|
27287
|
+
className: "absolute bottom-10 left-2 z-20 transform-gpu flex items-center gap-1.5 rounded bg-neutral-950/90 ring-1 ring-white/20 px-1.5 py-0.5 text-[9px] font-mono text-white/85 tabular-nums select-text",
|
|
27288
|
+
"data-testid": "stream-debug-pill",
|
|
27289
|
+
title: verdict.label,
|
|
27290
|
+
children: [
|
|
27291
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: `h-1.5 w-1.5 rounded-full ${VERDICT_DOT[verdict.kind]}` }),
|
|
27292
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: stats?.width !== null && stats?.width !== void 0 ? `${stats.width}×${stats.height}` : UNKNOWN }),
|
|
27293
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [n(stats?.fps), "fps"] }),
|
|
27294
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [n(win?.kbps), "k"] }),
|
|
27295
|
+
stale && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
27296
|
+
className: "text-amber-300",
|
|
27297
|
+
children: "stale"
|
|
27298
|
+
})
|
|
27299
|
+
]
|
|
27300
|
+
});
|
|
27268
27301
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
27269
|
-
className: "absolute
|
|
27302
|
+
className: "absolute bottom-10 left-2 z-20 transform-gpu w-[13.5rem] max-h-[70%] overflow-y-auto rounded-md bg-neutral-950/95 ring-1 ring-white/25 shadow-lg px-1.5 py-1 text-[9px] font-mono text-white/90 select-text",
|
|
27270
27303
|
"data-testid": "stream-debug-overlay",
|
|
27271
27304
|
children: [
|
|
27272
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
27273
|
-
|
|
27305
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
27306
|
+
type: "button",
|
|
27307
|
+
onClick: () => setExpanded(false),
|
|
27308
|
+
className: `w-full text-left rounded px-1.5 py-0.5 mb-1 text-[9px] font-semibold ${VERDICT_CLASS[verdict.kind]}`,
|
|
27274
27309
|
children: verdict.label
|
|
27275
27310
|
}),
|
|
27276
27311
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SectionHeader, {
|
|
@@ -27281,11 +27316,7 @@ function StreamDebugOverlay(props) {
|
|
|
27281
27316
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27282
27317
|
label: "framesDecoded",
|
|
27283
27318
|
value: n(stats?.framesDecoded),
|
|
27284
|
-
|
|
27285
|
-
}),
|
|
27286
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27287
|
-
label: "· this window",
|
|
27288
|
-
value: n(win?.framesDecoded),
|
|
27319
|
+
window: win?.framesDecoded === null ? void 0 : `+${n(win?.framesDecoded)}`,
|
|
27289
27320
|
strong: true
|
|
27290
27321
|
}),
|
|
27291
27322
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
@@ -27294,40 +27325,28 @@ function StreamDebugOverlay(props) {
|
|
|
27294
27325
|
strong: true
|
|
27295
27326
|
}),
|
|
27296
27327
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27297
|
-
label: "
|
|
27328
|
+
label: "frozen",
|
|
27298
27329
|
value: n(stats?.totalFreezeMs, { suffix: "ms" }),
|
|
27330
|
+
window: win?.freezeMs === null ? void 0 : `+${n(win?.freezeMs)}ms`,
|
|
27299
27331
|
strong: true
|
|
27300
27332
|
}),
|
|
27301
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27302
|
-
label: "· this window",
|
|
27303
|
-
value: n(win?.freezeMs, { suffix: "ms" })
|
|
27304
|
-
}),
|
|
27305
27333
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27306
27334
|
label: "pliCount",
|
|
27307
27335
|
value: n(stats?.pliCount),
|
|
27336
|
+
window: win?.pliCount === null ? void 0 : `+${n(win?.pliCount)}`,
|
|
27308
27337
|
strong: true
|
|
27309
27338
|
}),
|
|
27310
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27311
|
-
label: "· this window",
|
|
27312
|
-
value: n(win?.pliCount)
|
|
27313
|
-
}),
|
|
27314
27339
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27315
27340
|
label: "framesDropped",
|
|
27316
27341
|
value: n(stats?.framesDropped)
|
|
27317
27342
|
}),
|
|
27318
27343
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27319
|
-
label: "decode
|
|
27344
|
+
label: "decode",
|
|
27320
27345
|
value: n(stats?.avgDecodeMs, {
|
|
27321
27346
|
digits: 1,
|
|
27322
27347
|
suffix: "ms"
|
|
27323
|
-
})
|
|
27324
|
-
|
|
27325
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27326
|
-
label: "· this window",
|
|
27327
|
-
value: n(win?.decodeMs, {
|
|
27328
|
-
digits: 1,
|
|
27329
|
-
suffix: "ms"
|
|
27330
|
-
})
|
|
27348
|
+
}),
|
|
27349
|
+
window: win?.decodeMs === null ? void 0 : `${n(win?.decodeMs, { digits: 1 })}ms`
|
|
27331
27350
|
}),
|
|
27332
27351
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SectionHeader, {
|
|
27333
27352
|
title: "picture",
|
|
@@ -27385,33 +27404,24 @@ function StreamDebugOverlay(props) {
|
|
|
27385
27404
|
}),
|
|
27386
27405
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27387
27406
|
label: "packetsLost",
|
|
27388
|
-
value: n(stats?.packetsLost)
|
|
27389
|
-
|
|
27390
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27391
|
-
label: "· this window",
|
|
27392
|
-
value: n(win?.packetsLost)
|
|
27407
|
+
value: n(stats?.packetsLost),
|
|
27408
|
+
window: win?.packetsLost === null ? void 0 : `+${n(win?.packetsLost)}`
|
|
27393
27409
|
}),
|
|
27394
27410
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27395
27411
|
label: "loss",
|
|
27396
27412
|
value: n(stats?.lossPercent, {
|
|
27397
27413
|
digits: 2,
|
|
27398
27414
|
suffix: "%"
|
|
27399
|
-
})
|
|
27400
|
-
|
|
27401
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27402
|
-
label: "· this window",
|
|
27403
|
-
value: n(win?.lossPercent, {
|
|
27415
|
+
}),
|
|
27416
|
+
window: win?.lossPercent === null ? void 0 : n(win?.lossPercent, {
|
|
27404
27417
|
digits: 2,
|
|
27405
27418
|
suffix: "%"
|
|
27406
27419
|
})
|
|
27407
27420
|
}),
|
|
27408
27421
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27409
27422
|
label: "nackCount",
|
|
27410
|
-
value: n(stats?.nackCount)
|
|
27411
|
-
|
|
27412
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27413
|
-
label: "· this window",
|
|
27414
|
-
value: n(win?.nackCount)
|
|
27423
|
+
value: n(stats?.nackCount),
|
|
27424
|
+
window: win?.nackCount === null ? void 0 : `+${n(win?.nackCount)}`
|
|
27415
27425
|
}),
|
|
27416
27426
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
|
|
27417
27427
|
label: "candidate pair",
|
package/dist/index.js
CHANGED
|
@@ -27212,15 +27212,21 @@ var VERDICT_CLASS = {
|
|
|
27212
27212
|
"transport-stall": "bg-rose-500/30 text-rose-100",
|
|
27213
27213
|
"frozen-unknown": "bg-white/15 text-white/70"
|
|
27214
27214
|
};
|
|
27215
|
-
function Row({ label, value, strong = false }) {
|
|
27215
|
+
function Row({ label, value, window, strong = false }) {
|
|
27216
27216
|
return /* @__PURE__ */ jsxs("div", {
|
|
27217
|
-
className: "flex items-baseline justify-between gap-
|
|
27217
|
+
className: "flex items-baseline justify-between gap-2 leading-[1.25]",
|
|
27218
27218
|
children: [/* @__PURE__ */ jsx("span", {
|
|
27219
27219
|
className: "text-white/55 shrink-0",
|
|
27220
27220
|
children: label
|
|
27221
|
-
}), /* @__PURE__ */
|
|
27222
|
-
className:
|
|
27223
|
-
children:
|
|
27221
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
27222
|
+
className: "flex items-baseline gap-1 text-right",
|
|
27223
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
27224
|
+
className: strong ? "text-white font-semibold tabular-nums" : "text-white/90 tabular-nums",
|
|
27225
|
+
children: value
|
|
27226
|
+
}), window !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
27227
|
+
className: "text-sky-300/80 tabular-nums",
|
|
27228
|
+
children: window
|
|
27229
|
+
})]
|
|
27224
27230
|
})]
|
|
27225
27231
|
});
|
|
27226
27232
|
}
|
|
@@ -27237,16 +27243,45 @@ function SectionHeader({ title, measuredAt, now }) {
|
|
|
27237
27243
|
})]
|
|
27238
27244
|
});
|
|
27239
27245
|
}
|
|
27246
|
+
/** The pill's dot: the verdict, in the one place that is always visible. */
|
|
27247
|
+
var VERDICT_DOT = {
|
|
27248
|
+
unknown: "bg-white/50",
|
|
27249
|
+
decoding: "bg-emerald-400",
|
|
27250
|
+
"decoder-stall": "bg-amber-400",
|
|
27251
|
+
"transport-stall": "bg-rose-400",
|
|
27252
|
+
"frozen-unknown": "bg-white/50"
|
|
27253
|
+
};
|
|
27240
27254
|
function StreamDebugOverlay(props) {
|
|
27241
27255
|
const { stats, server, serverError, serverWired, now, sessionId } = props;
|
|
27242
27256
|
const verdict = freezeVerdict(stats);
|
|
27243
27257
|
const win = stats?.window;
|
|
27258
|
+
const [expanded, setExpanded] = useState(false);
|
|
27259
|
+
const stale = stats !== null && now - stats.at > STALE_AFTER_MS;
|
|
27260
|
+
if (!expanded) return /* @__PURE__ */ jsxs("button", {
|
|
27261
|
+
type: "button",
|
|
27262
|
+
onClick: () => setExpanded(true),
|
|
27263
|
+
className: "absolute bottom-10 left-2 z-20 transform-gpu flex items-center gap-1.5 rounded bg-neutral-950/90 ring-1 ring-white/20 px-1.5 py-0.5 text-[9px] font-mono text-white/85 tabular-nums select-text",
|
|
27264
|
+
"data-testid": "stream-debug-pill",
|
|
27265
|
+
title: verdict.label,
|
|
27266
|
+
children: [
|
|
27267
|
+
/* @__PURE__ */ jsx("span", { className: `h-1.5 w-1.5 rounded-full ${VERDICT_DOT[verdict.kind]}` }),
|
|
27268
|
+
/* @__PURE__ */ jsx("span", { children: stats?.width !== null && stats?.width !== void 0 ? `${stats.width}×${stats.height}` : UNKNOWN }),
|
|
27269
|
+
/* @__PURE__ */ jsxs("span", { children: [n(stats?.fps), "fps"] }),
|
|
27270
|
+
/* @__PURE__ */ jsxs("span", { children: [n(win?.kbps), "k"] }),
|
|
27271
|
+
stale && /* @__PURE__ */ jsx("span", {
|
|
27272
|
+
className: "text-amber-300",
|
|
27273
|
+
children: "stale"
|
|
27274
|
+
})
|
|
27275
|
+
]
|
|
27276
|
+
});
|
|
27244
27277
|
return /* @__PURE__ */ jsxs("div", {
|
|
27245
|
-
className: "absolute
|
|
27278
|
+
className: "absolute bottom-10 left-2 z-20 transform-gpu w-[13.5rem] max-h-[70%] overflow-y-auto rounded-md bg-neutral-950/95 ring-1 ring-white/25 shadow-lg px-1.5 py-1 text-[9px] font-mono text-white/90 select-text",
|
|
27246
27279
|
"data-testid": "stream-debug-overlay",
|
|
27247
27280
|
children: [
|
|
27248
|
-
/* @__PURE__ */ jsx("
|
|
27249
|
-
|
|
27281
|
+
/* @__PURE__ */ jsx("button", {
|
|
27282
|
+
type: "button",
|
|
27283
|
+
onClick: () => setExpanded(false),
|
|
27284
|
+
className: `w-full text-left rounded px-1.5 py-0.5 mb-1 text-[9px] font-semibold ${VERDICT_CLASS[verdict.kind]}`,
|
|
27250
27285
|
children: verdict.label
|
|
27251
27286
|
}),
|
|
27252
27287
|
/* @__PURE__ */ jsx(SectionHeader, {
|
|
@@ -27257,11 +27292,7 @@ function StreamDebugOverlay(props) {
|
|
|
27257
27292
|
/* @__PURE__ */ jsx(Row, {
|
|
27258
27293
|
label: "framesDecoded",
|
|
27259
27294
|
value: n(stats?.framesDecoded),
|
|
27260
|
-
|
|
27261
|
-
}),
|
|
27262
|
-
/* @__PURE__ */ jsx(Row, {
|
|
27263
|
-
label: "· this window",
|
|
27264
|
-
value: n(win?.framesDecoded),
|
|
27295
|
+
window: win?.framesDecoded === null ? void 0 : `+${n(win?.framesDecoded)}`,
|
|
27265
27296
|
strong: true
|
|
27266
27297
|
}),
|
|
27267
27298
|
/* @__PURE__ */ jsx(Row, {
|
|
@@ -27270,40 +27301,28 @@ function StreamDebugOverlay(props) {
|
|
|
27270
27301
|
strong: true
|
|
27271
27302
|
}),
|
|
27272
27303
|
/* @__PURE__ */ jsx(Row, {
|
|
27273
|
-
label: "
|
|
27304
|
+
label: "frozen",
|
|
27274
27305
|
value: n(stats?.totalFreezeMs, { suffix: "ms" }),
|
|
27306
|
+
window: win?.freezeMs === null ? void 0 : `+${n(win?.freezeMs)}ms`,
|
|
27275
27307
|
strong: true
|
|
27276
27308
|
}),
|
|
27277
|
-
/* @__PURE__ */ jsx(Row, {
|
|
27278
|
-
label: "· this window",
|
|
27279
|
-
value: n(win?.freezeMs, { suffix: "ms" })
|
|
27280
|
-
}),
|
|
27281
27309
|
/* @__PURE__ */ jsx(Row, {
|
|
27282
27310
|
label: "pliCount",
|
|
27283
27311
|
value: n(stats?.pliCount),
|
|
27312
|
+
window: win?.pliCount === null ? void 0 : `+${n(win?.pliCount)}`,
|
|
27284
27313
|
strong: true
|
|
27285
27314
|
}),
|
|
27286
|
-
/* @__PURE__ */ jsx(Row, {
|
|
27287
|
-
label: "· this window",
|
|
27288
|
-
value: n(win?.pliCount)
|
|
27289
|
-
}),
|
|
27290
27315
|
/* @__PURE__ */ jsx(Row, {
|
|
27291
27316
|
label: "framesDropped",
|
|
27292
27317
|
value: n(stats?.framesDropped)
|
|
27293
27318
|
}),
|
|
27294
27319
|
/* @__PURE__ */ jsx(Row, {
|
|
27295
|
-
label: "decode
|
|
27320
|
+
label: "decode",
|
|
27296
27321
|
value: n(stats?.avgDecodeMs, {
|
|
27297
27322
|
digits: 1,
|
|
27298
27323
|
suffix: "ms"
|
|
27299
|
-
})
|
|
27300
|
-
|
|
27301
|
-
/* @__PURE__ */ jsx(Row, {
|
|
27302
|
-
label: "· this window",
|
|
27303
|
-
value: n(win?.decodeMs, {
|
|
27304
|
-
digits: 1,
|
|
27305
|
-
suffix: "ms"
|
|
27306
|
-
})
|
|
27324
|
+
}),
|
|
27325
|
+
window: win?.decodeMs === null ? void 0 : `${n(win?.decodeMs, { digits: 1 })}ms`
|
|
27307
27326
|
}),
|
|
27308
27327
|
/* @__PURE__ */ jsx(SectionHeader, {
|
|
27309
27328
|
title: "picture",
|
|
@@ -27361,33 +27380,24 @@ function StreamDebugOverlay(props) {
|
|
|
27361
27380
|
}),
|
|
27362
27381
|
/* @__PURE__ */ jsx(Row, {
|
|
27363
27382
|
label: "packetsLost",
|
|
27364
|
-
value: n(stats?.packetsLost)
|
|
27365
|
-
|
|
27366
|
-
/* @__PURE__ */ jsx(Row, {
|
|
27367
|
-
label: "· this window",
|
|
27368
|
-
value: n(win?.packetsLost)
|
|
27383
|
+
value: n(stats?.packetsLost),
|
|
27384
|
+
window: win?.packetsLost === null ? void 0 : `+${n(win?.packetsLost)}`
|
|
27369
27385
|
}),
|
|
27370
27386
|
/* @__PURE__ */ jsx(Row, {
|
|
27371
27387
|
label: "loss",
|
|
27372
27388
|
value: n(stats?.lossPercent, {
|
|
27373
27389
|
digits: 2,
|
|
27374
27390
|
suffix: "%"
|
|
27375
|
-
})
|
|
27376
|
-
|
|
27377
|
-
/* @__PURE__ */ jsx(Row, {
|
|
27378
|
-
label: "· this window",
|
|
27379
|
-
value: n(win?.lossPercent, {
|
|
27391
|
+
}),
|
|
27392
|
+
window: win?.lossPercent === null ? void 0 : n(win?.lossPercent, {
|
|
27380
27393
|
digits: 2,
|
|
27381
27394
|
suffix: "%"
|
|
27382
27395
|
})
|
|
27383
27396
|
}),
|
|
27384
27397
|
/* @__PURE__ */ jsx(Row, {
|
|
27385
27398
|
label: "nackCount",
|
|
27386
|
-
value: n(stats?.nackCount)
|
|
27387
|
-
|
|
27388
|
-
/* @__PURE__ */ jsx(Row, {
|
|
27389
|
-
label: "· this window",
|
|
27390
|
-
value: n(win?.nackCount)
|
|
27399
|
+
value: n(stats?.nackCount),
|
|
27400
|
+
window: win?.nackCount === null ? void 0 : `+${n(win?.nackCount)}`
|
|
27391
27401
|
}),
|
|
27392
27402
|
/* @__PURE__ */ jsx(Row, {
|
|
27393
27403
|
label: "candidate pair",
|