dsh-context 0.58.0 → 0.59.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
@@ -358,6 +358,11 @@ window.__ModuleLoader__.load({
358
358
  "ov.kpi.toolSub": "工具执行 {dur}",
359
359
  "ov.kpi.wallSub": "模型调用 {n}",
360
360
  "ov.stats.empty": "统计范围内暂无 Token 用量",
361
+ "ov.usage.title": "近 7 天用量",
362
+ "ov.usage.tokens": "Token",
363
+ "ov.usage.cost": "费用(仅含支持计价映射的模型)",
364
+ "ov.usage.costTip": "费用",
365
+ "ov.usage.empty": "近 7 天暂无用量 — 会话产生模型请求后,这里会显示每日 Token 与费用",
361
366
  "balance.title": "DeepSeek 余额",
362
367
  "balance.tip.granted": "赠送余额",
363
368
  "balance.tip.toppedUp": "充值余额",
@@ -739,6 +744,11 @@ window.__ModuleLoader__.load({
739
744
  "ov.kpi.toolSub": "tool runs {dur}",
740
745
  "ov.kpi.wallSub": "{n} model calls",
741
746
  "ov.stats.empty": "No billed tokens in this range",
747
+ "ov.usage.title": "Last 7 Days",
748
+ "ov.usage.tokens": "Tokens",
749
+ "ov.usage.cost": "Cost (price-mapped models only)",
750
+ "ov.usage.costTip": "Cost",
751
+ "ov.usage.empty": "No usage in the last 7 days — daily tokens and cost appear once sessions make model requests",
742
752
  "balance.title": "DeepSeek balance",
743
753
  "balance.tip.granted": "Granted balance",
744
754
  "balance.tip.toppedUp": "Topped-up balance",
@@ -1627,12 +1637,13 @@ window.__ModuleLoader__.load({
1627
1637
  }
1628
1638
  /**
1629
1639
  * Narrow a delivered `contextActivity` value (the per-day ledger the Context
1630
- * Overview's heatmap reads off each session-list row) to a render-safe shape.
1631
- * Absent or non-record stays null (an older host serves no such key — the
1632
- * heatmap renders its empty note). Per-day re-proved: a malformed key or a
1633
- * wrong-typed figure drops just that entry, a hostile day record can never
1634
- * produce a NaN cell, and a well-formed payload passes through untouched
1635
- * (reference-stable for the selector equality).
1640
+ * Overview's heatmap and usage chart read off each session-list row) to a
1641
+ * render-safe shape. Absent or non-record stays null (an older host serves no
1642
+ * such key — the heatmap renders its empty note). Per-day re-proved: a
1643
+ * malformed key or a wrong-typed figure drops just that entry, a malformed
1644
+ * pricing record drops just the fee (the day's tokens survive), a hostile day
1645
+ * record can never produce a NaN cell, and a well-formed payload passes
1646
+ * through untouched (reference-stable for the selector equality).
1636
1647
  */
1637
1648
  function activityOf$1(value) {
1638
1649
  const data = asRecord(value);
@@ -1649,9 +1660,13 @@ window.__ModuleLoader__.load({
1649
1660
  dirty = true;
1650
1661
  continue;
1651
1662
  }
1663
+ const proved = costOf(entry.cost);
1664
+ const cost = proved !== void 0 && Object.keys(proved).length > 0 ? proved : void 0;
1665
+ if (entry.cost !== void 0 && cost === void 0) dirty = true;
1652
1666
  days[key] = {
1653
1667
  tokens,
1654
- requests
1668
+ requests,
1669
+ ...cost !== void 0 ? { cost } : {}
1655
1670
  };
1656
1671
  }
1657
1672
  return dirty ? { days } : data;
@@ -6486,33 +6501,44 @@ window.__ModuleLoader__.load({
6486
6501
  };
6487
6502
  }
6488
6503
  /**
6489
- * Merge every row's daily ledger into one — the heatmap's data. A session
6490
- * counts toward a day only when its own entry carries activity, mirroring
6491
- * the day filter's predicate, so the cell's tooltip previews the click; a
6492
- * zeroed entry is skipped whole. The merged record stays small even over
6493
- * long histories.
6504
+ * Merge every row's daily ledger into one — the heatmap's and the usage
6505
+ * chart's data. A session counts toward a day only when its own entry
6506
+ * carries activity, mirroring the day filter's predicate, so the cell's
6507
+ * tooltip previews the click; a zeroed entry is skipped whole. Each day's
6508
+ * pricing records merge into one SessionCostUsage and price off the SAME
6509
+ * book/estimator the KPI band's cost cell rides (null fee on anything
6510
+ * unpriced). The merged record stays small even over long histories.
6494
6511
  */
6495
- function aggregateDays(rows) {
6496
- const days = {};
6497
- const byKey = days;
6512
+ function aggregateDays(rows, book, currency) {
6513
+ const merged = {};
6514
+ const byKey = merged;
6498
6515
  for (const row of rows) {
6499
6516
  if (row.activity === null) continue;
6500
6517
  for (const key of Object.keys(row.activity.days)) {
6501
6518
  const entry = row.activity.days[key];
6502
6519
  if (entry.tokens <= 0 && entry.requests <= 0) continue;
6503
6520
  const prev = byKey[key];
6504
- if (prev === void 0) days[key] = {
6521
+ if (prev === void 0) merged[key] = {
6505
6522
  tokens: entry.tokens,
6506
6523
  requests: entry.requests,
6507
- sessions: 1
6524
+ sessions: 1,
6525
+ fees: entry.cost !== void 0 ? [entry.cost] : []
6508
6526
  };
6509
6527
  else {
6510
6528
  prev.tokens += entry.tokens;
6511
6529
  prev.requests += entry.requests;
6512
6530
  prev.sessions++;
6531
+ if (entry.cost !== void 0) prev.fees.push(entry.cost);
6513
6532
  }
6514
6533
  }
6515
6534
  }
6535
+ const days = {};
6536
+ for (const [key, day] of Object.entries(merged)) days[key] = {
6537
+ tokens: day.tokens,
6538
+ requests: day.requests,
6539
+ sessions: day.sessions,
6540
+ cost: estimateSessionCost(mergeCostUsage(...day.fees), book, currency)
6541
+ };
6516
6542
  return days;
6517
6543
  }
6518
6544
  /**
@@ -7291,6 +7317,166 @@ window.__ModuleLoader__.load({
7291
7317
  };
7292
7318
  }
7293
7319
  //#endregion
7320
+ //#region src/client/components/overviewUsage.tsx
7321
+ /**
7322
+ * The Context Insights panel's first-row usage chart — the RIGHT half of the
7323
+ * KPI row. Seven day columns ending today, each pairing two bars priced off
7324
+ * the merged daily ledger (overview.ts aggregateDays): billed TOKENS (the
7325
+ * heatmap's own blue) and the day's estimated COST (green). The fee rides
7326
+ * the same per-day pricing records the host fold books at each turn's
7327
+ * initiation, priced by the same book and estimator as the KPI band's cost
7328
+ * cell — never a whole session's spend dumped on the day it was last
7329
+ * active. The two series scale on their OWN window maxima (a $2 week must
7330
+ * not flatten under a 169M-token week), so each bar reads as a share of its
7331
+ * series' peak; the tooltip carries the exact figures. The window is fixed
7332
+ * to the last 7 days — the range selector above scopes the KPI figures, not
7333
+ * this calendar.
7334
+ *
7335
+ * The plot is framed like a chart: hairline gridlines at 0/25/50/75/100% of
7336
+ * each series' own peak, a solid baseline at 0, and a tick rail on each
7337
+ * side — TOKENS on the left, COST on the right, computed from the same
7338
+ * maxima the bars scale to. The cost rail reads '—' until some day actually
7339
+ * prices.
7340
+ */
7341
+ /** The chart's window: today and the six days before it, oldest first. */
7342
+ function usageWindowOf(today) {
7343
+ const columns = [];
7344
+ for (let d = -6; d <= 0; d++) {
7345
+ const key = shiftDayKey(today, d);
7346
+ if (key === null) return [];
7347
+ columns.push(key);
7348
+ }
7349
+ return columns;
7350
+ }
7351
+ /** The shared gridline/tick positions, in percent of each series' peak. */
7352
+ const TICKS = [
7353
+ 0,
7354
+ 25,
7355
+ 50,
7356
+ 75,
7357
+ 100
7358
+ ];
7359
+ function makeOverviewUsage(kit) {
7360
+ const { t, fmt } = kit;
7361
+ return function OverviewUsage(props) {
7362
+ const window = usageWindowOf(props.today);
7363
+ const byKey = props.days;
7364
+ const columns = window.map((key) => ({
7365
+ key,
7366
+ entry: byKey[key]
7367
+ }));
7368
+ const empty = columns.every((c) => c.entry === void 0 || c.entry.tokens <= 0 && c.entry.cost === null);
7369
+ let maxTokens = 0;
7370
+ let maxCost = 0;
7371
+ for (const c of columns) {
7372
+ if (c.entry === void 0) continue;
7373
+ if (c.entry.tokens > maxTokens) maxTokens = c.entry.tokens;
7374
+ if (c.entry.cost !== null && c.entry.cost > maxCost) maxCost = c.entry.cost;
7375
+ }
7376
+ const heightOf = (value, max) => max <= 0 || value <= 0 ? "0%" : `${Math.max(4, Math.round(value / max * 100))}%`;
7377
+ const tickOf = (percent) => fmt(Math.round(maxTokens * percent / 100));
7378
+ const costTickOf = (percent) => {
7379
+ if (maxCost <= 0) return "—";
7380
+ return percent === 0 ? "0" : formatCost(maxCost * percent / 100, props.currency);
7381
+ };
7382
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7383
+ className: "lc-card lc-ov-usage",
7384
+ children: [
7385
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7386
+ className: "lc-card-title",
7387
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7388
+ className: "lc-card-title-text",
7389
+ children: t("ov.usage.title")
7390
+ })
7391
+ }),
7392
+ empty || window.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7393
+ className: "lc-empty",
7394
+ children: t("ov.usage.empty")
7395
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7396
+ className: "lc-ov-usage-plot",
7397
+ role: "group",
7398
+ "aria-label": t("ov.usage.title"),
7399
+ children: [
7400
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7401
+ className: "lc-ov-usage-rail lc-ov-usage-rail-l",
7402
+ "aria-hidden": "true",
7403
+ children: TICKS.map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7404
+ className: "lc-ov-usage-tick",
7405
+ style: { top: `${100 - p}%` },
7406
+ children: tickOf(p)
7407
+ }, p))
7408
+ }),
7409
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7410
+ className: "lc-ov-usage-grid",
7411
+ children: [TICKS.map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7412
+ className: "lc-ov-usage-line" + (p === 0 ? " lc-ov-usage-line-0" : ""),
7413
+ style: { bottom: `${p}%` },
7414
+ "aria-hidden": "true"
7415
+ }, p)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7416
+ className: "lc-ov-usage-cols",
7417
+ children: columns.map((c) => {
7418
+ const tokens = c.entry?.tokens ?? 0;
7419
+ const cost = c.entry?.cost ?? null;
7420
+ const label = `${c.key}\n${t("ov.usage.tokens")} ${fmt(tokens)}\n${t("ov.usage.costTip")} ${cost === null ? "—" : formatCost(cost, props.currency)}`;
7421
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
7422
+ label,
7423
+ side: "top",
7424
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7425
+ className: "lc-ov-usage-col",
7426
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7427
+ className: "lc-ov-usage-bars",
7428
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7429
+ className: "lc-ov-usage-bar lc-ov-usage-tokens",
7430
+ style: { height: heightOf(tokens, maxTokens) }
7431
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7432
+ className: "lc-ov-usage-bar lc-ov-usage-cost",
7433
+ style: { height: cost === null ? "0%" : heightOf(cost, maxCost) }
7434
+ })]
7435
+ })
7436
+ })
7437
+ }, c.key);
7438
+ })
7439
+ })]
7440
+ }),
7441
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7442
+ className: "lc-ov-usage-rail lc-ov-usage-rail-r",
7443
+ "aria-hidden": "true",
7444
+ children: TICKS.map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7445
+ className: "lc-ov-usage-tick",
7446
+ style: { top: `${100 - p}%` },
7447
+ children: costTickOf(p)
7448
+ }, p))
7449
+ })
7450
+ ]
7451
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7452
+ className: "lc-ov-usage-days",
7453
+ "aria-hidden": "true",
7454
+ children: columns.map((c) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7455
+ className: "lc-ov-usage-day",
7456
+ children: c.key.slice(5)
7457
+ }, c.key))
7458
+ })] }),
7459
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7460
+ className: "lc-ov-usage-key",
7461
+ "aria-hidden": "true",
7462
+ children: [
7463
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "lc-ov-usage-swatch lc-ov-usage-tokens" }),
7464
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7465
+ className: "lc-ov-usage-key-label",
7466
+ children: t("ov.usage.tokens")
7467
+ }),
7468
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "lc-ov-usage-swatch lc-ov-usage-cost" }),
7469
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7470
+ className: "lc-ov-usage-key-label",
7471
+ children: t("ov.usage.cost")
7472
+ })
7473
+ ]
7474
+ })
7475
+ ]
7476
+ });
7477
+ };
7478
+ }
7479
+ //#endregion
7294
7480
  //#region src/client/components/statsTiming.tsx
