dsh-context 0.22.2 → 0.24.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/lib/client.js CHANGED
@@ -118,7 +118,9 @@ window.__ModuleLoader__.load({
118
118
  "attach.open": "查看原图",
119
119
  "attach.loading": "…",
120
120
  "attach.loadFailed": "加载失败 · 点击重试",
121
- "attach.orig": "原图 {d}"
121
+ "attach.orig": "原图 {d}",
122
+ "attach.tokens": "≈{n} tokens",
123
+ "attach.tokensTip": "按 DeepSeek 官方图片尺寸换算(单图上限 384 tokens)估算的 token 消耗"
122
124
  };
123
125
  const DICT_EN = {
124
126
  "tab": "Context",
@@ -233,7 +235,9 @@ window.__ModuleLoader__.load({
233
235
  "attach.open": "Open full image",
234
236
  "attach.loading": "…",
235
237
  "attach.loadFailed": "Load failed · click to retry",
236
- "attach.orig": "original {d}"
238
+ "attach.orig": "original {d}",
239
+ "attach.tokens": "≈{n} tokens",
240
+ "attach.tokensTip": "Estimated token cost via DeepSeek's official image-size conversion (384-token cap per image)"
237
241
  };
238
242
  //#endregion
239
243
  //#region src/client/modalStore.ts
@@ -350,6 +354,12 @@ window.__ModuleLoader__.load({
350
354
  color: "#14b8a6"
351
355
  }
352
356
  ];
357
+ const MESSAGE_CATS = [
358
+ "user",
359
+ "inject",
360
+ "assistant",
361
+ "tool"
362
+ ];
353
363
  function partsOf(breakdown) {
354
364
  return CATS.map((c) => {
355
365
  return {
@@ -360,25 +370,70 @@ window.__ModuleLoader__.load({
360
370
  });
361
371
  }
362
372
  /**
373
+ * Build the pie-consistent raw parts: system/tools/messages take the
374
+ * OFFICIAL `contextBreakdown` figures when delivered (the exact counts the
375
+ * chat ring's panel shows), with the message bucket subdivided into the
376
+ * four surface categories by the fold's per-category ratios (rounding
377
+ * residue lands on the largest category, so the four always sum exactly to
378
+ * the official message figure). Absent the projection, the fold's own sums
379
+ * serve — the same fixed estimator, so identical on image-free sessions.
380
+ */
381
+ function officialParts(current, breakdown) {
382
+ const foldSurface = current.user + current.inject + current.assistant + current.tool;
383
+ const system = breakdown?.systemTokens ?? current.system;
384
+ const tools = breakdown?.toolsTokens ?? current.tools;
385
+ const messages = breakdown?.messageTokens ?? foldSurface;
386
+ const shares = {
387
+ system,
388
+ tools
389
+ };
390
+ if (foldSurface > 0) {
391
+ let assigned = 0;
392
+ let largest = "user";
393
+ for (const cat of MESSAGE_CATS) {
394
+ const count = Math.round(messages * (current[cat] / foldSurface));
395
+ shares[cat] = count;
396
+ assigned += count;
397
+ if (current[cat] > current[largest]) largest = cat;
398
+ }
399
+ shares[largest] = Math.max(0, shares[largest] + messages - assigned);
400
+ } else for (const cat of MESSAGE_CATS) shares[cat] = 0;
401
+ return CATS.map((c) => ({
402
+ key: c.key,
403
+ color: c.color,
404
+ value: shares[c.key] ?? 0
405
+ }));
406
+ }
407
+ /**
363
408
  * Reproportion heuristic parts so they sum to a provider-anchored target —
364
409
  * the same trick the official ContextMeter uses: the heuristic breakdown
365
- * supplies the composition RATIOS, the provider sample the total. Returns
366
- * the parts unchanged when no anchor applies.
410
+ * supplies the composition RATIOS, the provider sample the total. The
411
+ * anchored figure rides `value` (bar widths); the heuristic count stays on
412
+ * `raw` for the legend and tooltips. Returns the parts unchanged when no
413
+ * anchor applies.
367
414
  */
368
415
  function anchoredParts(parts, target) {
369
- if (target === null || target <= 0) return parts;
416
+ const sourced = parts.map((p) => ({
417
+ ...p,
418
+ raw: p.raw ?? p.value
419
+ }));
420
+ if (target === null || target <= 0) return sourced;
370
421
  let total = 0;
371
- for (const p of parts) total += p.value;
372
- if (total <= 0 || total === target) return parts;
422
+ for (const p of sourced) total += p.raw;
423
+ if (total <= 0) return sourced;
424
+ if (total === target) return sourced.map((p) => ({
425
+ ...p,
426
+ value: p.raw
427
+ }));
373
428
  const scale = target / total;
374
- return parts.map((p) => ({
429
+ return sourced.map((p) => ({
375
430
  ...p,
376
- value: Math.round(p.value * scale)
431
+ value: Math.round(p.raw * scale)
377
432
  }));
378
433
  }
379
434
  //#endregion
380
435
  //#region src/client/headline.ts
381
- function headlineOf(data, pressure = null) {
436
+ function headlineOf(data, pressure = null, breakdown = null) {
382
437
  const current = data.current;
383
438
  const projected = pressure !== null && typeof pressure.projectedTokens === "number" ? pressure.projectedTokens : void 0;
384
439
  const requests = data.requests;
@@ -391,7 +446,7 @@ window.__ModuleLoader__.load({
391
446
  tokens,
392
447
  window,
393
448
  pct: window !== void 0 && window > 0 ? Math.min(100, Math.round(tokens / window * 100)) : null,
394
- parts: anchoredParts(partsOf(current), occupancyTokens !== null && tokens > 0 ? tokens : null)
449
+ parts: anchoredParts(officialParts(current, breakdown), occupancyTokens !== null && tokens > 0 ? tokens : null)
395
450
  };
396
451
  }
397
452
  //#endregion
@@ -483,6 +538,26 @@ window.__ModuleLoader__.load({
483
538
  }
484
539
  /**
485
540
  * Narrow a delivered projection value to the official token-meter
541
+ * `contextBreakdown` projection (the heuristic composition rows of the chat
542
+ * ring's panel). Every figure must be a finite number — a partial/corrupt
543
+ * value degrades to null so the composition card falls back to the fold's
544
+ * own sums instead of mixing sources.
545
+ */
546
+ function contextBreakdownOf(value) {
547
+ const data = asRecord(value);
548
+ if (data === null) return null;
549
+ const { systemTokens, toolsTokens, messageTokens } = data;
550
+ if (typeof systemTokens !== "number" || !Number.isFinite(systemTokens)) return null;
551
+ if (typeof toolsTokens !== "number" || !Number.isFinite(toolsTokens)) return null;
552
+ if (typeof messageTokens !== "number" || !Number.isFinite(messageTokens)) return null;
553
+ return {
554
+ systemTokens,
555
+ toolsTokens,
556
+ messageTokens
557
+ };
558
+ }
559
+ /**
560
+ * Narrow a delivered projection value to the official token-meter
486
561
  * `tokenUsage` projection (durable cumulative provider usage). Absent key or
487
562
  * value = the meter's projection is not composed (or no request has reported
488
563
  * usage yet) — callers drop the cache-hit cell to a dash.
@@ -613,6 +688,136 @@ window.__ModuleLoader__.load({
613
688
  return d.toLocaleTimeString("en-GB", { hour12: false });
614
689
  }
615
690
  //#endregion
691
+ //#region src/shared/imageTokens.ts
692
+ /**
693
+ * Per-image token estimate for DeepSeek's vision model — a faithful port of
694
+ * the official "图片 Token 计算器" (Image Token Calculator) shipped on the
695
+ * DeepSeek API docs (https://api-docs.deepseek.com/zh-cn/quick_start/token_usage),
696
+ * which implements the provider's own image→token conversion:
697
+ *
698
+ * - every image is aspect-preserved rescaled before entering the model:
699
+ * below ~384×384 total pixels it is enlarged, above it is shrunk;
700
+ * - tokens follow the patch grid (patch 14px, downsample 3), so every
701
+ * image costs at least 117 and at most ~384 tokens (the documented cap).
702
+ *
703
+ * Verified against the docs calculator itself: 2048×1365→313, 800×600→341,
704
+ * 2048×2048→349, 512×512→201, 100×100→117, 1920×1080→369, 400×900→249.
705
+ * The DSH request pipeline's own 640k-pixel pre-resize does not change the
706
+ * result (the provider formula rescales to the same patch grid), so the
707
+ * durable attachment dimensions can be fed in directly.
708
+ *
709
+ * Pure math shared by the Host fold (message pricing) and the Client
710
+ * (attachment card token badges) — no dependencies, never mutates.
711
+ */
712
+ const PATCH_SIZE = 14;
713
+ const DOWNSAMPLE_RATIO = 3;
714
+ const MAX_WH_RATIO = 8;
715
+ /** ~384×384 total pixels: smaller images are enlarged before patching. */
716
+ const MIN_PIXELS = 147456;
717
+ const floorDiv = (a, b) => Math.floor(a / b);
718
+ const ceilDiv = (a, b) => Math.floor((a + b - 1) / b);
719
+ /** Token count of one patch grid (rows×cols) under the v4 layout rule. */
720
+ function gridTokens(rows, cols) {
721
+ let n = rows * (cols + 1) + 2;
722
+ if (rows % 2 === 1) n += cols + 1;
723
+ n += ceilDiv(rows, 2) * (cols + 1) % 2 * 2;
724
+ return n;
725
+ }
726
+ /** Solve the largest in-grid resize whose token count fits `budget`. */
727
+ function solveResizeRatio(height, width, budget) {
728
+ const ratio = height / width;
729
+ const gridW = Math.sqrt((budget - 2) / ratio + .25) - .5;
730
+ const gridH = gridW * ratio;
731
+ const unit = 42;
732
+ let bestHeight;
733
+ let bestWidth;
734
+ if (gridW < 1) {
735
+ let rows = floorDiv(budget - 2, 2);
736
+ if (rows % 2 === 1) rows -= 1;
737
+ bestWidth = unit;
738
+ bestHeight = rows * unit;
739
+ } else if (gridH < 2) {
740
+ const cols = floorDiv(budget - 2, 2) - 1;
741
+ if (cols <= 1) throw new Error("image tokens: budget too small to solve");
742
+ bestHeight = 84;
743
+ bestWidth = cols * unit;
744
+ } else {
745
+ const cols = Math.trunc(gridW);
746
+ let rows = Math.trunc(gridH);
747
+ if (rows % 2 === 1) rows -= 1;
748
+ const scale = Math.min(cols * unit / width, rows * unit / height);
749
+ bestWidth = Math.trunc(width * scale / PATCH_SIZE) * PATCH_SIZE;
750
+ bestHeight = Math.trunc(height * scale / PATCH_SIZE) * PATCH_SIZE;
751
+ }
752
+ const nLlmH = ceilDiv(floorDiv(bestHeight, PATCH_SIZE), DOWNSAMPLE_RATIO);
753
+ const nLlmW = ceilDiv(floorDiv(bestWidth, PATCH_SIZE), DOWNSAMPLE_RATIO);
754
+ return {
755
+ nLlmH,
756
+ nLlmW,
757
+ bestHeight,
758
+ bestWidth,
759
+ numTokens: gridTokens(nLlmH, nLlmW)
760
+ };
761
+ }
762
+ /** Resize so the patch grid fits the cap, then re-add the pad reserve. */
763
+ function safeResize(height, width, paddedHeight, paddedWidth) {
764
+ const nLlmH = ceilDiv(floorDiv(paddedHeight, PATCH_SIZE), DOWNSAMPLE_RATIO);
765
+ const nLlmW = ceilDiv(floorDiv(paddedWidth, PATCH_SIZE), DOWNSAMPLE_RATIO);
766
+ const pad = 3;
767
+ const budget = 381;
768
+ let result = {
769
+ nLlmH,
770
+ nLlmW,
771
+ bestHeight: paddedHeight,
772
+ bestWidth: paddedWidth,
773
+ numTokens: gridTokens(nLlmH, nLlmW)
774
+ };
775
+ if (result.numTokens > budget) {
776
+ result = solveResizeRatio(height, width, budget);
777
+ let nextBudget = budget;
778
+ while (result.numTokens > budget) {
779
+ nextBudget -= 1;
780
+ result = solveResizeRatio(height, width, nextBudget);
781
+ }
782
+ }
783
+ result.numTokens += pad;
784
+ return result;
785
+ }
786
+ function calcResizeInner(width, height) {
787
+ let w = width;
788
+ let h = height;
789
+ if (w > h * MAX_WH_RATIO) w = h * MAX_WH_RATIO;
790
+ const pixels = w * h;
791
+ if (pixels < MIN_PIXELS && pixels > 0) {
792
+ const scale = Math.sqrt(MIN_PIXELS / pixels);
793
+ w = Math.trunc(w * scale);
794
+ h = Math.trunc(h * scale);
795
+ }
796
+ const paddedWidth = ceilDiv(w, PATCH_SIZE) * PATCH_SIZE;
797
+ const paddedHeight = ceilDiv(h, PATCH_SIZE) * PATCH_SIZE;
798
+ return safeResize(h, w, paddedHeight, paddedWidth);
799
+ }
800
+ /**
801
+ * Estimate the tokens one image consumes in a DeepSeek vision request, from
802
+ * its pixel dimensions. Returns null for non-positive/non-finite dimensions
803
+ * or when the official iteration fails to converge — callers fall back to
804
+ * the generic structural price.
805
+ */
806
+ function estimateImageTokens(width, height) {
807
+ if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return null;
808
+ try {
809
+ let result = calcResizeInner(width, height);
810
+ for (let i = 1; i < 10; i++) {
811
+ const next = calcResizeInner(result.bestWidth, result.bestHeight);
812
+ if (next.nLlmH === result.nLlmH && next.nLlmW === result.nLlmW && next.bestHeight === result.bestHeight && next.bestWidth === result.bestWidth && next.numTokens === result.numTokens) return result.numTokens;
813
+ result = next;
814
+ }
815
+ return null;
816
+ } catch {
817
+ return null;
818
+ }
819
+ }
820
+ //#endregion
616
821
  //#region src/client/components/images.tsx
617
822
  /**
618
823
  * Narrow an unknown content block to a durable image reference. Accepts both
@@ -651,7 +856,7 @@ window.__ModuleLoader__.load({
651
856
  * records), and the stored byte size.
652
857
  */
653
858
  function makeImageCard(kit) {
654
- const { t } = kit;
859
+ const { t, fmt } = kit;
655
860
  return function ImageCard(props) {
656
861
  const { attachment, load } = props;
657
862
  const [src, setSrc] = React.useState(null);
@@ -682,6 +887,7 @@ window.__ModuleLoader__.load({
682
887
  if (dims !== null) facts.push(dims);
683
888
  if (orig !== void 0) facts.push(t("attach.orig", { d: `${orig.width}×${orig.height}` }));
684
889
  if (attachment.bytes !== void 0) facts.push(fmtBytes(attachment.bytes));
890
+ const tokens = attachment.width !== void 0 && attachment.height !== void 0 ? estimateImageTokens(attachment.width, attachment.height) : null;
685
891
  const open = () => {
686
892
  if (src === null) return;
687
893
  try {
@@ -701,7 +907,10 @@ window.__ModuleLoader__.load({
701
907
  }) : /* @__PURE__ */ React.createElement("span", { className: error ? "lc-att-err" : "lc-att-ph" }, error ? "⚠" : load === void 0 ? "🖼" : t("attach.loading"))), /* @__PURE__ */ React.createElement("div", { className: "lc-att-meta" }, /* @__PURE__ */ React.createElement("span", {
702
908
  className: "lc-att-name",
703
909
  title: name
704
- }, name), facts.length > 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-att-dims" }, facts.join(" · ")) : null));
910
+ }, name), facts.length > 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-att-dims" }, facts.join(" · ")) : null, tokens !== null ? /* @__PURE__ */ React.createElement("span", {
911
+ className: "lc-att-tokens",
912
+ title: t("attach.tokensTip")
913
+ }, t("attach.tokens", { n: fmt(tokens) })) : null));
705
914
  };
706
915
  }
707
916
  //#endregion
@@ -911,33 +1120,82 @@ window.__ModuleLoader__.load({
911
1120
  }));
912
1121
  }
913
1122
  /**
914
- * One assistant tool call as its own card, mirroring the tool-definition
915
- * parameter card: the head names the call target (with the parsed argument
916
- * count), the body lists the arguments as name/type/value rows. Arguments
917
- * that are not a parseable JSON object fall back to the raw payload inside
918
- * the same card.
1123
+ * Parse a call's raw argument payload into an object; null when the payload
1124
+ * is missing, malformed, or not a JSON object (callers fall back to the raw
1125
+ * text).
1126
+ */
1127
+ function parseArgs(raw) {
1128
+ if (typeof raw !== "string" || raw === "") return null;
1129
+ try {
1130
+ const parsed = JSON.parse(raw);
1131
+ return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
1132
+ } catch {
1133
+ return null;
1134
+ }
1135
+ }
1136
+ /**
1137
+ * The one-line summary a call's arguments carry about the call: a
1138
+ * bash-style `description` says what it does; path-taking tools (edit /
1139
+ * read / write) name their target via `file_path`/`path`/`filePath`. Null
1140
+ * when the arguments hold neither — the row then falls back to the generic
1141
+ * label.
1142
+ */
1143
+ function summaryIn(args) {
1144
+ if (args === null) return null;
1145
+ for (const k of [
1146
+ "description",
1147
+ "file_path",
1148
+ "path",
1149
+ "filePath"
1150
+ ]) {
1151
+ const v = args[k];
1152
+ if (typeof v === "string" && v !== "") return v;
1153
+ }
1154
+ return null;
1155
+ }
1156
+ /**
1157
+ * The summary of a tool result's own call — the collapsed row's preview.
1158
+ * Null when the call summarizes to nothing.
1159
+ */
1160
+ function callSummaryOf(conv) {
1161
+ return summaryIn(parseArgs(conv?.call?.argsRaw));
1162
+ }
1163
+ /**
1164
+ * The first call summary inside an assistant message's tool-call blocks —
1165
+ * the collapsed-row preview for a text-less assistant turn. Null when no
1166
+ * block summarizes.
1167
+ */
1168
+ function blockSummaryOf(conv) {
1169
+ if (conv === void 0 || !Array.isArray(conv.blocks)) return null;
1170
+ for (const b of conv.blocks) {
1171
+ const blk = b !== null && typeof b === "object" ? b : null;
1172
+ if (blk === null || blk.kind !== "tool-call") continue;
1173
+ const s = summaryIn(parseArgs(blk.argsRaw));
1174
+ if (s !== null) return s;
1175
+ }
1176
+ return null;
1177
+ }
1178
+ /**
1179
+ * One tool call as its own card, mirroring the tool-definition parameter
1180
+ * card: the head names the call target (with the parsed argument count),
1181
+ * the body lists the arguments as name/value rows. Arguments that are not
1182
+ * a parseable JSON object fall back to the raw payload inside the same
1183
+ * card. Shared by assistant tool-call blocks (`→`) and the call half of a
1184
+ * tool result (`←`).
919
1185
  */
920
1186
  function ToolCallCard(props) {
921
- const args = React.useMemo(() => {
922
- if (typeof props.argsRaw !== "string" || props.argsRaw === "") return null;
923
- try {
924
- const parsed = JSON.parse(props.argsRaw);
925
- return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
926
- } catch {
927
- return null;
928
- }
929
- }, [props.argsRaw]);
930
- return /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card-head" }, /* @__PURE__ */ React.createElement("b", null, "→ " + props.name), args !== null ? /* @__PURE__ */ React.createElement("span", { className: "lc-ts-card-count" }, Object.keys(args).length) : null), args !== null ? Object.keys(args).map((k) => /* @__PURE__ */ React.createElement(CallArgRow, {
1187
+ const args = React.useMemo(() => parseArgs(props.argsRaw), [props.argsRaw]);
1188
+ return /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-ts-card-head" }, /* @__PURE__ */ React.createElement("b", { className: "lc-ts-call-name" }, (props.arrow ?? "") + " " + props.name), args !== null ? /* @__PURE__ */ React.createElement("span", { className: "lc-ts-card-count" }, Object.keys(args).length) : null), args !== null ? Object.keys(args).map((k) => /* @__PURE__ */ React.createElement(CallArgRow, {
931
1189
  key: k,
932
1190
  name: k,
933
1191
  value: args[k]
934
1192
  })) : typeof props.argsRaw === "string" && props.argsRaw !== "" ? /* @__PURE__ */ React.createElement("pre", { className: "lc-br-pre lc-br-dim" }, props.argsRaw) : null);
935
1193
  }
936
- /** One parsed call argument: name, value type, and the value itself (full-width line). */
1194
+ /** One parsed call argument: the name on the left, the value on the right. */
937
1195
  function CallArgRow(props) {
938
1196
  const v = props.value;
939
1197
  const text = typeof v === "string" ? v : v === void 0 ? "" : JSON.stringify(v);
940
- return /* @__PURE__ */ React.createElement("div", { className: "lc-ts-param-row" }, /* @__PURE__ */ React.createElement("span", { className: "lc-ts-param-name" }, props.name), /* @__PURE__ */ React.createElement("span", { className: "lc-ts-param-type" }, v === null ? "null" : Array.isArray(v) ? "array" : typeof v), /* @__PURE__ */ React.createElement("span", { className: "lc-ts-param-desc" }, text));
1198
+ return /* @__PURE__ */ React.createElement("div", { className: "lc-ts-arg-row" }, /* @__PURE__ */ React.createElement("span", { className: "lc-ts-param-name" }, props.name), /* @__PURE__ */ React.createElement("span", { className: "lc-ts-arg-val" }, text));
941
1199
  }
942
1200
  /** The actual content of one surface element, joined from the conversation snapshot. */
943
1201
  function NodeContent(props) {
@@ -978,7 +1236,11 @@ window.__ModuleLoader__.load({
978
1236
  });
979
1237
  return null;
980
1238
  }));
981
- if (conv.kind === "tool-result") return /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, conv.call != null ? /* @__PURE__ */ React.createElement("div", { className: "lc-br-call" }, /* @__PURE__ */ React.createElement("span", { className: "lc-br-tag" }, "← " + conv.call.name), conv.call.argsRaw !== "" ? /* @__PURE__ */ React.createElement("pre", { className: "lc-br-pre lc-br-dim" }, conv.call.argsRaw) : null) : null, Array.isArray(conv.content) ? /* @__PURE__ */ React.createElement(RawBlocks, {
1239
+ if (conv.kind === "tool-result") return /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, conv.call != null ? /* @__PURE__ */ React.createElement(ToolCallCard, {
1240
+ arrow: "←",
1241
+ name: conv.call.name,
1242
+ argsRaw: conv.call.argsRaw
1243
+ }) : null, Array.isArray(conv.content) ? /* @__PURE__ */ React.createElement(RawBlocks, {
982
1244
  blocks: conv.content,
983
1245
  mode: "raw",
984
1246
  rich,
@@ -1144,7 +1406,7 @@ window.__ModuleLoader__.load({
1144
1406
  setOpenElem(openElem === key ? null : key);
1145
1407
  };
1146
1408
  /** One expandable element row (preview line; content when open). */
1147
- const elemRow = (key, tag, preview, tokens, time, body) => {
1409
+ const elemRow = (key, tag, preview, tokens, time, body, inv = false) => {
1148
1410
  const open = openElem === key;
1149
1411
  return /* @__PURE__ */ React.createElement("div", {
1150
1412
  key,
@@ -1155,7 +1417,7 @@ window.__ModuleLoader__.load({
1155
1417
  onClick: () => {
1156
1418
  toggleElem(key);
1157
1419
  }
1158
- }, /* @__PURE__ */ React.createElement("span", { className: "lc-br-chev" + (open ? " lc-br-chev-on" : "") }, "▸"), tag !== null ? /* @__PURE__ */ React.createElement("span", { className: "lc-br-tag" }, tag) : null, /* @__PURE__ */ React.createElement("span", { className: "lc-br-preview" }, preview), time !== void 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-br-time" }, fmtTime(time)) : null, /* @__PURE__ */ React.createElement("span", { className: "lc-br-tokens" }, "≈" + fmt(tokens))), open ? body : null);
1420
+ }, /* @__PURE__ */ React.createElement("span", { className: "lc-br-chev" + (open ? " lc-br-chev-on" : "") }, "▸"), tag !== null ? /* @__PURE__ */ React.createElement("span", { className: "lc-br-tag" + (inv ? " lc-br-tag-inv" : "") }, tag) : null, /* @__PURE__ */ React.createElement("span", { className: "lc-br-preview" }, preview), time !== void 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-br-time" }, fmtTime(time)) : null, /* @__PURE__ */ React.createElement("span", { className: "lc-br-tokens" }, "≈" + fmt(tokens))), open ? body : null);
1159
1421
  };
1160
1422
  const catBody = (c) => {
1161
1423
  if (c === "system") {
@@ -1187,11 +1449,18 @@ window.__ModuleLoader__.load({
1187
1449
  }
1188
1450
  return (byCat[c] ?? []).slice().reverse().map((n) => {
1189
1451
  let tag = null;
1452
+ let inv = false;
1190
1453
  let preview = nodeText(n);
1191
1454
  if (n.cat === "tool") {
1192
1455
  tag = (n.tool ?? "?") + (n.err ? " ⚠" : "");
1193
- preview = t("node.toolResult") + (n.err ? " ⚠" : "");
1194
- } else if (n.cat === "inject" && !n.skill) {
1456
+ inv = true;
1457
+ preview = callSummaryOf(bySeq.get(n.seq)) ?? t("node.toolResult") + (n.err ? " ⚠" : "");
1458
+ } else if (n.cat === "assistant" && Array.isArray(n.calls) && n.calls.length > 0) {
1459
+ tag = n.calls.join(" › ");
1460
+ inv = true;
1461
+ preview = (n.text !== void 0 && n.text !== "" ? n.text : null) ?? blockSummaryOf(bySeq.get(n.seq)) ?? t("node.empty");
1462
+ } else if (n.cat === "assistant" && (n.text === void 0 || n.text === "")) preview = blockSummaryOf(bySeq.get(n.seq)) ?? preview;
1463
+ else if (n.cat === "inject" && !n.skill) {
1195
1464
  tag = t("form." + (n.form || "context"));
1196
1465
  if (n.text !== void 0 && n.text !== "") preview = n.form === "snapshot" ? t("node.snapshot") + n.text : n.text;
1197
1466
  }
@@ -1210,7 +1479,7 @@ window.__ModuleLoader__.load({
1210
1479
  other: t("attach.other")
1211
1480
  },
1212
1481
  hint: bySeq.get(n.seq) === void 0 && awaiting ? t("browser.loading") : t("browser.noContent")
1213
- }));
1482
+ }), inv);
1214
1483
  });
1215
1484
  };
1216
1485
  return /* @__PURE__ */ React.createElement("div", { className: "lc-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("browser.title")), /* @__PURE__ */ React.createElement("span", { className: "lc-br-hint" }, t("browser.deltaHint")), /* @__PURE__ */ React.createElement("select", {
@@ -1304,11 +1573,14 @@ window.__ModuleLoader__.load({
1304
1573
  };
1305
1574
  } else {
1306
1575
  let acc = 0;
1576
+ let rawTotal = 0;
1577
+ for (const p of props.parts) rawTotal += p.raw ?? p.value;
1307
1578
  for (const p of props.parts) {
1308
1579
  const pct = scale > 0 ? p.value / scale * 100 : 0;
1309
1580
  if (p.key === props.hoverKey && p.value > 0) {
1581
+ const count = p.raw ?? p.value;
1310
1582
  tip = {
1311
- text: `${catLabel(p.key)} ≈${fmt(p.value)} (${Math.round(p.value / total * 100)}%) ` + t("overview.ofUsed"),
1583
+ text: `${catLabel(p.key)} ≈${fmt(count)} (${rawTotal > 0 ? Math.round(count / rawTotal * 100) : 0}%) ` + t("overview.ofUsed"),
1312
1584
  leftPct: Math.max(12, Math.min(acc + pct / 2, 88))
1313
1585
  };
1314
1586
  break;
@@ -1371,8 +1643,9 @@ window.__ModuleLoader__.load({
1371
1643
  const { t, fmt, catLabel } = kit;
1372
1644
  return function Legend(props) {
1373
1645
  let total = 0;
1374
- for (const p of props.parts) total += p.value;
1646
+ for (const p of props.parts) total += p.raw ?? p.value;
1375
1647
  return /* @__PURE__ */ React.createElement("div", { className: "lc-legend" }, props.parts.map((p) => {
1648
+ const count = p.raw ?? p.value;
1376
1649
  const on = props.hoverKey !== void 0 && props.hoverKey === p.key;
1377
1650
  return /* @__PURE__ */ React.createElement("span", {
1378
1651
  key: p.key,
@@ -1384,7 +1657,7 @@ window.__ModuleLoader__.load({
1384
1657
  onMouseLeave: () => {
1385
1658
  if (props.onHoverKey !== void 0) props.onHoverKey(null);
1386
1659
  }
1387
- }, /* @__PURE__ */ React.createElement("i", { style: { background: p.color } }), /* @__PURE__ */ React.createElement("span", { className: "lc-chip-label" }, catLabel(p.key)), /* @__PURE__ */ React.createElement("span", { className: "lc-chip-nums" }, "≈" + fmt(p.value), total > 0 ? /* @__PURE__ */ React.createElement("em", null, `${Math.round(p.value / total * 100)}%`) : null));
1660
+ }, /* @__PURE__ */ React.createElement("i", { style: { background: p.color } }), /* @__PURE__ */ React.createElement("span", { className: "lc-chip-label" }, catLabel(p.key)), /* @__PURE__ */ React.createElement("span", { className: "lc-chip-nums" }, "≈" + fmt(count), total > 0 ? /* @__PURE__ */ React.createElement("em", null, `${Math.round(count / total * 100)}%`) : null));
1388
1661
  }));
1389
1662
  };
1390
1663
  }
@@ -1469,6 +1742,7 @@ window.__ModuleLoader__.load({
1469
1742
  const open = typeof props.useContextModal === "function" ? props.useContextModal((s) => s) : false;
1470
1743
  const data = typeof props.useProjection === "function" ? timelineOf(props.useProjection("contextTimeline")) : null;
1471
1744
  const pressure = typeof props.useProjection === "function" ? contextPressureOf(props.useProjection("contextPressure")) : null;
1745
+ const breakdown = typeof props.useProjection === "function" ? contextBreakdownOf(props.useProjection("contextBreakdown")) : null;
1472
1746
  const headers = typeof props.useProjection === "function" ? headersOf(props.useProjection("contextHeaders")) : null;
1473
1747
  const [hoverCat, setHoverCat] = React.useState(null);
1474
1748
  const [toolFocus, setToolFocus] = React.useState(null);
@@ -1496,7 +1770,7 @@ window.__ModuleLoader__.load({
1496
1770
  };
1497
1771
  }, [open, close]);
1498
1772
  if (!open) return null;
1499
- const head = data !== null ? headlineOf(data, pressure) : null;
1773
+ const head = data !== null ? headlineOf(data, pressure, breakdown) : null;
1500
1774
  const subtitle = data !== null ? (data.model ? data.model : "") + (data.provider ? " · " + data.provider : "") : "";
1501
1775
  return /* @__PURE__ */ React.createElement("div", {
1502
1776
  className: "lc-modal-backdrop",
@@ -1677,7 +1951,7 @@ window.__ModuleLoader__.load({
1677
1951
  return function PluginInfo() {
1678
1952
  const [latest, setLatest] = React.useState(null);
1679
1953
  React.useEffect(() => {
1680
- if ("0.22.2".includes("-dev")) return;
1954
+ if ("0.24.0".includes("-dev")) return;
1681
1955
  let on = true;
1682
1956
  fetchLatestVersion().then((v) => {
1683
1957
  if (on && v) setLatest(v);
@@ -1686,8 +1960,8 @@ window.__ModuleLoader__.load({
1686
1960
  on = false;
1687
1961
  };
1688
1962
  }, []);
1689
- const update = latest !== null && isNewerVersion(latest, "0.22.2") ? latest : null;
1690
- const nameValue = ["dsh-context (v0.22.2)"];
1963
+ const update = latest !== null && isNewerVersion(latest, "0.24.0") ? latest : null;
1964
+ const nameValue = ["dsh-context (v0.24.0)"];
1691
1965
  if (update) nameValue.push(/* @__PURE__ */ React.createElement("span", {
1692
1966
  key: "update",
1693
1967
  className: "lc-pi-update"
@@ -1943,11 +2217,39 @@ window.__ModuleLoader__.load({
1943
2217
  const BAR_W = 14;
1944
2218
  const BAR_GAP = 2;
1945
2219
  const TURN_FILLS = ["rgba(128,128,128,0.12)", "rgba(128,128,128,0.26)"];
2220
+ const anchorOf = (req) => typeof req.prompt === "number" && req.prompt > 0 && req.total > 0 ? req.prompt / req.total : 1;
2221
+ const barTotalOf = (req) => typeof req.prompt === "number" && req.prompt > 0 ? req.prompt : req.total;
2222
+ const ChartBar = React.memo(function ChartBar(props) {
2223
+ const { req, marker } = props;
2224
+ const markerAt = marker !== void 0 ? eventAt(marker) : null;
2225
+ return /* @__PURE__ */ React.createElement("div", {
2226
+ className: "lc-bar" + (props.selected ? " lc-bar-selected" : "") + (props.hovered ? " lc-bar-hovered" : "") + (props.inTurn ? " lc-bar-in-turn" : ""),
2227
+ "data-seq": req.seq,
2228
+ style: { width: `${BAR_W}px` },
2229
+ onClick: () => {
2230
+ props.onSelect(props.selected ? null : req.seq);
2231
+ },
2232
+ onMouseEnter: () => {
2233
+ props.onHover(req.seq);
2234
+ }
2235
+ }, marker !== void 0 ? /* @__PURE__ */ React.createElement("span", {
2236
+ className: "lc-bar-marker",
2237
+ title: "✂ " + (markerAt !== null ? markerAt + " — " : "") + eventLabel(marker)
2238
+ }, "✂") : null, /* @__PURE__ */ React.createElement("div", { className: "lc-bar-stack" }, CATS.map((c) => {
2239
+ const v = (req[c.key] || 0) * anchorOf(req);
2240
+ if (!v) return null;
2241
+ return /* @__PURE__ */ React.createElement("div", {
2242
+ key: c.key,
2243
+ style: {
2244
+ height: `${Math.max(1, Math.round(v / props.maxTotal * CHART_H))}px`,
2245
+ background: c.color
2246
+ }
2247
+ });
2248
+ })));
2249
+ });
1946
2250
  return function TrendChart(props) {
1947
2251
  const requests = props.requests;
1948
2252
  const markers = props.markers;
1949
- const anchorOf = (req) => typeof req.prompt === "number" && req.prompt > 0 && req.total > 0 ? req.prompt / req.total : 1;
1950
- const barTotalOf = (req) => typeof req.prompt === "number" && req.prompt > 0 ? req.prompt : req.total;
1951
2253
  let maxTotal = 1;
1952
2254
  for (const req of requests) {
1953
2255
  const bt = barTotalOf(req);
@@ -1997,6 +2299,14 @@ window.__ModuleLoader__.load({
1997
2299
  lastGranRef.current = props.granularity;
1998
2300
  scrolledOnce.current = false;
1999
2301
  }
2302
+ if (props.focusTurn !== null) {
2303
+ const gi = groups.findIndex((g) => g.turn === props.focusTurn);
2304
+ if (gi >= 0) {
2305
+ scrolledOnce.current = true;
2306
+ el.scrollLeft = Math.max(0, gi * 16 + BAR_W / 2 - el.clientWidth / 2);
2307
+ }
2308
+ props.onFocusTurnHandled();
2309
+ }
2000
2310
  if (!scrolledOnce.current) {
2001
2311
  scrolledOnce.current = true;
2002
2312
  el.scrollLeft = el.scrollWidth;
@@ -2025,37 +2335,17 @@ window.__ModuleLoader__.load({
2025
2335
  onMouseLeave: () => {
2026
2336
  props.onHover(null);
2027
2337
  }
2028
- }, /* @__PURE__ */ React.createElement("div", { className: "lc-grid lc-grid-top" }), /* @__PURE__ */ React.createElement("div", { className: "lc-grid lc-grid-mid" }), requests.map((req, i) => {
2029
- const marker = markers[i];
2030
- const markerAt = marker !== void 0 ? eventAt(marker) : null;
2031
- const selected = props.selectedSeq === req.seq;
2032
- const hovered = props.hoveredSeq === req.seq;
2033
- const inTurn = props.activeTurn !== null && (req.turn ?? 0) === props.activeTurn;
2034
- return /* @__PURE__ */ React.createElement("div", {
2035
- key: req.seq,
2036
- className: "lc-bar" + (selected ? " lc-bar-selected" : "") + (hovered ? " lc-bar-hovered" : "") + (inTurn ? " lc-bar-in-turn" : ""),
2037
- style: { width: `${BAR_W}px` },
2038
- onClick: () => {
2039
- props.onSelect(selected ? null : req.seq);
2040
- },
2041
- onMouseEnter: () => {
2042
- props.onHover(req.seq);
2043
- }
2044
- }, marker !== void 0 ? /* @__PURE__ */ React.createElement("span", {
2045
- className: "lc-bar-marker",
2046
- title: "✂ " + (markerAt !== null ? markerAt + " — " : "") + eventLabel(marker)
2047
- }, "✂") : null, /* @__PURE__ */ React.createElement("div", { className: "lc-bar-stack" }, CATS.map((c) => {
2048
- const v = (req[c.key] || 0) * anchorOf(req);
2049
- if (!v) return null;
2050
- return /* @__PURE__ */ React.createElement("div", {
2051
- key: c.key,
2052
- style: {
2053
- height: `${Math.max(1, Math.round(v / maxTotal * CHART_H))}px`,
2054
- background: c.color
2055
- }
2056
- });
2057
- })));
2058
- })), hoveredReq !== null ? /* @__PURE__ */ React.createElement("div", {
2338
+ }, /* @__PURE__ */ React.createElement("div", { className: "lc-grid lc-grid-top" }), /* @__PURE__ */ React.createElement("div", { className: "lc-grid lc-grid-mid" }), requests.map((req, i) => /* @__PURE__ */ React.createElement(ChartBar, {
2339
+ key: req.seq,
2340
+ req,
2341
+ marker: markers[i],
2342
+ selected: props.selectedSeq === req.seq,
2343
+ hovered: props.hoveredSeq === req.seq,
2344
+ inTurn: props.activeTurn !== null && (req.turn ?? 0) === props.activeTurn,
2345
+ maxTotal,
2346
+ onSelect: props.onSelect,
2347
+ onHover: props.onHover
2348
+ }))), hoveredReq !== null ? /* @__PURE__ */ React.createElement("div", {
2059
2349
  className: "lc-chart-tip",
2060
2350
  style: { left: `${hoveredIdx * 16 + BAR_W / 2}px` }
2061
2351
  }, tipOf(hoveredReq)) : null, /* @__PURE__ */ React.createElement("div", {
@@ -2076,6 +2366,9 @@ window.__ModuleLoader__.load({
2076
2366
  title: `T${grp.turn}`,
2077
2367
  onMouseEnter: () => {
2078
2368
  props.onHoverTurn(grp.turn);
2369
+ },
2370
+ onClick: () => {
2371
+ props.onPickTurn(grp.turn);
2079
2372
  }
2080
2373
  }, `T${grp.turn}`);
2081
2374
  }))), edges.right ? /* @__PURE__ */ React.createElement("div", { className: "lc-chart-fade lc-chart-fade-r" }) : null);
@@ -2107,12 +2400,14 @@ window.__ModuleLoader__.load({
2107
2400
  const data = typeof props.useProjection === "function" ? timelineOf(props.useProjection("contextTimeline")) : null;
2108
2401
  const pressure = typeof props.useProjection === "function" ? contextPressureOf(props.useProjection("contextPressure")) : null;
2109
2402
  const usage = typeof props.useProjection === "function" ? tokenUsageOf(props.useProjection("tokenUsage")) : null;
2403
+ const breakdown = typeof props.useProjection === "function" ? contextBreakdownOf(props.useProjection("contextBreakdown")) : null;
2110
2404
  const headers = typeof props.useProjection === "function" ? headersOf(props.useProjection("contextHeaders")) : null;
2111
2405
  const [selectedSeq, setSelectedSeq] = React.useState(null);
2112
2406
  const [hoveredSeq, setHoveredSeq] = React.useState(null);
2113
2407
  const [hoverTurn, setHoverTurn] = React.useState(null);
2114
2408
  const [tick, setTick] = React.useState(0);
2115
2409
  const [granularity, setGranularity] = React.useState("step");
2410
+ const [focusTurn, setFocusTurn] = React.useState(null);
2116
2411
  const [hoverCat, setHoverCat] = React.useState(null);
2117
2412
  const [pickedKinds, setPickedKinds] = React.useState([...EVENT_KINDS]);
2118
2413
  const toggleKind = (k) => {
@@ -2167,8 +2462,8 @@ window.__ModuleLoader__.load({
2167
2462
  const events = data.events;
2168
2463
  const shownEvents = pickedKinds.length === EVENT_KINDS.length ? events : events.filter((e) => pickedKinds.includes(e.kind));
2169
2464
  const nodes = data.nodes;
2170
- const displayRequests = granularity === "turn" ? aggregateByTurn(requests) : requests;
2171
- const markers = attachMarkers(displayRequests, events);
2465
+ const displayRequests = React.useMemo(() => granularity === "turn" ? aggregateByTurn(requests) : requests, [requests, granularity]);
2466
+ const markers = React.useMemo(() => attachMarkers(displayRequests, events), [displayRequests, events]);
2172
2467
  const markerOf = (req) => {
2173
2468
  const i = displayRequests.indexOf(req);
2174
2469
  return i >= 0 ? markers[i] : void 0;
@@ -2188,7 +2483,7 @@ window.__ModuleLoader__.load({
2188
2483
  break;
2189
2484
  }
2190
2485
  }
2191
- const head = headlineOf(data, pressure);
2486
+ const head = headlineOf(data, pressure, breakdown);
2192
2487
  const localeSvc = ctx.get("locale");
2193
2488
  const activeLocale = localeSvc !== void 0 && typeof localeSvc.getLocale === "function" ? localeSvc.getLocale().active : "en";
2194
2489
  return /* @__PURE__ */ React.createElement("div", {
@@ -2225,9 +2520,17 @@ window.__ModuleLoader__.load({
2225
2520
  hoveredSeq,
2226
2521
  activeTurn,
2227
2522
  granularity,
2523
+ focusTurn,
2228
2524
  onSelect: setSelectedSeq,
2229
2525
  onHover: setHoveredSeq,
2230
- onHoverTurn: setHoverTurn
2526
+ onHoverTurn: setHoverTurn,
2527
+ onPickTurn: (turn) => {
2528
+ setGranularity("turn");
2529
+ setFocusTurn(turn);
2530
+ },
2531
+ onFocusTurnHandled: () => {
2532
+ setFocusTurn(null);
2533
+ }
2231
2534
  }), /* @__PURE__ */ React.createElement(RequestDetail, {
2232
2535
  request: activeReq,
2233
2536
  marker: activeReq !== null ? markerOf(activeReq) : void 0
@@ -2273,7 +2576,7 @@ window.__ModuleLoader__.load({
2273
2576
  }
2274
2577
  //#endregion
2275
2578
  //#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles.css.mjs
2276
- const css = ".lc-root{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-primary);padding:16px 20px 32px;font-size:13px;overflow-y:auto}.lc-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;margin-bottom:14px;padding:14px 16px}.lc-card-title{align-items:baseline;gap:8px;margin-bottom:10px;font-weight:600;display:flex}.lc-card-title-text{white-space:nowrap;flex:none}.lc-stats{grid-template-columns:repeat(auto-fit,minmax(92px,1fr));gap:8px;display:grid}.lc-stat{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-direction:column;gap:2px;min-width:0;padding:8px 10px;display:flex}.lc-stat-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:600;overflow:hidden}.lc-stat-value{color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:14px;font-weight:600;overflow:hidden}.lc-stat-sub{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.lc-stat-tipped{position:relative}.lc-stat-q{text-align:center;width:11px;height:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);cursor:help;border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tipped:hover .lc-stat-q{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary)}.lc-stat-tip{z-index:6;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;max-width:280px;color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:6px 10px;font-size:12px;font-weight:400;line-height:1.5;transition:opacity .12s;position:absolute;top:calc(100% + 6px);left:0;box-shadow:0 2px 8px #0000002e}.lc-stat-tipped:hover .lc-stat-tip{opacity:1}.lc-stat-tip-prices{border-top:1px dashed var(--dsw-alias-border-l1);margin-top:5px;padding-top:5px;display:block}.lc-stat-tip-head{font-weight:600;display:block}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-model{color:var(--dsw-alias-label-primary)}.lc-card-sub{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:400}.lc-gran,.lc-kinds{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-gran-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-gran-btn:hover{color:var(--dsw-alias-label-primary)}.lc-gran-on,.lc-gran-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-overview-num{align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.lc-overview-num>b{font-size:20px}.lc-overview-num span{color:var(--dsw-alias-label-secondary)}.lc-overview-pct{margin-left:auto;font-size:11px}.lc-overview-pct b{color:var(--dsw-alias-label-primary);margin-right:4px;font-size:20px}.lc-stacked-wrap{width:100%;position:relative}.lc-stacked{background:#8080802e;border-radius:5px;width:100%;display:flex;position:relative;overflow:hidden}.lc-occupied-box{border:2px solid var(--dsw-alias-label-tertiary);box-sizing:border-box;pointer-events:none;opacity:0;box-shadow:0 0 0 1px var(--dsw-alias-bg-layer-2);border-radius:5px;transition:opacity .12s;position:absolute;top:0;bottom:0;left:0}.lc-occupied-box-on{opacity:1}.lc-bar-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:3px 8px;font-size:12px;transition:opacity .12s;position:absolute;bottom:calc(100% + 6px);transform:translate(-50%);box-shadow:0 2px 8px #0000002e}.lc-bar-tip-on{opacity:1}.lc-stacked>div{height:100%}.lc-stacked-seg{transition:filter .12s,opacity .12s}.lc-stacked-free{box-sizing:border-box;transition:box-shadow .12s,opacity .12s}.lc-stacked-seg-on{filter:brightness(1.18)}.lc-reserve{z-index:1;pointer-events:auto;cursor:help;background:repeating-linear-gradient(45deg, color-mix(in srgb, var(--dsw-alias-state-warn-primary) 24%, transparent) 0 5px, transparent 5px 10px);position:absolute;top:0;bottom:0}.lc-stacked-free-on{border:2px dashed var(--dsw-alias-label-secondary);border-radius:3px}.lc-stacked-dim .lc-stacked-seg{opacity:.35}.lc-stacked-dim .lc-stacked-seg-on{opacity:1}.lc-stacked-dim .lc-stacked-free{opacity:.35}.lc-stacked-dim .lc-stacked-free-on{opacity:1}.lc-legend{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:6px 14px;margin-top:10px;display:grid}.lc-chip{min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:5px;padding:1px 6px;transition:background-color .12s;display:flex}.lc-chip-label{white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}.lc-chip-nums{white-space:nowrap;flex:none;align-items:baseline;gap:6px;margin-left:auto;display:inline-flex}.lc-chip i,.lc-detail-row i,.lc-node i{border-radius:2px;width:8px;height:8px;display:inline-block}.lc-chip i{transition:box-shadow .12s}.lc-chip em{color:var(--dsw-alias-label-secondary);font-style:normal}.lc-chip-on{background:var(--dsw-alias-interactive-bg-hover);font-weight:600}.lc-chip-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-tools{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;align-items:center;gap:6px;margin-top:10px;display:flex}.lc-tools-label,.lc-tools-more{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;padding:0;font-family:inherit;font-size:12px}.lc-tools-label:hover,.lc-tools-more:hover{text-decoration:underline}.lc-tool-chip{background:var(--dsw-alias-bg-layer-2);font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:0;border-radius:4px;padding:1px 7px;font-size:12px}.lc-tool-chip:hover{text-decoration:underline}.lc-chartrow{align-items:stretch;gap:6px;display:flex}.lc-axis{box-sizing:border-box;width:40px;height:150px;color:var(--dsw-alias-label-secondary);padding-top:18px;font-size:11px;position:relative}.lc-axis span{line-height:1;position:absolute;right:0}.lc-axis-top{top:13px}.lc-axis-mid{top:69px}.lc-axis-bot{top:125px}.lc-chart-scroll{scrollbar-width:thin;flex:1;min-width:0;position:relative;overflow:auto hidden}.lc-chart-fade{pointer-events:none;z-index:2;width:26px;position:absolute;top:0;bottom:0}.lc-chart-fade-l{background:linear-gradient(to right, var(--dsw-alias-bg-layer-1), transparent);left:0}.lc-chart-fade-r{background:linear-gradient(to left, var(--dsw-alias-bg-layer-1), transparent);right:0}.lc-chart{box-sizing:border-box;align-items:flex-end;gap:2px;width:max-content;min-width:100%;height:130px;padding-top:18px;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-l1);pointer-events:none;position:absolute;left:0;right:0}.lc-grid-top{top:18px}.lc-grid-mid{top:74px}.lc-bar{cursor:pointer;border-radius:2px;flex:none;align-items:flex-end;width:14px;height:100%;transition:opacity .12s,background-color .12s;display:flex;position:relative}.lc-chart-dim .lc-bar{opacity:.35}.lc-chart-dim .lc-bar-in-turn{opacity:1}.lc-chart-dim .lc-turn{opacity:.35}.lc-chart-dim .lc-turn-on{opacity:1}.lc-chart-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;border-radius:6px;padding:3px 8px;font-size:12px;position:absolute;top:0;transform:translate(-50%);box-shadow:0 2px 8px #0000002e}.lc-bar:hover{background:var(--dsw-alias-bg-layer-2)}.lc-bar-hovered{outline:1px dashed var(--dsw-alias-brand-primary);outline-offset:1px}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:#80808024}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-marker{color:var(--dsw-alias-state-warn-primary);font-size:11px;position:absolute;top:-16px;left:50%;transform:translate(-50%)}.lc-turns{gap:2px;width:max-content;min-width:100%;margin-top:4px;display:flex}.lc-turn{box-sizing:border-box;text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;cursor:default;border-radius:3px;flex:none;height:14px;font-size:10px;font-weight:600;line-height:14px;transition:filter .12s,opacity .12s;overflow:hidden}.lc-turn-on{filter:brightness(1.35);color:var(--dsw-alias-label-primary)}.lc-detail{border-top:1px solid var(--dsw-alias-border-l1);margin-top:12px;padding-top:12px}.lc-detail-head{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-detail-head b{color:var(--dsw-alias-label-primary)}.lc-detail-marker{color:var(--dsw-alias-state-warn-primary);background:var(--dsw-alias-bg-layer-2);border-radius:6px;padding:1px 7px;font-size:11px}.lc-detail-head .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-detail-tag{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:4px;padding:0 6px;font-size:11px}.lc-detail-rows{grid-template-columns:1fr 1fr;gap:4px 24px;margin-top:10px;display:grid}.lc-detail-row{align-items:center;gap:8px;display:flex}.lc-detail-label{white-space:nowrap;min-width:70px;color:var(--dsw-alias-label-secondary)}.lc-bar-track{background:#8080802e;border-radius:3px;flex:1;height:5px;display:block;overflow:hidden}.lc-bar-fill{border-radius:3px;height:100%;display:block}.lc-detail-num{text-align:right;width:44px}.lc-detail-pct{text-align:right;width:34px;color:var(--dsw-alias-label-secondary)}.lc-cols{flex-wrap:wrap;gap:14px;margin-bottom:14px;display:flex}.lc-col{flex:1;min-width:280px}.lc-cols>.lc-card,.lc-col>.lc-card:last-child{margin-bottom:0}.lc-head>.lc-card:first-child{flex:7 1 0;min-width:360px}.lc-head>.lc-card:last-child{flex:3 1 0;min-width:220px}.lc-pi-grid{grid-template-columns:1fr;gap:8px;display:grid}.lc-pi-row{min-width:0;color:inherit;flex-direction:row;justify-content:space-between;align-items:baseline;gap:12px;text-decoration:none;display:flex}.lc-pi-row:hover .lc-pi-value{text-decoration:underline}.lc-pi-update{color:var(--dsw-alias-state-warn-primary);white-space:nowrap;margin-left:6px;font-size:11px}.lc-pi-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:none;font-size:11px;font-weight:600;overflow:hidden}.lc-pi-value{min-width:0;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:right;font-size:13px;font-weight:600;overflow:hidden}.lc-events,.lc-nodes{flex-direction:column;gap:2px;max-height:320px;display:flex;overflow-y:auto}.lc-event{align-items:center;gap:8px;padding:3px 0;display:flex}.lc-event-icon{text-align:center;width:18px;color:var(--dsw-alias-state-warn-primary)}.lc-event-icon.lc-event-inject{color:#a855f7}.lc-event-icon.lc-event-model{color:var(--dsw-alias-brand-primary)}.lc-kind{white-space:nowrap;border-radius:4px;flex:none;padding:1px 6px;font-size:10px;font-weight:600}.lc-kind-inject{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent);color:var(--dsw-alias-state-success-primary)}.lc-kind-compaction{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent);color:var(--dsw-alias-state-error-primary)}.lc-kind-prune{color:#8b5cf6;background:#8b5cf626}.lc-kind-model{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 15%, transparent);color:var(--dsw-alias-brand-primary)}.lc-event-label{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.lc-event-at{color:var(--dsw-alias-label-secondary);white-space:nowrap;flex:none;font-size:11px}.lc-event-tokens{color:var(--dsw-alias-state-success-primary);white-space:nowrap;font-weight:600}.lc-event-tokens.lc-up{color:var(--dsw-alias-state-warn-primary)}.lc-event-time{color:var(--dsw-alias-label-secondary);font-size:12px}.lc-node{align-items:center;gap:8px;padding:3px 0;display:flex}.lc-node-preview{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);flex:1;overflow:hidden}.lc-node-time{color:var(--dsw-alias-label-secondary);text-align:right;min-width:54px;font-size:12px}.lc-node-tokens{color:var(--dsw-alias-label-secondary)}.lc-nodes-more{color:var(--dsw-alias-label-secondary);padding:3px 0}.lc-empty{color:var(--dsw-alias-label-secondary);text-align:center;padding:18px 0}.lc-error{flex-direction:column;align-items:center;gap:8px;padding:40px 16px;display:flex}.lc-error-msg{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);overflow-wrap:anywhere;border-radius:6px;max-width:100%;padding:4px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.lc-error-retry{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:6px;padding:4px 14px;font-size:12px}.lc-error-retry:hover{border-color:var(--dsw-alias-label-primary)}.lc-foot{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:12px}.lc-modal-backdrop{z-index:200;background:#00000073;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.lc-modal-card{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);width:min(720px,100vw - 48px);max-height:min(82vh,760px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);color:var(--dsw-alias-label-primary);border-radius:12px;padding:16px 18px 18px;font-size:13px;overflow-y:auto}.lc-modal-head{align-items:baseline;gap:8px;margin-bottom:12px;display:flex}.lc-modal-title{font-size:14px;font-weight:600}.lc-modal-close{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;margin-left:auto;padding:2px 6px;font-family:inherit;font-size:18px;line-height:1}.lc-modal-close:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.lc-br-hint{color:var(--dsw-alias-label-secondary);white-space:nowrap;margin-left:auto;font-size:11px;font-weight:400}.lc-br-pick{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;max-width:240px;padding:3px 6px;font-size:12px}.lc-br-meta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-br-meta b{color:var(--dsw-alias-label-primary)}.lc-br-meta .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-br-note{color:var(--dsw-alias-label-secondary);margin-top:8px;font-size:12px}.lc-br-cats{flex-direction:column;gap:4px;margin-top:10px;display:flex}.lc-br-cat{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:8px;overflow:hidden}.lc-br-cat-empty{opacity:.55}.lc-br-cat-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;transition:background-color .12s;display:flex}.lc-br-cat-row:hover,.lc-br-cat-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-cat-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-br-cat-row i{border-radius:2px;flex:none;width:8px;height:8px;transition:box-shadow .12s;display:inline-block}.lc-br-cat-label{font-weight:600}.lc-br-cat-count{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:12px}.lc-br-count-grp{flex:1;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-chev{width:12px;color:var(--dsw-alias-label-secondary);flex:none;transition:transform .12s}.lc-br-chev-on{transform:rotate(90deg)}.lc-br-tokens{color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-delta,.lc-br-tdelta{white-space:nowrap;border-radius:4px;flex:none;padding:0 5px;font-size:11px;font-weight:600}.lc-br-delta-up,.lc-br-tdelta-up{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent)}.lc-br-delta-down,.lc-br-tdelta-down{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent)}.lc-br-tokens-grp{flex:none;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-pct{text-align:right;width:36px;color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-body{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:2px;padding:4px 6px;display:flex}.lc-br-elem{border-radius:6px}.lc-br-elem-on{background:var(--dsw-alias-interactive-bg-active)}.lc-br-elem-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;padding:5px 6px;font-size:12px;transition:background-color .12s;display:flex}.lc-br-elem-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-tag{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);text-overflow:ellipsis;white-space:nowrap;border-radius:4px;flex:none;max-width:220px;padding:0 6px;font-size:11px;overflow:hidden}.lc-br-preview{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-br-time{color:var(--dsw-alias-label-secondary);flex:none;font-size:11px}.lc-br-content{flex-direction:column;gap:6px;padding:2px 6px 8px 26px;display:flex}.lc-br-pre{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;border-radius:6px;max-height:320px;margin:0;padding:8px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-br-dim{color:var(--dsw-alias-label-secondary)}.lc-br-call{flex-direction:column;align-items:flex-start;gap:4px;display:flex}.lc-br-blk{flex-direction:column;gap:4px;display:flex}.lc-br-blk-label{color:var(--dsw-alias-label-secondary);font-size:11px;font-weight:600}.lc-ts-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;overflow:hidden}.lc-ts-card-head{color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:8px;padding:6px 10px;font-size:11px;font-weight:600;display:flex}.lc-ts-card-head b{color:var(--dsw-alias-label-primary)}.lc-ts-card-count{margin-left:auto}.lc-ts-desc-body{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:160px;margin:0;padding:8px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-param-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:140px 90px 56px 1fr;align-items:baseline;gap:2px 10px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-param-row:first-of-type{border-top:0}.lc-ts-param-name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.lc-ts-param-type{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;overflow:hidden}.lc-ts-param-req{color:var(--dsw-alias-state-warn-primary);font-size:11px;font-weight:600}.lc-ts-param-req-off{color:var(--dsw-alias-label-secondary);font-size:11px}.lc-ts-param-desc{color:var(--dsw-alias-label-secondary);grid-column:1/-1;line-height:1.5}.lc-ts-params-empty{color:var(--dsw-alias-label-secondary);padding:8px 10px;font-size:12px}.lc-ts-json{flex-direction:column;gap:4px;display:flex}.lc-ts-json-toggle{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:0;align-self:flex-start;padding:0;font-size:11px}.lc-ts-json-toggle:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.lc-rich-seg{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;align-self:flex-end;gap:2px;padding:1px;display:flex}.lc-rich-seg-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-rich-seg-btn:hover{color:var(--dsw-alias-label-primary)}.lc-rich-seg-on,.lc-rich-seg-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-rich-seg-head{align-self:auto;margin-left:auto}.lc-br-md{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);word-break:break-word;scrollbar-width:thin;border-radius:6px;max-height:320px;padding:4px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-desc-md{color:var(--dsw-alias-label-primary);word-break:break-word;scrollbar-width:thin;max-height:160px;padding:4px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-br-md>div,.lc-ts-desc-md>div{font-size:13px;line-height:1.55}.lc-br-md div :is(h1,h2,h3,h4,h5,h6),.lc-ts-desc-md div :is(h1,h2,h3,h4,h5,h6){margin:10px 0 4px;font-size:13px;font-weight:600}.lc-br-md div p,.lc-ts-desc-md div p,.lc-br-md div pre,.lc-ts-desc-md div pre{margin:6px 0}.lc-br-md div :not(pre)>code,.lc-ts-desc-md div :not(pre)>code{box-decoration-break:clone;padding:1px 5px;line-height:1.3;font-size:1em!important}.lc-br-md div table code,.lc-ts-desc-md div table code{font-size:inherit}.lc-br-rich-inline{flex-direction:column;gap:6px;display:flex}.lc-ts-card .lc-br-pre{margin:8px 10px}.lc-att-grid{flex-wrap:wrap;gap:10px;padding:8px 10px;display:flex}.lc-att-item{align-items:center;gap:8px;min-width:0;display:flex}.lc-att-thumb{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);cursor:pointer;width:64px;height:64px;font:inherit;border-radius:6px;flex:none;justify-content:center;align-items:center;padding:0;display:flex;overflow:hidden}.lc-att-thumb img{object-fit:cover;width:100%;height:100%;display:block}.lc-att-ph,.lc-att-err{color:var(--dsw-alias-label-secondary);text-align:center;padding:2px;font-size:10px}.lc-att-meta{flex-direction:column;gap:2px;min-width:0;display:flex}.lc-att-name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;max-width:200px;font-size:12px;overflow:hidden}.lc-att-dims{color:var(--dsw-alias-label-secondary);font-size:11px}";
2579
+ const css = ".lc-root{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-primary);padding:16px 20px 32px;font-size:13px;overflow-y:auto}.lc-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;margin-bottom:14px;padding:14px 16px}.lc-card-title{align-items:baseline;gap:8px;margin-bottom:10px;font-weight:600;display:flex}.lc-card-title-text{white-space:nowrap;flex:none}.lc-stats{grid-template-columns:repeat(auto-fit,minmax(92px,1fr));gap:8px;display:grid}.lc-stat{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-direction:column;gap:2px;min-width:0;padding:8px 10px;display:flex}.lc-stat-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:600;overflow:hidden}.lc-stat-value{color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:14px;font-weight:600;overflow:hidden}.lc-stat-sub{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.lc-stat-tipped{position:relative}.lc-stat-q{text-align:center;width:11px;height:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);cursor:help;border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tipped:hover .lc-stat-q{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary)}.lc-stat-tip{z-index:6;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;max-width:280px;color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:6px 10px;font-size:12px;font-weight:400;line-height:1.5;transition:opacity .12s;position:absolute;top:calc(100% + 6px);left:0;box-shadow:0 2px 8px #0000002e}.lc-stat-tipped:hover .lc-stat-tip{opacity:1}.lc-stat-tip-prices{border-top:1px dashed var(--dsw-alias-border-l1);margin-top:5px;padding-top:5px;display:block}.lc-stat-tip-head{font-weight:600;display:block}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-model{color:var(--dsw-alias-label-primary)}.lc-card-sub{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:400}.lc-gran,.lc-kinds{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-gran-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-gran-btn:hover{color:var(--dsw-alias-label-primary)}.lc-gran-on,.lc-gran-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-overview-num{align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.lc-overview-num>b{font-size:20px}.lc-overview-num span{color:var(--dsw-alias-label-secondary)}.lc-overview-pct{margin-left:auto;font-size:11px}.lc-overview-pct b{color:var(--dsw-alias-label-primary);margin-right:4px;font-size:20px}.lc-stacked-wrap{width:100%;position:relative}.lc-stacked{background:#8080802e;border-radius:5px;width:100%;display:flex;position:relative;overflow:hidden}.lc-occupied-box{border:2px solid var(--dsw-alias-label-tertiary);box-sizing:border-box;pointer-events:none;opacity:0;box-shadow:0 0 0 1px var(--dsw-alias-bg-layer-2);border-radius:5px;transition:opacity .12s;position:absolute;top:0;bottom:0;left:0}.lc-occupied-box-on{opacity:1}.lc-bar-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:3px 8px;font-size:12px;transition:opacity .12s;position:absolute;bottom:calc(100% + 6px);transform:translate(-50%);box-shadow:0 2px 8px #0000002e}.lc-bar-tip-on{opacity:1}.lc-stacked>div{height:100%}.lc-stacked-seg{transition:filter .12s,opacity .12s}.lc-stacked-free{box-sizing:border-box;transition:box-shadow .12s,opacity .12s}.lc-stacked-seg-on{filter:brightness(1.18)}.lc-reserve{z-index:1;pointer-events:auto;cursor:help;background:repeating-linear-gradient(45deg, color-mix(in srgb, var(--dsw-alias-state-warn-primary) 24%, transparent) 0 5px, transparent 5px 10px);position:absolute;top:0;bottom:0}.lc-stacked-free-on{border:2px dashed var(--dsw-alias-label-secondary);border-radius:3px}.lc-stacked-dim .lc-stacked-seg{opacity:.35}.lc-stacked-dim .lc-stacked-seg-on{opacity:1}.lc-stacked-dim .lc-stacked-free{opacity:.35}.lc-stacked-dim .lc-stacked-free-on{opacity:1}.lc-legend{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:6px 14px;margin-top:10px;display:grid}.lc-chip{min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:5px;padding:1px 6px;transition:background-color .12s;display:flex}.lc-chip-label{white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}.lc-chip-nums{white-space:nowrap;flex:none;align-items:baseline;gap:6px;margin-left:auto;display:inline-flex}.lc-chip i,.lc-detail-row i,.lc-node i{border-radius:2px;width:8px;height:8px;display:inline-block}.lc-chip i{transition:box-shadow .12s}.lc-chip em{color:var(--dsw-alias-label-secondary);font-style:normal}.lc-chip-on{background:var(--dsw-alias-interactive-bg-hover);font-weight:600}.lc-chip-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-tools{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;align-items:center;gap:6px;margin-top:10px;display:flex}.lc-tools-label,.lc-tools-more{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;padding:0;font-family:inherit;font-size:12px}.lc-tools-label:hover,.lc-tools-more:hover{text-decoration:underline}.lc-tool-chip{background:var(--dsw-alias-bg-layer-2);font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:0;border-radius:4px;padding:1px 7px;font-size:12px}.lc-tool-chip:hover{text-decoration:underline}.lc-chartrow{align-items:stretch;gap:6px;display:flex}.lc-axis{box-sizing:border-box;width:40px;height:150px;color:var(--dsw-alias-label-secondary);padding-top:18px;font-size:11px;position:relative}.lc-axis span{line-height:1;position:absolute;right:0}.lc-axis-top{top:13px}.lc-axis-mid{top:69px}.lc-axis-bot{top:125px}.lc-chart-scroll{scrollbar-width:thin;flex:1;min-width:0;padding-bottom:8px;position:relative;overflow:auto hidden}.lc-chart-fade{pointer-events:none;z-index:2;width:26px;position:absolute;top:0;bottom:0}.lc-chart-fade-l{background:linear-gradient(to right, var(--dsw-alias-bg-layer-1), transparent);left:0}.lc-chart-fade-r{background:linear-gradient(to left, var(--dsw-alias-bg-layer-1), transparent);right:0}.lc-chart{box-sizing:border-box;align-items:flex-end;gap:2px;width:max-content;min-width:100%;height:130px;padding-top:18px;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-l1);pointer-events:none;position:absolute;left:0;right:0}.lc-grid-top{top:18px}.lc-grid-mid{top:74px}.lc-bar{cursor:pointer;border-radius:2px;flex:none;align-items:flex-end;width:14px;height:100%;transition:opacity .12s,background-color .12s;display:flex;position:relative}.lc-chart-dim .lc-bar{opacity:.35}.lc-chart-dim .lc-bar-in-turn{opacity:1}.lc-chart-dim .lc-turn{opacity:.35}.lc-chart-dim .lc-turn-on{opacity:1}.lc-chart-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;border-radius:6px;padding:3px 8px;font-size:12px;position:absolute;top:0;transform:translate(-50%);box-shadow:0 2px 8px #0000002e}.lc-bar:hover{background:var(--dsw-alias-bg-layer-2)}.lc-bar-hovered{outline:1px dashed var(--dsw-alias-brand-primary);outline-offset:1px}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:#80808024}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-marker{color:var(--dsw-alias-state-warn-primary);font-size:11px;position:absolute;top:-16px;left:50%;transform:translate(-50%)}.lc-turns{gap:2px;width:max-content;min-width:100%;margin-top:4px;display:flex}.lc-turn{box-sizing:border-box;text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;cursor:pointer;border-radius:3px;flex:none;height:14px;font-size:10px;font-weight:600;line-height:14px;transition:filter .12s,opacity .12s;overflow:hidden}.lc-turn-on{filter:brightness(1.35);color:var(--dsw-alias-label-primary)}.lc-detail{border-top:1px solid var(--dsw-alias-border-l1);margin-top:12px;padding-top:12px}.lc-detail-head{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-detail-head b{color:var(--dsw-alias-label-primary)}.lc-detail-marker{color:var(--dsw-alias-state-warn-primary);background:var(--dsw-alias-bg-layer-2);border-radius:6px;padding:1px 7px;font-size:11px}.lc-detail-head .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-detail-tag{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:4px;padding:0 6px;font-size:11px}.lc-detail-rows{grid-template-columns:1fr 1fr;gap:4px 24px;margin-top:10px;display:grid}.lc-detail-row{align-items:center;gap:8px;display:flex}.lc-detail-label{white-space:nowrap;min-width:70px;color:var(--dsw-alias-label-secondary)}.lc-bar-track{background:#8080802e;border-radius:3px;flex:1;height:5px;display:block;overflow:hidden}.lc-bar-fill{border-radius:3px;height:100%;display:block}.lc-detail-num{text-align:right;width:44px}.lc-detail-pct{text-align:right;width:34px;color:var(--dsw-alias-label-secondary)}.lc-cols{flex-wrap:wrap;gap:14px;margin-bottom:14px;display:flex}.lc-col{flex:1;min-width:280px}.lc-cols>.lc-card,.lc-col>.lc-card:last-child{margin-bottom:0}.lc-head>.lc-card:first-child{flex:7 1 0;min-width:360px}.lc-head>.lc-card:last-child{flex:3 1 0;min-width:220px}.lc-pi-grid{grid-template-columns:1fr;gap:8px;display:grid}.lc-pi-row{min-width:0;color:inherit;flex-direction:row;justify-content:space-between;align-items:baseline;gap:12px;text-decoration:none;display:flex}.lc-pi-row:hover .lc-pi-value{text-decoration:underline}.lc-pi-update{color:var(--dsw-alias-state-warn-primary);white-space:nowrap;margin-left:6px;font-size:11px}.lc-pi-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:none;font-size:11px;font-weight:600;overflow:hidden}.lc-pi-value{min-width:0;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:right;font-size:13px;font-weight:600;overflow:hidden}.lc-events,.lc-nodes{flex-direction:column;gap:2px;max-height:320px;display:flex;overflow-y:auto}.lc-event{align-items:center;gap:8px;padding:3px 0;display:flex}.lc-event-icon{text-align:center;width:18px;color:var(--dsw-alias-state-warn-primary)}.lc-event-icon.lc-event-inject{color:#a855f7}.lc-event-icon.lc-event-model{color:var(--dsw-alias-brand-primary)}.lc-kind{white-space:nowrap;border-radius:4px;flex:none;padding:1px 6px;font-size:10px;font-weight:600}.lc-kind-inject{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent);color:var(--dsw-alias-state-success-primary)}.lc-kind-compaction{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent);color:var(--dsw-alias-state-error-primary)}.lc-kind-prune{color:#8b5cf6;background:#8b5cf626}.lc-kind-model{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 15%, transparent);color:var(--dsw-alias-brand-primary)}.lc-event-label{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.lc-event-at{color:var(--dsw-alias-label-secondary);white-space:nowrap;flex:none;font-size:11px}.lc-event-tokens{color:var(--dsw-alias-state-success-primary);white-space:nowrap;font-weight:600}.lc-event-tokens.lc-up{color:var(--dsw-alias-state-warn-primary)}.lc-event-time{color:var(--dsw-alias-label-secondary);font-size:12px}.lc-node{align-items:center;gap:8px;padding:3px 0;display:flex}.lc-node-preview{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);flex:1;overflow:hidden}.lc-node-time{color:var(--dsw-alias-label-secondary);text-align:right;min-width:54px;font-size:12px}.lc-node-tokens{color:var(--dsw-alias-label-secondary)}.lc-nodes-more{color:var(--dsw-alias-label-secondary);padding:3px 0}.lc-empty{color:var(--dsw-alias-label-secondary);text-align:center;padding:18px 0}.lc-error{flex-direction:column;align-items:center;gap:8px;padding:40px 16px;display:flex}.lc-error-msg{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);overflow-wrap:anywhere;border-radius:6px;max-width:100%;padding:4px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.lc-error-retry{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:6px;padding:4px 14px;font-size:12px}.lc-error-retry:hover{border-color:var(--dsw-alias-label-primary)}.lc-foot{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:12px}.lc-modal-backdrop{z-index:200;background:#00000073;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.lc-modal-card{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);width:min(720px,100vw - 48px);max-height:min(82vh,760px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);color:var(--dsw-alias-label-primary);border-radius:12px;padding:16px 18px 18px;font-size:13px;overflow-y:auto}.lc-modal-head{align-items:baseline;gap:8px;margin-bottom:12px;display:flex}.lc-modal-title{font-size:14px;font-weight:600}.lc-modal-close{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;margin-left:auto;padding:2px 6px;font-family:inherit;font-size:18px;line-height:1}.lc-modal-close:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.lc-br-hint{color:var(--dsw-alias-label-secondary);white-space:nowrap;margin-left:auto;font-size:11px;font-weight:400}.lc-br-pick{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;max-width:240px;padding:3px 6px;font-size:12px}.lc-br-meta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-br-meta b{color:var(--dsw-alias-label-primary)}.lc-br-meta .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-br-note{color:var(--dsw-alias-label-secondary);margin-top:8px;font-size:12px}.lc-br-cats{flex-direction:column;gap:4px;margin-top:10px;display:flex}.lc-br-cat{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:8px;overflow:hidden}.lc-br-cat-empty{opacity:.55}.lc-br-cat-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;transition:background-color .12s;display:flex}.lc-br-cat-row:hover,.lc-br-cat-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-cat-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-br-cat-row i{border-radius:2px;flex:none;width:8px;height:8px;transition:box-shadow .12s;display:inline-block}.lc-br-cat-label{font-weight:600}.lc-br-cat-count{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:12px}.lc-br-count-grp{flex:1;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-chev{width:12px;color:var(--dsw-alias-label-secondary);flex:none;transition:transform .12s}.lc-br-chev-on{transform:rotate(90deg)}.lc-br-tokens{color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-delta,.lc-br-tdelta{white-space:nowrap;border-radius:4px;flex:none;padding:0 5px;font-size:11px;font-weight:600}.lc-br-delta-up,.lc-br-tdelta-up{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent)}.lc-br-delta-down,.lc-br-tdelta-down{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent)}.lc-br-tokens-grp{flex:none;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-pct{text-align:right;width:36px;color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-body{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:2px;padding:4px 6px;display:flex}.lc-br-elem{border-radius:6px}.lc-br-elem-on{background:var(--dsw-alias-interactive-bg-active)}.lc-br-elem-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;padding:5px 6px;font-size:12px;transition:background-color .12s;display:flex}.lc-br-elem-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-tag{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);text-overflow:ellipsis;white-space:nowrap;border-radius:4px;flex:none;max-width:220px;padding:0 6px;font-size:11px;overflow:hidden}.lc-br-tag-inv{color:var(--dsw-alias-bg-layer-1);background:var(--dsw-alias-label-primary);border-color:#0000;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.lc-br-preview{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-br-time{color:var(--dsw-alias-label-secondary);flex:none;font-size:11px}.lc-br-content{flex-direction:column;gap:6px;padding:2px 6px 8px 26px;display:flex}.lc-br-pre{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;border-radius:6px;max-height:320px;margin:0;padding:8px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-br-dim{color:var(--dsw-alias-label-secondary)}.lc-br-blk{flex-direction:column;gap:4px;display:flex}.lc-br-blk-label{color:var(--dsw-alias-label-secondary);font-size:11px;font-weight:600}.lc-ts-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;overflow:hidden}.lc-ts-card-head{color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:8px;padding:6px 10px;font-size:11px;font-weight:600;display:flex}.lc-ts-card-head b{color:var(--dsw-alias-label-primary)}.lc-ts-call-name{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px}.lc-ts-card-count{margin-left:auto}.lc-ts-desc-body{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:160px;margin:0;padding:8px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-param-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:140px 90px 56px 1fr;align-items:baseline;gap:2px 10px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-param-row:first-of-type{border-top:0}.lc-ts-param-name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.lc-ts-param-type{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;overflow:hidden}.lc-ts-param-req{color:var(--dsw-alias-state-warn-primary);font-size:11px;font-weight:600}.lc-ts-param-req-off{color:var(--dsw-alias-label-secondary);font-size:11px}.lc-ts-param-desc{color:var(--dsw-alias-label-secondary);grid-column:1/-1;line-height:1.5}.lc-ts-params-empty{color:var(--dsw-alias-label-secondary);padding:8px 10px;font-size:12px}.lc-ts-arg-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:minmax(0,96px) 1fr;align-items:start;column-gap:12px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-arg-row:first-of-type{border-top:0}.lc-ts-arg-row .lc-ts-param-name{text-overflow:unset;white-space:normal;overflow-wrap:anywhere;overflow:visible}.lc-ts-arg-val{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:200px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-json{flex-direction:column;gap:4px;display:flex}.lc-ts-json-toggle{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:0;align-self:flex-start;padding:0;font-size:11px}.lc-ts-json-toggle:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.lc-rich-seg{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;align-self:flex-end;gap:2px;padding:1px;display:flex}.lc-rich-seg-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-rich-seg-btn:hover{color:var(--dsw-alias-label-primary)}.lc-rich-seg-on,.lc-rich-seg-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-rich-seg-head{align-self:auto;margin-left:auto}.lc-br-md{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);word-break:break-word;scrollbar-width:thin;border-radius:6px;max-height:320px;padding:4px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-desc-md{color:var(--dsw-alias-label-primary);word-break:break-word;scrollbar-width:thin;max-height:160px;padding:4px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-br-md>div,.lc-ts-desc-md>div{font-size:13px;line-height:1.55}.lc-br-md div :is(h1,h2,h3,h4,h5,h6),.lc-ts-desc-md div :is(h1,h2,h3,h4,h5,h6){margin:10px 0 4px;font-size:13px;font-weight:600}.lc-br-md div p,.lc-ts-desc-md div p,.lc-br-md div pre,.lc-ts-desc-md div pre{margin:6px 0}.lc-br-md div :not(pre)>code,.lc-ts-desc-md div :not(pre)>code{box-decoration-break:clone;padding:1px 5px;line-height:1.3;font-size:1em!important}.lc-br-md div table code,.lc-ts-desc-md div table code{font-size:inherit}.lc-br-rich-inline{flex-direction:column;gap:6px;display:flex}.lc-ts-card .lc-br-pre{margin:8px 10px}.lc-att-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;padding:8px 10px;display:grid}.lc-att-item{align-items:center;gap:8px;min-width:0;display:flex}.lc-att-thumb{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);cursor:pointer;width:64px;height:64px;font:inherit;border-radius:6px;flex:none;justify-content:center;align-items:center;padding:0;display:flex;overflow:hidden}.lc-att-thumb img{object-fit:cover;width:100%;height:100%;display:block}.lc-att-ph,.lc-att-err{color:var(--dsw-alias-label-secondary);text-align:center;padding:2px;font-size:10px}.lc-att-meta{flex-direction:column;gap:2px;min-width:0;display:flex}.lc-att-name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.lc-att-dims{color:var(--dsw-alias-label-secondary);font-size:11px}.lc-att-tokens{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;font-size:11px}";
2277
2580
  const tagId = "dsh-context/styles.css";
2278
2581
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
2279
2582
  const tag = document.createElement("style");