@tangle-network/charts 0.21.17 → 0.21.19
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/react/flow-waterfall.css +28 -11
- package/dist/react/index.d.ts +4 -0
- package/dist/react/index.js +62 -16
- package/package.json +1 -1
|
@@ -259,7 +259,8 @@
|
|
|
259
259
|
/* Muted agents (the default): one quiet tone for every agent bar, its steps and handoffs; the slowest agent alone takes amber, and
|
|
260
260
|
failure keeps its red glyph, so color only ever means state. */
|
|
261
261
|
.fw-root.fw-fill-muted .fw-view-agents [data-tone] { --tone: var(--fw-h0); }
|
|
262
|
-
|
|
262
|
+
/* With per-agent hues the slowest agent keeps its own hue and says so with the amber pill (round 27: an amber-brown bar read "muddy"). */
|
|
263
|
+
.fw-root.fw-fill-muted .fw-view-agents .fw-row[data-slowest], .fw-root.fw-fill-muted .fw-view-agents .fw-row[data-slowest] [data-tone] { --tone: var(--fw-amber); }
|
|
263
264
|
.fw-root [data-outcome="ok"], .fw-root [data-outcome="ok"] [data-tone] { --tone: var(--fw-ok); }
|
|
264
265
|
.fw-root [data-outcome="failed"], .fw-root [data-outcome="failed"] [data-tone] { --tone: var(--fw-failed); }
|
|
265
266
|
.fw-root [data-outcome="warn"], .fw-root [data-outcome="warn"] [data-tone] { --tone: var(--fw-amber); }
|
|
@@ -291,14 +292,30 @@
|
|
|
291
292
|
.fw-root:is(.fw-fill-muted, .fw-fill-outcome) .fw-view-agents .fw-seg-model { background: var(--fw-kind-model); box-shadow: none; }
|
|
292
293
|
.fw-root:is(.fw-fill-muted, .fw-fill-outcome) .fw-view-agents .fw-seg-tool { background: var(--fw-kind-tool); box-shadow: none; }
|
|
293
294
|
/* Per-agent hues at full saturation (blind round 26: muted per-agent bars "blur together", "wash out on white"): kind is a darker or
|
|
294
|
-
lighter step of the agent's own saturated hue
|
|
295
|
-
|
|
296
|
-
.fw-root.fw-fill-agent .fw-view-agents .fw-seg-
|
|
295
|
+
lighter step of the agent's own saturated hue; waiting stays the only pale fill. Light theme sits one step softer (round 27: the
|
|
296
|
+
saturated light bars read "heavy"). */
|
|
297
|
+
.fw-root.fw-fill-agent .fw-view-agents .fw-seg-model { background: light-dark(color-mix(in oklab, var(--tone) 88%, var(--fw-text)), var(--tone)); box-shadow: none; }
|
|
298
|
+
.fw-root.fw-fill-agent .fw-view-agents .fw-seg-tool { background: light-dark(color-mix(in oklab, var(--tone) 84%, var(--fw-surface)), color-mix(in oklab, var(--tone) 72%, var(--fw-text))); box-shadow: none; }
|
|
297
299
|
/* A failed turn is still the agent's work: it keeps the agent's saturated hue, and the red cross on the ending turn says it failed. */
|
|
298
|
-
.fw-root.fw-fill-agent .fw-view-agents .fw-seg-failed { background: light-dark(var(--tone), color-mix(in oklab, var(--tone) 72%, var(--fw-text))); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-failed) 55%, transparent); }
|
|
299
|
-
.fw-root .fw-view-agents .fw-seg
|
|
300
|
-
|
|
301
|
-
|
|
300
|
+
.fw-root.fw-fill-agent .fw-view-agents .fw-seg-failed { background: light-dark(color-mix(in oklab, var(--tone) 84%, var(--fw-surface)), color-mix(in oklab, var(--tone) 72%, var(--fw-text))); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-failed) 55%, transparent); }
|
|
301
|
+
.fw-root .fw-view-agents .fw-seg { container-type: inline-size; justify-content: flex-start; font-size: 12px; line-height: 16px; white-space: nowrap; color: var(--fw-seg-ink); }
|
|
302
|
+
/* Label ink holds 4.5:1 on its fill: light text on the darker model step, a near-black of the agent's hue on the lighter tool step
|
|
303
|
+
(round 28: white on the pale light-theme fills failed); on dark the steps are bright, so ink is the page's dark. */
|
|
304
|
+
.fw-root .fw-view-agents .fw-seg-model { --fw-seg-ink: light-dark(var(--fw-surface), hsl(var(--hsl-background))); }
|
|
305
|
+
.fw-root .fw-view-agents :is(.fw-seg-tool, .fw-seg-failed) { --fw-seg-ink: light-dark(color-mix(in oklab, var(--tone) 18%, black), hsl(var(--hsl-background))); }
|
|
306
|
+
.fw-root .fw-view-agents .fw-seg > * { pointer-events: none; }
|
|
307
|
+
/* One line, 6 px in from each end; a part that does not fit whole wraps to the hidden second line, so trailing parts drop first. */
|
|
308
|
+
.fw-root .fw-seg-label { flex: 1; min-width: 0; height: 16px; margin: 0 6px; display: flex; flex-wrap: wrap; align-items: center; column-gap: 4px; overflow: hidden; }
|
|
309
|
+
.fw-root .fw-seg-label > * { flex: none; height: 16px; display: inline-flex; align-items: center; }
|
|
310
|
+
.fw-root .fw-seg-icon svg { width: 12px; height: 12px; stroke-width: 1.75; }
|
|
311
|
+
.fw-root .fw-seg-name { font-weight: 600; }
|
|
312
|
+
.fw-root .fw-seg-chip { padding: 0 4px; border-radius: var(--radius-pill); background: color-mix(in oklab, currentColor 18%, transparent); font-weight: 600; font-variant-numeric: tabular-nums; }
|
|
313
|
+
.fw-root .fw-seg-meta { font-variant-numeric: tabular-nums; }
|
|
314
|
+
@container (max-width: 24px) { .fw-root :is(.fw-seg-label, .fw-view-agents .fw-seg .fw-glyph) { display: none; } }
|
|
315
|
+
/* Fail and retry read as filled chips inside the bar, red and amber, as the references draw them. */
|
|
316
|
+
.fw-root .fw-view-agents .fw-seg .fw-glyph { flex: none; margin-left: 6px; display: grid; place-items: center; width: 14px; height: 14px; border-radius: 50%; background: var(--fw-failed); color: light-dark(var(--fw-surface), hsl(var(--hsl-background))); }
|
|
317
|
+
.fw-root .fw-view-agents .fw-seg .fw-glyph[data-glyph="retry"] { background: var(--fw-amber); }
|
|
318
|
+
.fw-root .fw-view-agents .fw-seg .fw-glyph svg { width: 9px; height: 9px; stroke-width: 2.5; }
|
|
302
319
|
.fw-root:is(.fw-fill-muted, .fw-fill-outcome) .fw-view-agents :is(.fw-seg-alt.fw-seg-model, .fw-seg-alt.fw-seg-tool) { filter: brightness(.88); }
|
|
303
320
|
.fw-root .fw-seg-failed { background: color-mix(in oklab, var(--fw-failed) 18%, var(--fw-surface)); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-failed) 70%, transparent); color: var(--fw-failed); }
|
|
304
321
|
/* In the agent view a failed turn draws like any turn; the agent's own failure shows once, by its name and its end label. */
|
|
@@ -320,15 +337,15 @@
|
|
|
320
337
|
.fw-root .fw-links { position: absolute; top: 0; bottom: 0; left: var(--fw-label-col); right: 0; overflow: hidden; pointer-events: none; z-index: 0; }
|
|
321
338
|
.fw-root .fw-link {
|
|
322
339
|
--x: calc(var(--fw-pad) + (var(--s) - var(--fw-v0)) * var(--fw-k) * 1px);
|
|
323
|
-
position: absolute; width:
|
|
340
|
+
position: absolute; width: 12px; border: 0 solid var(--line); border-bottom-width: 1.5px; translate: 0 var(--fw-bar-shift);
|
|
324
341
|
opacity: clamp(0, (var(--fw-t) - var(--s)) * 1000, 1);
|
|
325
342
|
}
|
|
326
343
|
.fw-root .fw-view-spans .fw-link { opacity: calc(clamp(0, (var(--fw-t) - var(--s)) * 1000, 1) * .7); }
|
|
327
344
|
/* Agent-view connectors rest faint, one curved elbow per spawn in the agent's hue (they show who started whom), and come to
|
|
328
345
|
full strength for the agent under the pointer, pinned or focused. */
|
|
329
|
-
.fw-root .fw-view-agents .fw-link:not(.fw-link-hot) { opacity: calc(clamp(0, (var(--fw-t) - var(--s)) * 1000, 1) * .
|
|
346
|
+
.fw-root .fw-view-agents .fw-link:not(.fw-link-hot) { opacity: calc(clamp(0, (var(--fw-t) - var(--s)) * 1000, 1) * .8); }
|
|
330
347
|
.fw-root .fw-link { transition: opacity 160ms var(--fw-ease); }
|
|
331
|
-
.fw-root .fw-link-down { left: calc(var(--x) -
|
|
348
|
+
.fw-root .fw-link-down { left: calc(var(--x) - 12px); border-left-width: 1.5px; border-bottom-left-radius: 12px; }
|
|
332
349
|
.fw-root .fw-link-up { left: var(--x); border-right-width: 1.5px; border-bottom-right-radius: 12px; }
|
|
333
350
|
.fw-root .fw-link::before { content: ""; position: absolute; top: -3.5px; width: 5px; height: 5px; border-radius: 50%; background: var(--line); box-shadow: 0 0 0 1.5px var(--fw-surface); }
|
|
334
351
|
.fw-root .fw-link-down::before { left: -3.25px; }
|
package/dist/react/index.d.ts
CHANGED
|
@@ -391,6 +391,10 @@ interface FlowSegment {
|
|
|
391
391
|
name?: string;
|
|
392
392
|
/** The tool every merged step shares (the name before " · "); undefined once the merged steps differ. */
|
|
393
393
|
tool?: string;
|
|
394
|
+
/** What the merged steps cost, when any of them recorded a cost. */
|
|
395
|
+
costUsd?: number;
|
|
396
|
+
/** A failed mark that was a model call, so it draws the model's icon and no tool name. */
|
|
397
|
+
modelCall?: boolean;
|
|
394
398
|
}
|
|
395
399
|
/** A row's direct steps: model and tool calls (failed ones included), the failed and retrying ones, and tool calls by tool. */
|
|
396
400
|
interface StepCounts {
|
package/dist/react/index.js
CHANGED
|
@@ -2476,6 +2476,7 @@ function mergeSegments(marks, gapMs, cap = 240) {
|
|
|
2476
2476
|
last.endMs = Math.max(last.endMs, mark.endMs);
|
|
2477
2477
|
last.count += mark.count;
|
|
2478
2478
|
if (last.tool !== mark.tool) last.tool = void 0;
|
|
2479
|
+
if (mark.costUsd !== void 0) last.costUsd = (last.costUsd ?? 0) + mark.costUsd;
|
|
2479
2480
|
last.kind = share.model >= share.tool ? "model" : "tool";
|
|
2480
2481
|
} else out.push({ ...mark });
|
|
2481
2482
|
}
|
|
@@ -2656,7 +2657,9 @@ function segmentOf(row) {
|
|
|
2656
2657
|
count: 1,
|
|
2657
2658
|
retry: row.retry,
|
|
2658
2659
|
name: row.name,
|
|
2659
|
-
tool: toolOf(row.name)
|
|
2660
|
+
tool: toolOf(row.name),
|
|
2661
|
+
...row.span.costUsd === void 0 ? {} : { costUsd: row.span.costUsd },
|
|
2662
|
+
...!row.ok && row.kind === "model" ? { modelCall: true } : {}
|
|
2660
2663
|
};
|
|
2661
2664
|
}
|
|
2662
2665
|
/** The rows a search term matches by themselves, before ancestor context is added. */
|
|
@@ -3374,25 +3377,54 @@ const at = (startMs, endMs) => ({
|
|
|
3374
3377
|
});
|
|
3375
3378
|
const endLabelWidth = (label, slowest, costliest) => label.length * 7 + 8 + (slowest ? 80 : 0) + (costliest ? 90 : 0);
|
|
3376
3379
|
function Segment({ mark, events, agentView, ending }) {
|
|
3377
|
-
const glyph = mark.kind === "failed" ? agentView && !ending ? null :
|
|
3378
|
-
const
|
|
3379
|
-
|
|
3380
|
+
const glyph = mark.kind === "failed" ? agentView && !ending ? null : "fail" : mark.retry ? "retry" : null;
|
|
3381
|
+
const model = mark.kind === "model" || mark.modelCall;
|
|
3382
|
+
const name = model ? void 0 : mark.count === 1 ? mark.name : mark.tool;
|
|
3383
|
+
const duration = Number.isFinite(mark.endMs) ? formatSpanDuration(mark.endMs - mark.startMs) : "";
|
|
3384
|
+
const meta = [duration, mark.costUsd ? formatCost(mark.costUsd) : ""].filter(Boolean).join(" · ");
|
|
3385
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
3380
3386
|
className: `fw-seg fw-seg-${mark.kind}${mark.alt ? " fw-seg-alt" : ""}`,
|
|
3381
3387
|
"data-tone": toneKey(mark.tone),
|
|
3382
3388
|
style: at(mark.startMs, mark.endMs),
|
|
3383
|
-
title: mark.name ? `${mark.name}${mark.count > 1 ? ` +${mark.count - 1} more` : ""}` : void 0,
|
|
3389
|
+
title: mark.name ? `${mark.name}${mark.count > 1 ? ` +${mark.count - 1} more` : ""}${meta ? ` · ${meta}` : ""}` : void 0,
|
|
3384
3390
|
onPointerEnter: agentView ? (event) => events.onInspect(mark.id, event.currentTarget, event.clientX) : void 0,
|
|
3385
3391
|
onClick: agentView ? (event) => {
|
|
3386
3392
|
event.stopPropagation();
|
|
3387
3393
|
events.onPin(mark.id, event.currentTarget, event.clientX);
|
|
3388
3394
|
} : void 0,
|
|
3389
|
-
children: glyph
|
|
3395
|
+
children: [glyph && /* @__PURE__ */ jsx("span", {
|
|
3390
3396
|
className: "fw-glyph",
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3397
|
+
"data-glyph": glyph,
|
|
3398
|
+
children: glyph === "fail" ? /* @__PURE__ */ jsx(FailGlyph, {}) : /* @__PURE__ */ jsx(RetryGlyph, {})
|
|
3399
|
+
}), agentView && /* @__PURE__ */ jsxs("span", {
|
|
3400
|
+
className: "fw-seg-label",
|
|
3401
|
+
children: [
|
|
3402
|
+
/* @__PURE__ */ jsx("span", {
|
|
3403
|
+
className: "fw-seg-icon",
|
|
3404
|
+
"aria-hidden": true,
|
|
3405
|
+
children: /* @__PURE__ */ jsx(KindGlyph, {
|
|
3406
|
+
kind: model ? "model" : "tool",
|
|
3407
|
+
name: mark.tool ?? mark.name
|
|
3408
|
+
})
|
|
3409
|
+
}),
|
|
3410
|
+
name && /* @__PURE__ */ jsx("span", {
|
|
3411
|
+
className: "fw-seg-name",
|
|
3412
|
+
children: name
|
|
3413
|
+
}),
|
|
3414
|
+
mark.count > 1 && /* @__PURE__ */ jsxs("span", {
|
|
3415
|
+
className: "fw-seg-chip",
|
|
3416
|
+
children: ["×", mark.count]
|
|
3417
|
+
}),
|
|
3418
|
+
duration && /* @__PURE__ */ jsx("span", {
|
|
3419
|
+
className: "fw-seg-meta",
|
|
3420
|
+
children: duration
|
|
3421
|
+
}),
|
|
3422
|
+
mark.costUsd ? /* @__PURE__ */ jsx("span", {
|
|
3423
|
+
className: "fw-seg-meta",
|
|
3424
|
+
children: formatCost(mark.costUsd)
|
|
3425
|
+
}) : null
|
|
3426
|
+
]
|
|
3427
|
+
})]
|
|
3396
3428
|
});
|
|
3397
3429
|
}
|
|
3398
3430
|
/** A span the clock is inside: it grows live, or playback has not reached its end. */
|
|
@@ -3418,7 +3450,7 @@ const FlowRow = memo(function FlowRow(props) {
|
|
|
3418
3450
|
const kind = !row.ok ? "failed" : row.kind;
|
|
3419
3451
|
const marks = isAgent || row.hasChildren || row.id.startsWith("run:") ? folded && !agentView ? row.segments : row.own : [];
|
|
3420
3452
|
const label = endLabel(row, clockMs);
|
|
3421
|
-
const summary = [...span.detail && span.detail !== props.sharedDetail ? [span.detail] : [], ...agentSummary(row)];
|
|
3453
|
+
const summary = [...span.detail && span.detail !== props.sharedDetail ? [span.detail] : [], ...agentSummary(row).filter((part) => part !== props.sharedOutcome)];
|
|
3422
3454
|
const inspect = (event) => props.onInspect(row.id, event.currentTarget, event.clientX);
|
|
3423
3455
|
const family = agentView && row.id.startsWith("family:");
|
|
3424
3456
|
const step = agentView && row.stepOf !== void 0;
|
|
@@ -3554,6 +3586,11 @@ const FlowRow = memo(function FlowRow(props) {
|
|
|
3554
3586
|
"aria-label": `${row.descendants} hidden steps`,
|
|
3555
3587
|
children: ["+", row.descendants]
|
|
3556
3588
|
}),
|
|
3589
|
+
family && !props.expanded && /* @__PURE__ */ jsxs("span", {
|
|
3590
|
+
className: "fw-count",
|
|
3591
|
+
"aria-label": `${row.descendants} agents folded`,
|
|
3592
|
+
children: ["+", row.descendants]
|
|
3593
|
+
}),
|
|
3557
3594
|
!row.ok && !agentView && /* @__PURE__ */ jsx("span", {
|
|
3558
3595
|
className: "fw-alert",
|
|
3559
3596
|
children: /* @__PURE__ */ jsx(AlertGlyph, { label: "failed" })
|
|
@@ -3622,7 +3659,7 @@ const FlowRow = memo(function FlowRow(props) {
|
|
|
3622
3659
|
] })
|
|
3623
3660
|
})]
|
|
3624
3661
|
});
|
|
3625
|
-
}, (a, b) => a.row === b.row && a.view === b.view && a.top === b.top && a.collapsed === b.collapsed && a.searching === b.searching && a.slowest === b.slowest && a.costliest === b.costliest && a.critical === b.critical && a.matched === b.matched && a.active === b.active && a.focusable === b.focusable && a.selected === b.selected && a.sticky === b.sticky && a.motion === b.motion && a.renderIcon === b.renderIcon && a.fillByAgent === b.fillByAgent && a.sharedDetail === b.sharedDetail && a.expanded === b.expanded && (a.clockMs === b.clockMs || !open(a.row, a.clockMs) && !open(b.row, b.clockMs)));
|
|
3662
|
+
}, (a, b) => a.row === b.row && a.view === b.view && a.top === b.top && a.collapsed === b.collapsed && a.searching === b.searching && a.slowest === b.slowest && a.costliest === b.costliest && a.critical === b.critical && a.matched === b.matched && a.active === b.active && a.focusable === b.focusable && a.selected === b.selected && a.sticky === b.sticky && a.motion === b.motion && a.renderIcon === b.renderIcon && a.fillByAgent === b.fillByAgent && a.sharedDetail === b.sharedDetail && a.sharedOutcome === b.sharedOutcome && a.expanded === b.expanded && (a.clockMs === b.clockMs || !open(a.row, a.clockMs) && !open(b.row, b.clockMs)));
|
|
3626
3663
|
/** An elbow connector between two rows at one moment, drawn in the row's tone; appears when the clock reaches it. */
|
|
3627
3664
|
function LinkMark({ link, rowHeight, hot }) {
|
|
3628
3665
|
const upper = Math.min(link.from, link.to), lower = Math.max(link.from, link.to);
|
|
@@ -4095,6 +4132,7 @@ function FlowBody(props) {
|
|
|
4095
4132
|
renderIcon: props.renderIcon,
|
|
4096
4133
|
fillByAgent: props.fillByAgent,
|
|
4097
4134
|
sharedDetail: props.sharedDetail,
|
|
4135
|
+
sharedOutcome: props.sharedOutcome,
|
|
4098
4136
|
expanded: props.expandedIds?.has(item.id),
|
|
4099
4137
|
onToggle: props.onToggle,
|
|
4100
4138
|
onInspect: props.onInspect,
|
|
@@ -4481,6 +4519,13 @@ function useHostable(value, onChange, initial) {
|
|
|
4481
4519
|
}, [controlled])];
|
|
4482
4520
|
}
|
|
4483
4521
|
const CARD_WIDTH = 320;
|
|
4522
|
+
/** The value at least half of several agents share, if one does. */
|
|
4523
|
+
function usual(values) {
|
|
4524
|
+
const counts = /* @__PURE__ */ new Map();
|
|
4525
|
+
for (const value of values) if (value) counts.set(value, (counts.get(value) ?? 0) + 1);
|
|
4526
|
+
const [top, n] = [...counts].sort((a, b) => b[1] - a[1])[0] ?? [];
|
|
4527
|
+
return values.length > 1 && n !== void 0 && n >= 2 && n * 2 >= values.length ? top : void 0;
|
|
4528
|
+
}
|
|
4484
4529
|
/** The summary strip: as of the playhead while scrubbing, the producer's totals otherwise. */
|
|
4485
4530
|
function summaryCells(trace, at, durationMs) {
|
|
4486
4531
|
const cost = costSummary(at ? at.costUsd : trace.costUsd, trace);
|
|
@@ -4658,8 +4703,8 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
4658
4703
|
const pipelines = rows.filter((row) => row.kind === "pipeline");
|
|
4659
4704
|
return pipelines.length ? pipelines : rows.filter((row) => !row.parentId);
|
|
4660
4705
|
}, [rows]);
|
|
4661
|
-
const
|
|
4662
|
-
const
|
|
4706
|
+
const sharedDetail = usual(agents.map((row) => row.span.detail));
|
|
4707
|
+
const sharedOutcome = usual(agents.map((row) => row.span.outcome?.label));
|
|
4663
4708
|
const [flippedFamilies, setFlippedFamilies] = useState(/* @__PURE__ */ new Set());
|
|
4664
4709
|
const openFamilies = useMemo(() => defaultOpenFamilies(agents, UNFOLD_ROWS, flippedFamilies), [agents, flippedFamilies]);
|
|
4665
4710
|
const [openSteps, setOpenSteps] = useState(/* @__PURE__ */ new Set());
|
|
@@ -4982,7 +5027,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
4982
5027
|
agents.length,
|
|
4983
5028
|
" ",
|
|
4984
5029
|
agents.length === 1 ? "agent" : "agents",
|
|
4985
|
-
sharedDetail ? ` · ${sharedDetail}` : "",
|
|
5030
|
+
sharedDetail ? ` · ${agents.every((row) => row.span.detail === sharedDetail) ? "" : "mostly "}${sharedDetail}` : "",
|
|
4986
5031
|
done && speedup >= 1.05 ? ` · ${speedup.toFixed(1)}x parallel` : ""
|
|
4987
5032
|
]
|
|
4988
5033
|
}),
|
|
@@ -5068,6 +5113,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
5068
5113
|
pauses: trace.pauses,
|
|
5069
5114
|
cursorLine: position !== null || playing,
|
|
5070
5115
|
sharedDetail,
|
|
5116
|
+
sharedOutcome,
|
|
5071
5117
|
expandedIds: view === "agents" ? /* @__PURE__ */ new Set([...openFamilies, ...openSteps]) : void 0,
|
|
5072
5118
|
holdHeight: isLive,
|
|
5073
5119
|
slowestId: slowest?.id ?? callouts.slowestId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/charts",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.19",
|
|
4
4
|
"description": "Static SVG and HTML figures for benchmarks and operational timing. Draws from producer data and refuses what it cannot draw honestly.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|