7295
7481
  /**
7296
7482
  * The Timing card: where the session's ACTIVE time went. The donut splits
@@ -7623,9 +7809,12 @@ window.__ModuleLoader__.load({
7623
7809
  * projection values), so the panel draws every session's insight without
7624
7810
  * opening one log.
7625
7811
  *
7626
- * The panel's first row is the KPI metrics band: the range's six figures
7627
- * (sessions, billed tokens, cost, cache hit, tool calls, active time) in one
7628
- * full-width line. Below it, the aggregate stats row folds the same range's
7812
+ * The panel's first row is a 1:1 column pair: the KPI metrics band (the
7813
+ * range's six figures — sessions, billed tokens, cost, cache hit, tool
7814
+ * calls, active time — three per row) beside the last-7-days usage chart
7815
+ * (each day's billed tokens and estimated cost as a bar pair, folded off
7816
+ * the merged daily ledger). Below it, the aggregate stats row folds the
7817
+ * same range's
7629
7818
  * sessions into the two donut cards the per-session Context tab opens with —
7630
7819
  * Token Stats (the composition-split billed volume) and Timing Stats (the
7631
7820
  * summed totals). The body is then a 3:7 column pair: the insight column (the
@@ -7656,6 +7845,7 @@ window.__ModuleLoader__.load({
7656
7845
  const Donut = makeDonut(kit);
7657
7846
  const OverviewTokens = makeOverviewTokens(kit, Donut);
7658
7847
  const StatsTiming = makeStatsTiming(kit, Donut);
7848
+ const OverviewUsage = makeOverviewUsage(kit);
7659
7849
  const ErrorBoundary = makeErrorBoundary(t);
7660
7850
  /** The display currency follows the active locale (zh → CNY), read per render — the slot outlet re-renders on a locale switch. */
7661
7851
  function activeCurrency() {
@@ -7717,7 +7907,7 @@ window.__ModuleLoader__.load({
7717
7907
  const visible = sortRows(group === null ? scoped : scoped.filter((row) => inGroup(row, group, groups)), sort);
7718
7908
  const paged = pageOf(visible, page);
7719
7909
  const kpi = kpisOf(ranged, allRows.length, book, currency);
7720
- const days = aggregateDays(allRows);
7910
+ const days = aggregateDays(allRows, book, currency);
7721
7911
  const openOne = (id) => {
7722
7912
  openSessionVia(ctx, id);
7723
7913
  overviewStore.set(false);
@@ -7766,301 +7956,311 @@ window.__ModuleLoader__.load({
7766
7956
  }), rows === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7767
7957
  className: "lc-empty",
7768
7958
  children: t("ov.unavailable")
7769
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
7770
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7771
- className: "lc-ov-kpis",
7772
- children: [
7773
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7774
- className: "lc-stat lc-ov-kpi",
7775
- children: [
7776
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7777
- className: "lc-stat-label",
7778
- children: t("ov.kpi.sessions")
7779
- }),
7780
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7781
- className: "lc-stat-value",
7782
- children: kpi.sessions
7783
- }),
7784
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7785
- className: "lc-stat-sub",
7786
- children: t("ov.kpi.ofTotal", { n: kpi.listed })
7787
- })
7788
- ]
7789
- }),
7790
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7791
- className: "lc-stat lc-ov-kpi",
7959
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7960
+ className: "lc-ov-scroll",
7961
+ children: [
7962
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7963
+ className: "lc-ov-first",
7964
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7965
+ className: "lc-ov-kpis",
7792
7966
  children: [
7793
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7794
- className: "lc-stat-label",
7795
- children: t("ov.kpi.tokens")
7796
- }),
7797
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7798
- className: "lc-stat-value",
7799
- children: fmt(kpi.tokens)
7800
- }),
7801
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7802
- className: "lc-stat-sub",
7967
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7968
+ className: "lc-stat lc-ov-kpi",
7803
7969
  children: [
7804
- t("stats.turns"),
7805
- " ",
7806
- fmt(kpi.turns)
7970
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7971
+ className: "lc-stat-label",
7972
+ children: t("ov.kpi.sessions")
7973
+ }),
7974
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7975
+ className: "lc-stat-value",
7976
+ children: kpi.sessions
7977
+ }),
7978
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7979
+ className: "lc-stat-sub",
7980
+ children: t("ov.kpi.ofTotal", { n: kpi.listed })
7981
+ })
7807
7982
  ]
7808
- })
7809
- ]
7810
- }),
7811
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7812
- className: "lc-stat lc-ov-kpi",
7813
- children: [
7814
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7815
- className: "lc-stat-label",
7816
- children: t("stats.cost")
7817
- }),
7818
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7819
- className: "lc-stat-value",
7820
- children: kpi.cost === null ? "—" : formatCost(kpi.cost, currency)
7821
- }),
7822
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7823
- className: "lc-stat-sub",
7824
- children: t("ov.kpi.pricedSub", {
7825
- n: kpi.costSessions,
7826
- total: kpi.sessions
7827
- })
7828
- })
7829
- ]
7830
- }),
7831
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7832
- className: "lc-stat lc-ov-kpi",
7833
- children: [
7834
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7835
- className: "lc-stat-label",
7836
- children: t("stats.cacheHit")
7837
- }),
7838
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7839
- className: "lc-stat-value",
7840
- children: kpi.cacheHit === null ? "—" : kpi.cacheHit + "%"
7841
7983
  }),
7842
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7843
- className: "lc-stat-sub",
7844
- children: t("ov.kpi.sessionsSub", { n: kpi.usageSessions })
7845
- })
7846
- ]
7847
- }),
7848
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7849
- className: "lc-stat lc-ov-kpi",
7850
- children: [
7851
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7852
- className: "lc-stat-label",
7853
- children: t("stats.toolCalls")
7984
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7985
+ className: "lc-stat lc-ov-kpi",
7986
+ children: [
7987
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7988
+ className: "lc-stat-label",
7989
+ children: t("ov.kpi.tokens")
7990
+ }),
7991
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7992
+ className: "lc-stat-value",
7993
+ children: fmt(kpi.tokens)
7994
+ }),
7995
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7996
+ className: "lc-stat-sub",
7997
+ children: [
7998
+ t("stats.turns"),
7999
+ " ",
8000
+ fmt(kpi.turns)
8001
+ ]
8002
+ })
8003
+ ]
7854
8004
  }),
7855
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7856
- className: "lc-stat-value",
7857
- children: fmt(kpi.toolCalls)
8005
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8006
+ className: "lc-stat lc-ov-kpi",
8007
+ children: [
8008
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8009
+ className: "lc-stat-label",
8010
+ children: t("stats.cost")
8011
+ }),
8012
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8013
+ className: "lc-stat-value",
8014
+ children: kpi.cost === null ? "—" : formatCost(kpi.cost, currency)
8015
+ }),
8016
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8017
+ className: "lc-stat-sub",
8018
+ children: t("ov.kpi.pricedSub", {
8019
+ n: kpi.costSessions,
8020
+ total: kpi.sessions
8021
+ })
8022
+ })
8023
+ ]
7858
8024
  }),
7859
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7860
- className: "lc-stat-sub",
7861
- children: t("ov.kpi.toolSub", { dur: fmtDuration(kpi.toolsMs) })
7862
- })
7863
- ]
7864
- }),
7865
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7866
- className: "lc-stat lc-ov-kpi",
7867
- children: [
7868
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7869
- className: "lc-stat-label",
7870
- children: t("timing.total")
8025
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8026
+ className: "lc-stat lc-ov-kpi",
8027
+ children: [
8028
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8029
+ className: "lc-stat-label",
8030
+ children: t("stats.cacheHit")
8031
+ }),
8032
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8033
+ className: "lc-stat-value",
8034
+ children: kpi.cacheHit === null ? "—" : kpi.cacheHit + "%"
8035
+ }),
8036
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8037
+ className: "lc-stat-sub",
8038
+ children: t("ov.kpi.sessionsSub", { n: kpi.usageSessions })
8039
+ })
8040
+ ]
7871
8041
  }),
7872
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7873
- className: "lc-stat-value",
7874
- children: fmtDuration(kpi.wallMs)
8042
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8043
+ className: "lc-stat lc-ov-kpi",
8044
+ children: [
8045
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8046
+ className: "lc-stat-label",
8047
+ children: t("stats.toolCalls")
8048
+ }),
8049
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8050
+ className: "lc-stat-value",
8051
+ children: fmt(kpi.toolCalls)
8052
+ }),
8053
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8054
+ className: "lc-stat-sub",
8055
+ children: t("ov.kpi.toolSub", { dur: fmtDuration(kpi.toolsMs) })
8056
+ })
8057
+ ]
7875
8058
  }),
7876
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7877
- className: "lc-stat-sub",
7878
- children: t("ov.kpi.wallSub", { n: fmt(kpi.calls) })
8059
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8060
+ className: "lc-stat lc-ov-kpi",
8061
+ children: [
8062
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8063
+ className: "lc-stat-label",
8064
+ children: t("timing.total")
8065
+ }),
8066
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8067
+ className: "lc-stat-value",
8068
+ children: fmtDuration(kpi.wallMs)
8069
+ }),
8070
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8071
+ className: "lc-stat-sub",
8072
+ children: t("ov.kpi.wallSub", { n: fmt(kpi.calls) })
8073
+ })
8074
+ ]
7879
8075
  })
7880
8076
  ]
7881
- })
7882
- ]
7883
- }),
7884
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7885
- className: "lc-ov-stats",
7886
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(OverviewTokens, { tokens: kpi.tokenParts }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatsTiming, { timing: kpi.timing })]
7887
- }),
7888
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7889
- className: "lc-ov-body",
7890
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7891
- className: "lc-ov-left",
8077
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OverviewUsage, {
8078
+ days,
8079
+ currency,
8080
+ today: todayKey()
8081
+ })]
8082
+ }),
8083
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8084
+ className: "lc-ov-stats",
8085
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(OverviewTokens, { tokens: kpi.tokenParts }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatsTiming, { timing: kpi.timing })]
8086
+ }),
8087
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8088
+ className: "lc-ov-body",
7892
8089
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7893
- className: "lc-card lc-ov-heat-card",
8090
+ className: "lc-ov-left",
7894
8091
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7895
- className: "lc-card-title",
7896
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7897
- className: "lc-card-title-text",
7898
- children: t("ov.heat.title")
7899
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7900
- className: "lc-heat-ctl",
8092
+ className: "lc-card lc-ov-heat-card",
8093
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8094
+ className: "lc-card-title",
7901
8095
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7902
- className: "lc-card-sub",
7903
- children: t("ov.heat.sub")
7904
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7905
- className: "lc-gran",
7906
- role: "group",
7907
- "aria-label": t("ov.heat.metric"),
7908
- children: METRICS.map((m) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7909
- type: "button",
7910
- className: "lc-gran-btn" + (metric === m ? " lc-gran-on" : ""),
7911
- onClick: () => {
7912
- setMetric(m);
7913
- },
7914
- children: t("ov.heat.metric." + m)
7915
- }, m))
8096
+ className: "lc-card-title-text",
8097
+ children: t("ov.heat.title")
8098
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
8099
+ className: "lc-heat-ctl",
8100
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8101
+ className: "lc-card-sub",
8102
+ children: t("ov.heat.sub")
8103
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8104
+ className: "lc-gran",
8105
+ role: "group",
8106
+ "aria-label": t("ov.heat.metric"),
8107
+ children: METRICS.map((m) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8108
+ type: "button",
8109
+ className: "lc-gran-btn" + (metric === m ? " lc-gran-on" : ""),
8110
+ onClick: () => {
8111
+ setMetric(m);
8112
+ },
8113
+ children: t("ov.heat.metric." + m)
8114
+ }, m))
8115
+ })]
7916
8116
  })]
8117
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Heatmap, {
8118
+ days,
8119
+ metric,
8120
+ selected: day,
8121
+ onSelect: setDay,
8122
+ today: todayKey()
8123
+ })]
8124
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8125
+ type: "button",
8126
+ className: "lc-ov-settings",
8127
+ onClick: () => {
8128
+ openPluginSettings();
8129
+ close();
8130
+ },
8131
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
8132
+ className: "lc-ov-settings-label",
8133
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconSettings, { size: 14 }), t("plugin.settings")]
8134
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8135
+ className: "lc-ov-settings-hint",
8136
+ children: t("plugin.settingsOpen")
7917
8137
  })]
7918
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Heatmap, {
7919
- days,
7920
- metric,
7921
- selected: day,
7922
- onSelect: setDay,
7923
- today: todayKey()
7924
- })]
7925
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
7926
- type: "button",
7927
- className: "lc-ov-settings",
7928
- onClick: () => {
7929
- openPluginSettings();
7930
- close();
7931
- },
7932
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7933
- className: "lc-ov-settings-label",
7934
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconSettings, { size: 14 }), t("plugin.settings")]
7935
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7936
- className: "lc-ov-settings-hint",
7937
- children: t("plugin.settingsOpen")
7938
8138
  })]
7939
- })]
7940
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7941
- className: "lc-ov-right",
7942
- children: [
7943
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7944
- className: "lc-ov-list-head",
7945
- children: [
7946
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7947
- className: "lc-ov-list-title",
7948
- children: t("ov.list.title")
7949
- }),
7950
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7951
- className: "lc-ov-list-count",
7952
- children: visible.length
7953
- }),
7954
- day !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
7955
- type: "button",
7956
- className: "lc-ov-day-chip",
7957
- title: t("ov.list.dayClear"),
7958
- onClick: () => {
7959
- setDay(null);
7960
- },
7961
- children: [t("ov.list.dayFilter", { day }), " ×"]
7962
- }),
7963
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
7964
- className: "lc-ov-search",
7965
- type: "search",
7966
- value: query,
7967
- placeholder: t("ov.list.search"),
7968
- "aria-label": t("ov.list.search"),
7969
- onChange: (ev) => {
7970
- setQuery(ev.target.value);
7971
- }
7972
- }),
7973
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7974
- className: "lc-gran",
7975
- role: "group",
7976
- "aria-label": t("ov.list.sortLabel"),
7977
- children: SORTS.map((s) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8139
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8140
+ className: "lc-ov-right",
8141
+ children: [
8142
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8143
+ className: "lc-ov-list-head",
8144
+ children: [
8145
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8146
+ className: "lc-ov-list-title",
8147
+ children: t("ov.list.title")
8148
+ }),
8149
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8150
+ className: "lc-ov-list-count",
8151
+ children: visible.length
8152
+ }),
8153
+ day !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
7978
8154
  type: "button",
7979
- className: "lc-gran-btn" + (sort === s ? " lc-gran-on" : ""),
8155
+ className: "lc-ov-day-chip",
8156
+ title: t("ov.list.dayClear"),
7980
8157
  onClick: () => {
7981
- setSort(s);
8158
+ setDay(null);
7982
8159
  },
7983
- children: t("ov.list.sort." + s)
7984
- }, s))
7985
- })
7986
- ]
7987
- }),
7988
- chips.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7989
- className: "lc-ov-groups",
7990
- role: "group",
7991
- "aria-label": t("ov.group.label"),
7992
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
7993
- type: "button",
7994
- className: "lc-ov-chip" + (group === null ? " lc-ov-chip-on" : ""),
7995
- onClick: () => {
7996
- setGroup(null);
7997
- },
7998
- children: [t("ov.range.all"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7999
- className: "lc-ov-chip-n",
8000
- children: scoped.length
8001
- })]
8002
- }), chips.map((c) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8003
- type: "button",
8004
- className: "lc-ov-chip" + (group === c.key ? " lc-ov-chip-on" : ""),
8005
- onClick: () => {
8006
- setGroup(group === c.key ? null : c.key);
8007
- },
8008
- children: [c.key === "__ungrouped__" ? t("ov.group.ungrouped") : c.key, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8009
- className: "lc-ov-chip-n",
8010
- children: c.count
8011
- })]
8012
- }, c.key))]
8013
- }),
8014
- visible.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8015
- className: "lc-empty",
8016
- children: t(allRows.length === 0 ? "ov.list.empty" : "ov.list.noMatch")
8017
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8018
- className: "lc-ov-grid",
8019
- children: paged.items.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OverviewCard, {
8020
- row,
8021
- ...groups?.[row.id] !== void 0 ? { group: groups[row.id] } : {},
8022
- costLabel: cardCostOf(row, book, currency),
8023
- now,
8024
- onOpen: openOne
8025
- }, row.id))
8026
- }), paged.count > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8027
- className: "lc-ov-pager",
8028
- role: "navigation",
8029
- "aria-label": t("ov.list.pager"),
8030
- children: [
8031
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8160
+ children: [t("ov.list.dayFilter", { day }), " ×"]
8161
+ }),
8162
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
8163
+ className: "lc-ov-search",
8164
+ type: "search",
8165
+ value: query,
8166
+ placeholder: t("ov.list.search"),
8167
+ "aria-label": t("ov.list.search"),
8168
+ onChange: (ev) => {
8169
+ setQuery(ev.target.value);
8170
+ }
8171
+ }),
8172
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8173
+ className: "lc-gran",
8174
+ role: "group",
8175
+ "aria-label": t("ov.list.sortLabel"),
8176
+ children: SORTS.map((s) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8177
+ type: "button",
8178
+ className: "lc-gran-btn" + (sort === s ? " lc-gran-on" : ""),
8179
+ onClick: () => {
8180
+ setSort(s);
8181
+ },
8182
+ children: t("ov.list.sort." + s)
8183
+ }, s))
8184
+ })
8185
+ ]
8186
+ }),
8187
+ chips.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8188
+ className: "lc-ov-groups",
8189
+ role: "group",
8190
+ "aria-label": t("ov.group.label"),
8191
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8032
8192
  type: "button",
8033
- className: "lc-ov-pager-btn",
8034
- disabled: paged.index === 0,
8035
- "aria-label": t("ov.list.prev"),
8193
+ className: "lc-ov-chip" + (group === null ? " lc-ov-chip-on" : ""),
8036
8194
  onClick: () => {
8037
- setPage(paged.index - 1);
8195
+ setGroup(null);
8038
8196
  },
8039
- children: "‹"
8040
- }),
8041
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8042
- className: "lc-ov-pager-n",
8043
- children: t("ov.list.page", {
8044
- n: paged.index + 1,
8045
- total: paged.count
8046
- })
8047
- }),
8048
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8197
+ children: [t("ov.range.all"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8198
+ className: "lc-ov-chip-n",
8199
+ children: scoped.length
8200
+ })]
8201
+ }), chips.map((c) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8049
8202
  type: "button",
8050
- className: "lc-ov-pager-btn",
8051
- disabled: paged.index === paged.count - 1,
8052
- "aria-label": t("ov.list.next"),
8203
+ className: "lc-ov-chip" + (group === c.key ? " lc-ov-chip-on" : ""),
8053
8204
  onClick: () => {
8054
- setPage(paged.index + 1);
8205
+ setGroup(group === c.key ? null : c.key);
8055
8206
  },
8056
- children: "›"
8057
- })
8058
- ]
8059
- })] })
8060
- ]
8061
- })]
8062
- })
8063
- ] })]
8207
+ children: [c.key === "__ungrouped__" ? t("ov.group.ungrouped") : c.key, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8208
+ className: "lc-ov-chip-n",
8209
+ children: c.count
8210
+ })]
8211
+ }, c.key))]
8212
+ }),
8213
+ visible.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8214
+ className: "lc-empty",
8215
+ children: t(allRows.length === 0 ? "ov.list.empty" : "ov.list.noMatch")
8216
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8217
+ className: "lc-ov-grid",
8218
+ children: paged.items.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OverviewCard, {
8219
+ row,
8220
+ ...groups?.[row.id] !== void 0 ? { group: groups[row.id] } : {},
8221
+ costLabel: cardCostOf(row, book, currency),
8222
+ now,
8223
+ onOpen: openOne
8224
+ }, row.id))
8225
+ }), paged.count > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8226
+ className: "lc-ov-pager",
8227
+ role: "navigation",
8228
+ "aria-label": t("ov.list.pager"),
8229
+ children: [
8230
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8231
+ type: "button",
8232
+ className: "lc-ov-pager-btn",
8233
+ disabled: paged.index === 0,
8234
+ "aria-label": t("ov.list.prev"),
8235
+ onClick: () => {
8236
+ setPage(paged.index - 1);
8237
+ },
8238
+ children: "‹"
8239
+ }),
8240
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8241
+ className: "lc-ov-pager-n",
8242
+ children: t("ov.list.page", {
8243
+ n: paged.index + 1,
8244
+ total: paged.count
8245
+ })
8246
+ }),
8247
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8248
+ type: "button",
8249
+ className: "lc-ov-pager-btn",
8250
+ disabled: paged.index === paged.count - 1,
8251
+ "aria-label": t("ov.list.next"),
8252
+ onClick: () => {
8253
+ setPage(paged.index + 1);
8254
+ },
8255
+ children: "›"
8256
+ })
8257
+ ]
8258
+ })] })
8259
+ ]
8260
+ })]
8261
+ })
8262
+ ]
8263
+ })]
8064
8264
  })
8065
8265
  });
8066
8266
  }
@@ -10439,7 +10639,7 @@ window.__ModuleLoader__.load({
10439
10639
  });
10440
10640
  }
10441
10641
  //#endregion
10442
- //#region node_modules/.pnpm/simple-icons@16.31.0/node_modules/simple-icons/index.mjs
10642
+ //#region node_modules/.pnpm/simple-icons@16.32.0/node_modules/simple-icons/index.mjs
10443
10643
  const c = "<svg role=\"img\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><title>";
10444
10644
  const t = "</title><path d=\"";
10445
10645
  const a = "\"/></svg>";
@@ -10547,7 +10747,7 @@ window.__ModuleLoader__.load({
10547
10747
  return function PluginInfo() {
10548
10748
  const [latest, setLatest] = (0, react.useState)(null);
10549
10749
  (0, react.useEffect)(() => {
10550
- if ("0.58.0".includes("-dev")) return;
10750
+ if ("0.59.0".includes("-dev")) return;
10551
10751
  let on = true;
10552
10752
  fetchLatestVersion().then((v) => {
10553
10753
  if (on && v) setLatest(v);
@@ -10556,8 +10756,8 @@ window.__ModuleLoader__.load({
10556
10756
  on = false;
10557
10757
  };
10558
10758
  }, []);
10559
- const update = latest !== null && isNewerVersion(latest, "0.58.0") ? latest : null;
10560
- const nameText = "dsh-context (v0.58.0)";
10759
+ const update = latest !== null && isNewerVersion(latest, "0.59.0") ? latest : null;
10760
+ const nameText = "dsh-context (v0.59.0)";
10561
10761
  const nameValue = [nameText];
10562
10762
  if (update) nameValue.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
10563
10763
  className: "lc-pi-update",
@@ -12263,7 +12463,7 @@ window.__ModuleLoader__.load({
12263
12463
  }
12264
12464
  //#endregion
12265
12465
  //#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/overview.css.mjs
12266
- const css = ".lc-ov-entry{box-sizing:border-box;width:calc(100% + 4px);height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:8px;margin:0 -2px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.lc-ov-entry:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-ov-entry-rail{border-radius:50%;flex:none;justify-content:center;gap:0;width:36px;height:36px;margin:0;padding:0}.lc-ov-entry-icon{flex:none}.lc-ov-entry-label{text-align:left;white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;overflow:hidden}.lc-ov-backdrop{z-index:200;background:var(--dsw-alias-bg-mask-1,#00000073);justify-content:center;align-items:center;display:flex;position:fixed;inset:0;container:lc-ov/inline-size}.lc-ov-card{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);width:min(1120px,100vw - 32px);height:calc(100% - 80px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);color:var(--dsw-alias-label-primary);border-radius:12px;flex-direction:column;padding:16px 18px 18px;font-size:13px;display:flex;overflow:hidden}.lc-ov-head{flex-wrap:wrap;flex:none;align-items:center;gap:10px;margin-bottom:14px;display:flex}.lc-ov-head-icon{flex:none}.lc-ov-title{white-space:nowrap;font-size:15px;font-weight:600}.lc-ov-balance{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);max-width:100%;color:inherit;border-radius:999px;flex:none;align-items:center;gap:6px;padding:2px 10px;font-size:12px;line-height:18px;text-decoration:none;display:inline-flex}.lc-ov-balance:hover .lc-ov-balance-value{text-decoration:underline}.lc-ov-balance-label{color:var(--dsw-alias-label-secondary);white-space:nowrap}.lc-ov-balance-value{font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600}.lc-ov-head .lc-modal-close{flex:none;margin-left:0}.lc-ov-kpis{flex:none;grid-template-columns:repeat(6,minmax(0,1fr));gap:10px;margin-bottom:10px;display:grid}.lc-ov-kpi{align-items:center;padding:10px 8px}.lc-ov-kpi .lc-stat-value{font-size:20px}@container lc-ov (width<=1000px){.lc-ov-kpis{grid-template-columns:repeat(3,minmax(0,1fr))}}@container lc-ov (width<=640px){.lc-ov-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}}.lc-ov-stats{flex:none;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-bottom:10px;display:grid}.lc-ov-stats>.lc-card{box-sizing:border-box;min-width:0;margin-bottom:0}@container lc-ov (width<=700px){.lc-ov-stats{grid-template-columns:minmax(0,1fr)}}.lc-ov-body{flex:auto;grid-template-columns:minmax(0,3fr) minmax(0,7fr);gap:10px;min-height:0;display:grid}.lc-ov-left{scrollbar-gutter:stable;flex-direction:column;gap:10px;min-height:0;padding-right:8px;display:flex;overflow-y:auto}.lc-ov-right{scrollbar-gutter:stable;min-height:0;padding-right:8px;overflow-y:auto}@container lc-ov (width<=932px){.lc-ov-card{overflow-y:auto}.lc-ov-body{display:block}.lc-ov-left{margin-bottom:12px}.lc-ov-left,.lc-ov-right{min-height:auto;padding-right:0;overflow:visible}.lc-ov-heat-card{flex:none}}.lc-ov-left>.lc-card{box-sizing:border-box;min-width:0;margin-bottom:0}.lc-ov-heat-card{flex-direction:column;flex:1 0 auto;display:flex}.lc-ov-settings{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:10px;flex:none;align-items:center;gap:8px;padding:9px 12px;font-size:12px;display:flex}.lc-ov-settings:hover{border-color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary)}.lc-ov-settings-label{white-space:nowrap;flex:none;align-items:center;gap:6px;display:inline-flex}.lc-ov-settings-hint{text-align:right;white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;overflow:hidden}.lc-heat-wrap{flex-direction:column;flex:1;display:flex}.lc-heat{flex:1;justify-content:center;align-items:center;gap:8px;display:flex}.lc-heat-wds,.lc-heat-col{padding-top:18px}.lc-heat-wds{flex-direction:column;gap:3px;display:flex}.lc-heat-wd{height:20px;color:var(--dsw-alias-label-secondary);text-align:center;white-space:nowrap;flex:none;justify-content:center;align-items:center;font-size:9px;display:flex}.lc-heat-cols{gap:3px;display:flex}.lc-heat-col{flex-direction:column;gap:3px;display:flex;position:relative}.lc-heat-mon{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:9px;line-height:18px;position:absolute;top:0;left:0}.lc-heat-cell{box-sizing:border-box;background:var(--dsw-alias-bg-layer-2);cursor:default;border:0;border-radius:20%;width:20px;height:20px;padding:0}button.lc-heat-cell{cursor:pointer}button.lc-heat-cell:hover{box-shadow:0 0 0 1.5px color-mix(in srgb, var(--color-blue-500) 70%, transparent)}.lc-heat-future{background:0 0}.lc-heat-0{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 16%, transparent)}.lc-heat-1{background:color-mix(in srgb, var(--color-blue-500) 28%, transparent)}.lc-heat-2{background:color-mix(in srgb, var(--color-blue-500) 50%, transparent)}.lc-heat-3{background:color-mix(in srgb, var(--color-blue-500) 72%, transparent)}.lc-heat-4{background:color-mix(in srgb, var(--color-blue-500) 92%, transparent)}.lc-heat-on{box-shadow:0 0 0 1.5px var(--color-blue-500)}.lc-heat-legend{justify-content:flex-end;align-items:center;gap:3px;padding-top:6px;display:flex}.lc-heat-key{color:var(--dsw-alias-label-secondary);font-size:9px}.lc-ov-list-head{flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:10px;display:flex}.lc-ov-list-title{white-space:nowrap;font-weight:600}.lc-ov-list-count{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;background:var(--dsw-alias-bg-layer-2);border-radius:8px;padding:1px 7px;font-size:11px}.lc-ov-day-chip{border:1px solid color-mix(in srgb, var(--color-blue-500) 45%, transparent);color:var(--color-blue-500);background:color-mix(in srgb, var(--color-blue-500) 10%, transparent);cursor:pointer;white-space:nowrap;border-radius:999px;padding:1px 10px;font-family:inherit;font-size:11px;line-height:1.4}.lc-ov-search{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-width:110px;font:inherit;color:var(--dsw-alias-label-primary);transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;outline:none;flex:150px;padding:4px 10px;font-size:12px}.lc-ov-search:focus{border-color:var(--dsw-alias-label-secondary)}.lc-ov-search::placeholder{color:var(--dsw-alias-label-secondary)}.lc-ov-groups{flex-wrap:wrap;gap:6px;margin:-2px 0 10px;display:flex}.lc-ov-chip{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;white-space:nowrap;text-overflow:ellipsis;max-width:220px;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border-radius:999px;align-items:baseline;gap:5px;padding:2px 10px;font-size:11px;line-height:1.5;display:inline-flex;overflow:hidden}.lc-ov-chip:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-secondary)}.lc-ov-chip-on,.lc-ov-chip-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);border-color:#0000}.lc-ov-chip-n{font-variant-numeric:tabular-nums;opacity:.65;font-size:10px}.lc-ov-chip-on .lc-ov-chip-n{opacity:.85}.lc-ov-grid{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:10px;display:grid}.lc-ov-session{text-align:left;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;font:inherit;color:inherit;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;display:flex}.lc-ov-session:hover{border-color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}.lc-ov-session-current{border-color:color-mix(in srgb, var(--color-blue-500) 65%, transparent)}.lc-ov-session-head{align-items:flex-start;gap:6px;min-width:0;display:flex}.lc-ov-running{background:var(--color-green-500);border-radius:50%;flex:none;width:7px;height:7px}.lc-ov-session-title{-webkit-line-clamp:2;overflow-wrap:anywhere;-webkit-box-orient:vertical;flex:auto;min-width:0;font-weight:600;display:-webkit-box;overflow:hidden}.lc-ov-current{color:var(--color-blue-500);border:1px solid color-mix(in srgb, var(--color-blue-500) 45%, transparent);border-radius:4px;flex:none;padding:0 4px;font-size:10px;line-height:1.5}.lc-ov-session-times{flex-direction:column;flex:none;align-items:flex-end;gap:1px;display:flex}.lc-ov-session-time{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:11px}.lc-ov-session-created{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-variant-numeric:tabular-nums;font-size:10px;line-height:1.4}.lc-ov-session-crumb{min-width:0;color:var(--dsw-alias-label-secondary);white-space:nowrap;align-items:center;gap:5px;font-size:11px;display:flex;overflow:hidden}.lc-ov-crumb-group{text-overflow:ellipsis;flex:none;max-width:55%;overflow:hidden}.lc-ov-crumb-sep{opacity:.55;flex:none}.lc-ov-crumb-project{text-overflow:ellipsis;min-width:0;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);color:var(--dsw-alias-label-primary);background:color-mix(in srgb, var(--dsw-alias-label-secondary) 16%, transparent);border-radius:999px;flex:0 auto;padding:0 8px;font-size:10px;line-height:1.6;overflow:hidden}.lc-ov-session-body{align-items:center;gap:14px;min-width:0;display:flex}.lc-ov-mini-stats{flex-direction:column;flex:auto;gap:3px;min-width:0;display:flex}.lc-ov-mini-stat{justify-content:space-between;align-items:baseline;gap:10px;font-size:11px;display:flex}.lc-ov-mini-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;flex:none}.lc-ov-mini-value{font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600}.lc-ov-session-empty{color:var(--dsw-alias-label-secondary);padding:6px 0;font-size:11px;line-height:1.5}.lc-ov-session-preview{border-top:1px solid color-mix(in srgb, var(--dsw-alias-border-l2) 60%, transparent);align-items:baseline;gap:6px;min-width:0;margin-top:auto;padding-top:6px;display:flex}.lc-ov-session-preview-label{color:var(--dsw-alias-label-secondary);flex:none;font-size:10px}.lc-ov-session-preview-text{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);flex:0 auto;font-size:11px;line-height:1.5;overflow:hidden}.lc-ov-pager{justify-content:center;align-items:center;gap:10px;margin-top:12px;display:flex}.lc-ov-pager-btn{border:1px solid var(--dsw-alias-border-l2);width:26px;height:22px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border-radius:6px;flex:none;justify-content:center;align-items:center;line-height:1;display:flex}.lc-ov-pager-btn:hover:enabled{border-color:var(--dsw-alias-label-secondary)}.lc-ov-pager-btn:disabled{opacity:.4;cursor:default}.lc-ov-pager-n{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:11px}";
12466
+ const css = ".lc-ov-entry{box-sizing:border-box;width:calc(100% + 4px);height:42px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:8px;margin:0 -2px;padding:0 10px 0 8px;font-family:inherit;font-size:14px;line-height:22px;display:flex;overflow:hidden}.lc-ov-entry:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-ov-entry-rail{border-radius:50%;flex:none;justify-content:center;gap:0;width:36px;height:36px;margin:0;padding:0}.lc-ov-entry-icon{flex:none}.lc-ov-entry-label{text-align:left;white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;overflow:hidden}.lc-ov-backdrop{z-index:200;background:var(--dsw-alias-bg-mask-1,#00000073);justify-content:center;align-items:center;display:flex;position:fixed;inset:0;container:lc-ov/inline-size}.lc-ov-card{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);width:min(1120px,100vw - 32px);height:calc(100% - 80px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);color:var(--dsw-alias-label-primary);border-radius:12px;flex-direction:column;padding:16px 18px 18px;font-size:13px;display:flex;overflow:hidden}.lc-ov-head{flex-wrap:wrap;flex:none;align-items:center;gap:10px;margin-bottom:14px;display:flex}.lc-ov-head-icon{flex:none}.lc-ov-title{white-space:nowrap;font-size:15px;font-weight:600}.lc-ov-balance{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);max-width:100%;color:inherit;border-radius:999px;flex:none;align-items:center;gap:6px;padding:2px 10px;font-size:12px;line-height:18px;text-decoration:none;display:inline-flex}.lc-ov-balance:hover .lc-ov-balance-value{text-decoration:underline}.lc-ov-balance-label{color:var(--dsw-alias-label-secondary);white-space:nowrap}.lc-ov-balance-value{font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600}.lc-ov-head .lc-modal-close{flex:none;margin-left:0}.lc-ov-scroll{scrollbar-gutter:stable;flex:auto;min-height:0;padding-right:8px;overflow-y:auto}.lc-ov-first{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-bottom:10px;display:grid}.lc-ov-kpis{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;display:grid}.lc-ov-kpi{align-items:center;padding:8px}.lc-ov-kpi .lc-stat-value{font-size:20px}@container lc-ov (width<=932px){.lc-ov-first{grid-template-columns:minmax(0,1fr)}}@container lc-ov (width<=640px){.lc-ov-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}}.lc-ov-usage{box-sizing:border-box;flex-direction:column;flex:auto;min-width:0;margin-bottom:0;display:flex}.lc-ov-usage .lc-card-title{margin-bottom:4px}.lc-ov-usage-plot{flex:auto;align-items:stretch;gap:6px;min-height:0;display:flex}.lc-ov-usage-rail{width:42px;color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:9px;line-height:1.2;position:relative}.lc-ov-usage-rail-l .lc-ov-usage-tick{right:0}.lc-ov-usage-rail-r .lc-ov-usage-tick{left:0}.lc-ov-usage-tick{white-space:nowrap;position:absolute;transform:translateY(-50%)}.lc-ov-usage-grid{flex:auto;min-width:0;min-height:56px;display:flex;position:relative}.lc-ov-usage-line{background:color-mix(in srgb, var(--dsw-alias-border-l2) 70%, transparent);height:1px;position:absolute;left:0;right:0}.lc-ov-usage-line-0{background:var(--dsw-alias-border-l2)}.lc-ov-usage-cols{flex:auto;align-items:stretch;gap:6px;min-width:0;display:flex;position:relative}.lc-ov-usage-col{flex-direction:column;flex:1 1 0;min-width:0;display:flex}.lc-ov-usage-bars{flex:auto;justify-content:center;align-items:flex-end;gap:3px;width:100%;display:flex}.lc-ov-usage-bar{border-radius:3px 3px 0 0;flex:none;width:10px}.lc-ov-usage-tokens{background:color-mix(in srgb, var(--color-blue-500) 72%, transparent)}.lc-ov-usage-cost{background:color-mix(in srgb, var(--color-green-500) 72%, transparent)}.lc-ov-usage-days{flex:none;gap:6px;padding-top:3px;display:flex}.lc-ov-usage-day{text-align:center;min-width:0;color:var(--dsw-alias-label-secondary);white-space:nowrap;font-variant-numeric:tabular-nums;flex:1 1 0;font-size:9px;line-height:1.2}.lc-ov-usage-key{flex:none;justify-content:flex-end;align-items:center;gap:5px;padding-top:5px;display:flex}.lc-ov-usage-swatch{border-radius:2px;flex:none;width:10px;height:8px}.lc-ov-usage-key-label{color:var(--dsw-alias-label-secondary);font-size:9px}.lc-ov-stats{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-bottom:10px;display:grid}.lc-ov-stats>.lc-card{box-sizing:border-box;min-width:0;margin-bottom:0}@container lc-ov (width<=700px){.lc-ov-stats{grid-template-columns:minmax(0,1fr)}}.lc-ov-body{grid-template-columns:minmax(0,3fr) minmax(0,7fr);align-items:start;gap:10px;display:grid}.lc-ov-left{flex-direction:column;gap:10px;min-width:0;display:flex}.lc-ov-right{min-width:0}@container lc-ov (width<=932px){.lc-ov-body{display:block}.lc-ov-left{margin-bottom:12px}}.lc-ov-left>.lc-card{box-sizing:border-box;min-width:0;margin-bottom:0}.lc-ov-heat-card{flex-direction:column;display:flex}.lc-ov-settings{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);width:100%;font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:10px;flex:none;align-items:center;gap:8px;padding:9px 12px;font-size:12px;display:flex}.lc-ov-settings:hover{border-color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary)}.lc-ov-settings-label{white-space:nowrap;flex:none;align-items:center;gap:6px;display:inline-flex}.lc-ov-settings-hint{text-align:right;white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;overflow:hidden}.lc-heat-wrap{flex-direction:column;flex:1;display:flex}.lc-heat{flex:1;justify-content:center;align-items:center;gap:8px;display:flex}.lc-heat-wds,.lc-heat-col{padding-top:18px}.lc-heat-wds{flex-direction:column;gap:3px;display:flex}.lc-heat-wd{height:20px;color:var(--dsw-alias-label-secondary);text-align:center;white-space:nowrap;flex:none;justify-content:center;align-items:center;font-size:9px;display:flex}.lc-heat-cols{gap:3px;display:flex}.lc-heat-col{flex-direction:column;gap:3px;display:flex;position:relative}.lc-heat-mon{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:9px;line-height:18px;position:absolute;top:0;left:0}.lc-heat-cell{box-sizing:border-box;background:var(--dsw-alias-bg-layer-2);cursor:default;border:0;border-radius:20%;width:20px;height:20px;padding:0}button.lc-heat-cell{cursor:pointer}button.lc-heat-cell:hover{box-shadow:0 0 0 1.5px color-mix(in srgb, var(--color-blue-500) 70%, transparent)}.lc-heat-future{background:0 0}.lc-heat-0{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 16%, transparent)}.lc-heat-1{background:color-mix(in srgb, var(--color-blue-500) 28%, transparent)}.lc-heat-2{background:color-mix(in srgb, var(--color-blue-500) 50%, transparent)}.lc-heat-3{background:color-mix(in srgb, var(--color-blue-500) 72%, transparent)}.lc-heat-4{background:color-mix(in srgb, var(--color-blue-500) 92%, transparent)}.lc-heat-on{box-shadow:0 0 0 1.5px var(--color-blue-500)}.lc-heat-legend{justify-content:flex-end;align-items:center;gap:3px;padding-top:6px;display:flex}.lc-heat-key{color:var(--dsw-alias-label-secondary);font-size:9px}.lc-ov-list-head{flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:10px;display:flex}.lc-ov-list-title{white-space:nowrap;font-weight:600}.lc-ov-list-count{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;background:var(--dsw-alias-bg-layer-2);border-radius:8px;padding:1px 7px;font-size:11px}.lc-ov-day-chip{border:1px solid color-mix(in srgb, var(--color-blue-500) 45%, transparent);color:var(--color-blue-500);background:color-mix(in srgb, var(--color-blue-500) 10%, transparent);cursor:pointer;white-space:nowrap;border-radius:999px;padding:1px 10px;font-family:inherit;font-size:11px;line-height:1.4}.lc-ov-search{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);min-width:110px;font:inherit;color:var(--dsw-alias-label-primary);transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;outline:none;flex:150px;padding:4px 10px;font-size:12px}.lc-ov-search:focus{border-color:var(--dsw-alias-label-secondary)}.lc-ov-search::placeholder{color:var(--dsw-alias-label-secondary)}.lc-ov-groups{flex-wrap:wrap;gap:6px;margin:-2px 0 10px;display:flex}.lc-ov-chip{border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;white-space:nowrap;text-overflow:ellipsis;max-width:220px;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border-radius:999px;align-items:baseline;gap:5px;padding:2px 10px;font-size:11px;line-height:1.5;display:inline-flex;overflow:hidden}.lc-ov-chip:hover{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-secondary)}.lc-ov-chip-on,.lc-ov-chip-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground);border-color:#0000}.lc-ov-chip-n{font-variant-numeric:tabular-nums;opacity:.65;font-size:10px}.lc-ov-chip-on .lc-ov-chip-n{opacity:.85}.lc-ov-grid{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:10px;display:grid}.lc-ov-session{text-align:left;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;font:inherit;color:inherit;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;display:flex}.lc-ov-session:hover{border-color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}.lc-ov-session-current{border-color:color-mix(in srgb, var(--color-blue-500) 65%, transparent)}.lc-ov-session-head{align-items:flex-start;gap:6px;min-width:0;display:flex}.lc-ov-running{background:var(--color-green-500);border-radius:50%;flex:none;width:7px;height:7px}.lc-ov-session-title{-webkit-line-clamp:2;overflow-wrap:anywhere;-webkit-box-orient:vertical;flex:auto;min-width:0;font-weight:600;display:-webkit-box;overflow:hidden}.lc-ov-current{color:var(--color-blue-500);border:1px solid color-mix(in srgb, var(--color-blue-500) 45%, transparent);border-radius:4px;flex:none;padding:0 4px;font-size:10px;line-height:1.5}.lc-ov-session-times{flex-direction:column;flex:none;align-items:flex-end;gap:1px;display:flex}.lc-ov-session-time{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:11px}.lc-ov-session-created{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-variant-numeric:tabular-nums;font-size:10px;line-height:1.4}.lc-ov-session-crumb{min-width:0;color:var(--dsw-alias-label-secondary);white-space:nowrap;align-items:center;gap:5px;font-size:11px;display:flex;overflow:hidden}.lc-ov-crumb-group{text-overflow:ellipsis;flex:none;max-width:55%;overflow:hidden}.lc-ov-crumb-sep{opacity:.55;flex:none}.lc-ov-crumb-project{text-overflow:ellipsis;min-width:0;font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);color:var(--dsw-alias-label-primary);background:color-mix(in srgb, var(--dsw-alias-label-secondary) 16%, transparent);border-radius:999px;flex:0 auto;padding:0 8px;font-size:10px;line-height:1.6;overflow:hidden}.lc-ov-session-body{align-items:center;gap:14px;min-width:0;display:flex}.lc-ov-mini-stats{flex-direction:column;flex:auto;gap:3px;min-width:0;display:flex}.lc-ov-mini-stat{justify-content:space-between;align-items:baseline;gap:10px;font-size:11px;display:flex}.lc-ov-mini-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;flex:none}.lc-ov-mini-value{font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:600}.lc-ov-session-empty{color:var(--dsw-alias-label-secondary);padding:6px 0;font-size:11px;line-height:1.5}.lc-ov-session-preview{border-top:1px solid color-mix(in srgb, var(--dsw-alias-border-l2) 60%, transparent);align-items:baseline;gap:6px;min-width:0;margin-top:auto;padding-top:6px;display:flex}.lc-ov-session-preview-label{color:var(--dsw-alias-label-secondary);flex:none;font-size:10px}.lc-ov-session-preview-text{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary);flex:0 auto;font-size:11px;line-height:1.5;overflow:hidden}.lc-ov-pager{justify-content:center;align-items:center;gap:10px;margin-top:12px;display:flex}.lc-ov-pager-btn{border:1px solid var(--dsw-alias-border-l2);width:26px;height:22px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);background:0 0;border-radius:6px;flex:none;justify-content:center;align-items:center;line-height:1;display:flex}.lc-ov-pager-btn:hover:enabled{border-color:var(--dsw-alias-label-secondary)}.lc-ov-pager-btn:disabled{opacity:.4;cursor:default}.lc-ov-pager-n{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;font-size:11px}";
12267
12467
  const tagId = "dsh-context/overview.css";
12268
12468
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
12269
12469
  const tag = document.createElement("style");