cctally 1.10.0 → 1.10.2

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/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [1.10.2] - 2026-05-21
9
+
10
+ ### Fixed
11
+ - `blocks` panel + CLI no longer renders a phantom ACTIVE heuristic block when a canonical 5h reset doesn't fall on a 10-minute boundary. The legacy partition predicate used `[R_floored - 5h, R_floored)` as the bucket interval, so floor-band entries — session timestamps inside `[floor(R), R)` (e.g. the 09:30–09:39:59 UTC band for a 09:39:59 reset) — fell into neither the preceding nor the following recorded bucket, dropped to `leftover`, and became a phantom heuristic block running `+5h` from `floor_to_hour(first_leftover_entry)`. With current-time activity in the band, that phantom block was `is_active=True` and overlapped the real canonical ACTIVE block, surfacing as TWO ACTIVE rows in `cctally blocks` and a `~HH:00` heuristic plus a `HH:40` recorded entry in the dashboard `/api/data` payload. The fix routes both the entry partition AND the recorded `Block` construction (start_time / end_time / is_active / burn / projection) through a single `_exact_interval(R)` helper that returns the canonical `(block_start_at, five_hour_resets_at)` from `five_hour_blocks` (jitter intact); `_load_recorded_five_hour_windows` grows a third return — `canonical_intervals: {R_floored → (bs_utc, rs_utc)}` — plumbed through `build_blocks_view`, `cmd_blocks`, `_dashboard_build_blocks_view`, and the `/api/block/:start_at` handler. Raw-only anchors (no canonical `five_hour_blocks` row) fall back to the legacy `(R - 5h, R)` shape. Credit-truncated anchors compose with the new path: the truncation rewrites the upper bound in-place inside `canonical_intervals` while preserving the override-supplied `bs`. Regression: new `tests/fixtures/blocks/floor-band-trap/` scenario (canonical reset at `T:39:59 UTC` with 8 dense entries in the trap band) locks the kernel behavior; new `test_block_detail_floor_band_trap_returns_exact_window` in `tests/test_dashboard_api_block.py` covers the panel ↔ detail consistency surface (clicking a block whose canonical reset is off the 10-min boundary returns 200 with the exact `bs` window instead of 404'ing against the floored bs). ([#76](https://github.com/omrikais/cctally-dev/issues/76))
12
+
13
+ ## [1.10.1] - 2026-05-20
14
+
15
+ ### Fixed
16
+ - dashboard static bundle: `dashboard/static/assets/index-*.js` now matches the TypeScript source. Three Projects-modal fixes that landed on `feat/projects-panel` in the final review round (drill stale-on-window-switch guard, persisted-selection re-bind on dropout, mobile sort cycle's `first_seen` direction) were applied to `dashboard/web/src/modals/*.tsx` but the regenerated Vite bundle was never committed, so the committed `dashboard/static/assets/index-DUKjFlG8.js` lagged the TSX by those three commits. Running `npm run build` (`tsc --noEmit && vite build`) produces `index-Cy59E7Ru.js` instead, and `dashboard/static/dashboard.html` now references it. The Python-side share `period_end` clip from the same review round shipped correctly on v1.10.0 via `bin/_cctally_dashboard.py`; this is purely a bundle-rebuild closure. CI regression: `dashboard-build-stability` job runs `git diff --exit-code dashboard/static/` after `npm run build`.
17
+
8
18
  ## [1.10.0] - 2026-05-20
9
19
 
10
20
  ### Added
@@ -2330,8 +2330,8 @@ def _dashboard_build_blocks_view(conn: "sqlite3.Connection",
2330
2330
  entries = get_entries(fetch_start, fetch_end, skip_sync=skip_sync)
2331
2331
  entries = [e for e in entries if week_start_at <= e.timestamp < week_end_at]
2332
2332
 
2333
- recorded_windows, block_start_overrides = _load_recorded_five_hour_windows(
2334
- fetch_start, fetch_end,
2333
+ recorded_windows, block_start_overrides, canonical_intervals = (
2334
+ _load_recorded_five_hour_windows(fetch_start, fetch_end)
2335
2335
  )
2336
2336
  c = _cctally()
2337
2337
  return c.build_blocks_view(
@@ -2339,6 +2339,7 @@ def _dashboard_build_blocks_view(conn: "sqlite3.Connection",
2339
2339
  now_utc=now_utc,
2340
2340
  recorded_windows=recorded_windows,
2341
2341
  block_start_overrides=block_start_overrides,
2342
+ canonical_intervals=canonical_intervals,
2342
2343
  range_start=week_start_at,
2343
2344
  range_end=week_end_at,
2344
2345
  display_tz=display_tz,
@@ -5997,7 +5998,7 @@ class DashboardHTTPHandler(BaseHTTPRequestHandler):
5997
5998
  now_utc = _command_as_of()
5998
5999
  # Recorded-windows lookup widens by one block on each side so
5999
6000
  # a recorded reset just outside the bounds can still anchor.
6000
- recorded_windows, block_start_overrides = (
6001
+ recorded_windows, block_start_overrides, canonical_intervals = (
6001
6002
  _load_recorded_five_hour_windows(
6002
6003
  start_at - BLOCK_DURATION, end_at + BLOCK_DURATION,
6003
6004
  )
@@ -6020,6 +6021,7 @@ class DashboardHTTPHandler(BaseHTTPRequestHandler):
6020
6021
  entries_in_window, mode="auto",
6021
6022
  recorded_windows=recorded_windows,
6022
6023
  block_start_overrides=block_start_overrides,
6024
+ canonical_intervals=canonical_intervals,
6023
6025
  now=now_utc,
6024
6026
  )
6025
6027
  target = next(
@@ -95,6 +95,9 @@ def _group_entries_into_blocks(
95
95
  *,
96
96
  recorded_windows: list[dt.datetime] | None = None,
97
97
  block_start_overrides: dict[dt.datetime, dt.datetime] | None = None,
98
+ canonical_intervals: dict[
99
+ dt.datetime, tuple[dt.datetime, dt.datetime]
100
+ ] | None = None,
98
101
  now: dt.datetime | None = None,
99
102
  ) -> list[Block]:
100
103
  """Group sorted UsageEntry objects into 5-hour blocks with gap detection.
@@ -103,21 +106,29 @@ def _group_entries_into_blocks(
103
106
  The last block is marked active if now < block_start + 5h.
104
107
 
105
108
  When `recorded_windows` is non-empty, entries whose timestamp falls in
106
- [R - BLOCK_DURATION, R) for some R in recorded_windows are partitioned
107
- into per-R buckets and built as 'recorded' blocks. Leftover entries
108
- run through the existing gap-detection heuristic (anchor='heuristic').
109
+ the exact ``[bs, rs)`` interval of each accepted anchor are
110
+ partitioned into per-R buckets and built as 'recorded' blocks.
111
+ Leftover entries run through the existing gap-detection heuristic
112
+ (anchor='heuristic').
113
+
114
+ `canonical_intervals` (issue #76): an optional
115
+ ``{R_floored → (bs_utc, rs_utc)}`` map carrying the EXACT
116
+ ``(block_start_at, five_hour_resets_at)`` per accepted anchor. Drives
117
+ both the partition predicate AND Phase 1.5 ``Block`` construction
118
+ so floor-band entries (timestamps inside ``[floor(R), R)`` for a
119
+ canonical reset that doesn't fall on a 10-minute boundary) land in
120
+ the right bucket and the rendered window matches Anthropic's actual
121
+ interval. Anchors missing from the map fall back to ``(R - 5h, R)``
122
+ (the legacy floored shape) — preserves raw-only / pre-rollup
123
+ history behavior.
109
124
 
110
125
  `block_start_overrides` (v1.7.2 round-5 / Bug J): an optional
111
- `{R → block_start_at}` map. When present for a given R, the
112
- recorded block's displayed ``start_time`` becomes the override
113
- instead of the default ``R - BLOCK_DURATION``. Used by
114
- ``_load_recorded_five_hour_windows`` to preserve the real
115
- ``five_hour_blocks.block_start_at`` for credit-truncated windows
116
- (an in-place credit shortens the prior 5h block's effective end
117
- to the credit moment, but the block's API-derived START is
118
- unchanged — without an override the renderer would compute
119
- ``start = truncated_R - 5h`` which is hours before the real start
120
- and confuses the user with an off-by-hours window header).
126
+ ``{R → block_start_at}`` map. Provides the same override semantics
127
+ for callers that don't pass ``canonical_intervals``. When BOTH are
128
+ present, ``canonical_intervals`` wins (the credit-truncation path
129
+ in ``_load_recorded_five_hour_windows`` writes a unified entry
130
+ into ``canonical_intervals`` already carrying the override-supplied
131
+ ``bs`` and the truncated ``rs``).
121
132
 
122
133
  `now` pins the current instant (typically via `_command_as_of()`). When
123
134
  omitted, falls back to wall clock so existing callers are unaffected.
@@ -131,31 +142,44 @@ def _group_entries_into_blocks(
131
142
 
132
143
  recorded_windows = sorted(recorded_windows or [])
133
144
  block_start_overrides = block_start_overrides or {}
145
+ canonical_intervals = canonical_intervals or {}
146
+
147
+ # Single source of truth for the (bs, rs) interval of each accepted
148
+ # anchor — shared by the partition predicate below AND Phase 1.5
149
+ # block construction. issue #76: a 10-min-floored R as a partition
150
+ # boundary trapped floor-band entries into a phantom heuristic
151
+ # block whenever R was off the 10-min boundary; routing both
152
+ # surfaces through this helper keeps them consistent.
153
+ def _exact_interval(R: dt.datetime) -> tuple[dt.datetime, dt.datetime]:
154
+ if R in canonical_intervals:
155
+ return canonical_intervals[R]
156
+ bs = block_start_overrides.get(R, R - BLOCK_DURATION)
157
+ return (bs, R)
134
158
 
135
159
  # ── Partition entries by recorded windows ──────────────────────────
136
160
  # For each R in recorded_windows, entries whose timestamp falls in
137
- # [override_start_or_R-5h, R) go into recorded_buckets[R]. Everything
138
- # else (gaps between recorded windows, or fully outside any window)
139
- # drops into `leftover` and runs through the existing heuristic
140
- # grouper.
141
- #
142
- # Why override_start_or_R-5h, not always R-5h: a credit-truncated
143
- # canonical block has R = effective_reset_at_utc (e.g. 17:58Z) but
144
- # its real ``block_start_at`` is unchanged (e.g. 15:50Z). Using
145
- # `R - 5h` as the partition floor would pull entries from earlier
146
- # blocks (e.g. 12:58-15:50Z range) into the truncated bucket. The
147
- # override keeps the real start so each entry lands in the bucket
148
- # whose API-defined interval actually contains it.
161
+ # [bs, rs) (the EXACT canonical interval, NOT the 10-min-floored
162
+ # shape) go into recorded_buckets[R]. Everything else (gaps between
163
+ # recorded windows, or fully outside any window) drops into
164
+ # `leftover` and runs through the existing heuristic grouper.
149
165
  recorded_buckets: dict[dt.datetime, list[UsageEntry]] = {
150
166
  R: [] for R in recorded_windows
151
167
  }
152
168
  leftover: list[UsageEntry] = []
169
+ # Sort the (interval, R) pairs by rs so bisect_right(rs_keys, ts)
170
+ # locates the candidate window in O(log n) per entry.
171
+ sorted_intervals: list[
172
+ tuple[tuple[dt.datetime, dt.datetime], dt.datetime]
173
+ ] = sorted(
174
+ [(_exact_interval(R), R) for R in recorded_windows],
175
+ key=lambda item: item[0][1],
176
+ )
177
+ rs_keys = [iv[0][1] for iv in sorted_intervals]
153
178
  for entry in entries_sorted:
154
- idx = bisect.bisect_right(recorded_windows, entry.timestamp)
155
- if idx < len(recorded_windows):
156
- R = recorded_windows[idx]
157
- bucket_start = block_start_overrides.get(R, R - BLOCK_DURATION)
158
- if bucket_start <= entry.timestamp:
179
+ idx = bisect.bisect_right(rs_keys, entry.timestamp)
180
+ if idx < len(sorted_intervals):
181
+ (bs, rs), R = sorted_intervals[idx]
182
+ if bs <= entry.timestamp < rs:
159
183
  recorded_buckets[R].append(entry)
160
184
  continue
161
185
  leftover.append(entry)
@@ -192,17 +216,22 @@ def _group_entries_into_blocks(
192
216
 
193
217
  # Clamp each raw_block's end so it cannot overlap a later recorded
194
218
  # window. Entries in `leftover` are by construction earlier than the
195
- # next recorded R - 5h boundary, so the heuristic block belongs to a
196
- # PREVIOUS 5h window that ended no later than that boundary. Without
197
- # this clamp, the +5h heuristic span can cross into the recorded
198
- # window and produce two simultaneously-active rows.
219
+ # next recorded window's real ``bs``, so the heuristic block belongs
220
+ # to a PREVIOUS 5h window that ended no later than that boundary.
221
+ # Without this clamp, the +5h heuristic span can cross into the
222
+ # recorded window and produce two simultaneously-active rows.
223
+ # issue #76: use the EXACT ``bs`` from ``_exact_interval`` so the
224
+ # clamp matches the partition predicate above (using a floored
225
+ # ``R - 5h`` would leave a sliver of overlap whenever bs sits in
226
+ # the 10-min floor band).
199
227
  if recorded_windows:
200
228
  for rb in raw_blocks:
201
229
  idx = bisect.bisect_right(recorded_windows, rb["start"])
202
230
  if idx < len(recorded_windows):
203
- next_R_start = recorded_windows[idx] - BLOCK_DURATION
204
- if rb["start"] < next_R_start < rb["end"]:
205
- rb["end"] = next_R_start
231
+ next_R = recorded_windows[idx]
232
+ next_bs, _next_rs = _exact_interval(next_R)
233
+ if rb["start"] < next_bs < rb["end"]:
234
+ rb["end"] = next_bs
206
235
 
207
236
  # Track the "actual first entry timestamp" for each block so Phase 3
208
237
  # can compute gap ends the same way the legacy interleaved code did
@@ -210,18 +239,19 @@ def _group_entries_into_blocks(
210
239
  # floor-to-hour window start). Maps id(block) -> actual first ts.
211
240
  first_entry_ts_by_block: dict[int, dt.datetime] = {}
212
241
 
213
- # Phase 1.5: Build recorded Block objects from non-empty buckets
242
+ # Phase 1.5: Build recorded Block objects from non-empty buckets.
243
+ # issue #76: ``start_time`` / ``end_time`` come from the SAME
244
+ # ``_exact_interval(R)`` that drives the partition predicate above.
245
+ # Without this, a canonical reset off the 10-min boundary would
246
+ # render with the floored window (off by up to 9m59s) and
247
+ # ``is_active`` / burn / projection would compute against the
248
+ # wrong endpoints, even though the partition was correct.
214
249
  recorded_block_objs: list[Block] = []
215
250
  for R in recorded_windows:
216
251
  bucket = recorded_buckets[R]
217
252
  if not bucket:
218
253
  continue
219
- # Display start: override when present (credit-truncated
220
- # canonical blocks need their real block_start_at so the
221
- # rendered window header matches Anthropic's actual interval);
222
- # default to R - BLOCK_DURATION for normal canonical anchors.
223
- start_time = block_start_overrides.get(R, R - BLOCK_DURATION)
224
- end_time = R
254
+ start_time, end_time = _exact_interval(R)
225
255
  bucket_sorted = sorted(bucket, key=lambda e: e.timestamp)
226
256
  blk = _build_activity_block(
227
257
  bucket_sorted, start_time, end_time, now, mode,
@@ -1146,6 +1146,7 @@ def build_blocks_view(
1146
1146
  now_utc,
1147
1147
  recorded_windows=None,
1148
1148
  block_start_overrides=None,
1149
+ canonical_intervals=None,
1149
1150
  range_start=None,
1150
1151
  range_end=None,
1151
1152
  display_tz=None,
@@ -1191,6 +1192,7 @@ def build_blocks_view(
1191
1192
  mode=mode,
1192
1193
  recorded_windows=recorded_windows,
1193
1194
  block_start_overrides=block_start_overrides,
1195
+ canonical_intervals=canonical_intervals,
1194
1196
  now=now_utc,
1195
1197
  )
1196
1198
  rows: list = []
package/bin/cctally CHANGED
@@ -3401,10 +3401,42 @@ def _select_non_overlapping_recorded_windows(
3401
3401
  def _load_recorded_five_hour_windows(
3402
3402
  range_start: dt.datetime,
3403
3403
  range_end: dt.datetime,
3404
- ) -> tuple[list[dt.datetime], dict[dt.datetime, dt.datetime]]:
3404
+ ) -> tuple[
3405
+ list[dt.datetime],
3406
+ dict[dt.datetime, dt.datetime],
3407
+ dict[dt.datetime, tuple[dt.datetime, dt.datetime]],
3408
+ ]:
3405
3409
  """Return sorted, UTC-aware recorded ``five_hour_resets_at`` values
3406
3410
  that anchor real 5h windows in ``[range_start, range_end]``.
3407
3411
 
3412
+ Returns a 3-tuple ``(selected, block_start_overrides, canonical_intervals)``:
3413
+
3414
+ * ``selected``: list of 10-min-floored ``R`` anchors (sorted),
3415
+ each representing one accepted canonical 5h window. Same shape
3416
+ as before — drives `_group_entries_into_blocks`'s
3417
+ ``recorded_windows=`` kwarg.
3418
+
3419
+ * ``block_start_overrides``: ``{R_floored → block_start_at_utc}``
3420
+ for credit-truncated anchors (Bug J). When a credit moment
3421
+ falls inside a canonical block's overlap with the next block,
3422
+ the earlier ``R`` is replaced by the credit moment (floored to
3423
+ 10 min) and the original ``block_start_at`` is recorded here so
3424
+ the renderer keeps the real display start.
3425
+
3426
+ * ``canonical_intervals``: ``{R_floored → (bs_utc, rs_utc)}``
3427
+ carrying the **exact** ``(block_start_at, five_hour_resets_at)``
3428
+ for every selected anchor that has a canonical
3429
+ ``five_hour_blocks`` row. ``rs_utc`` is the un-floored reset
3430
+ moment (jitter intact), ``bs_utc`` is the API-derived block
3431
+ start normalized to UTC. Drives `_group_entries_into_blocks`'s
3432
+ partition predicate AND Phase 1.5 block construction
3433
+ (issue #76 — 10-min-floor partition trap). Anchors with no
3434
+ canonical row (legacy weekly-snapshots-only) are absent from
3435
+ the map and the partitioner falls back to ``(R - 5h, R)``.
3436
+ Credit-truncated anchors land here with the truncated upper
3437
+ bound (``rs = effective_reset``) and the override-supplied
3438
+ ``bs`` (the real pre-truncation block start).
3439
+
3408
3440
  Two sources contribute to the merged anchor set:
3409
3441
 
3410
3442
  1. ``weekly_usage_snapshots.five_hour_resets_at`` — every
@@ -3515,7 +3547,7 @@ def _load_recorded_five_hour_windows(
3515
3547
  # OSError covers ensure_dirs() failures (read-only FS, permission
3516
3548
  # denied on parent dir) that propagate from open_db() before any
3517
3549
  # SQL runs. Either way, fall back to the heuristic anchor path.
3518
- return [], {}
3550
+ return [], {}, {}
3519
3551
  counts: dict[dt.datetime, int] = {}
3520
3552
  for row in rows:
3521
3553
  raw = row["five_hour_resets_at"] if hasattr(row, "keys") else row[0]
@@ -3571,6 +3603,21 @@ def _load_recorded_five_hour_windows(
3571
3603
  canonical_pairs.append((bs, rs))
3572
3604
  canonical_pairs.sort(key=lambda p: p[0])
3573
3605
 
3606
+ # issue #76: canonical_intervals maps every floored R -> its EXACT
3607
+ # (block_start_at, five_hour_resets_at) — both UTC, rs un-floored
3608
+ # (jitter intact). Drives the partition predicate AND Phase 1.5
3609
+ # block construction in `_group_entries_into_blocks` so floor-band
3610
+ # entries (timestamps in [floor(R), R)) land in the right bucket
3611
+ # and the displayed window matches Anthropic's actual interval.
3612
+ # Built before the credit-truncation loop below so that loop can
3613
+ # rewrite the upper bound in-place (truncated R replaces rs).
3614
+ canonical_intervals: dict[
3615
+ dt.datetime, tuple[dt.datetime, dt.datetime]
3616
+ ] = {}
3617
+ for bs, rs in canonical_pairs:
3618
+ snapped = _floor_to_ten_minutes(rs)
3619
+ canonical_intervals[snapped] = (bs, rs)
3620
+
3574
3621
  # Detect overlap-with-credit and replace the earlier R with a
3575
3622
  # credit-truncated anchor. The (anchor → real_block_start) map is
3576
3623
  # returned alongside the anchor list so the renderer can show the
@@ -3595,6 +3642,21 @@ def _load_recorded_five_hour_windows(
3595
3642
  if bs < cm_floored < rs:
3596
3643
  truncated_R = cm_floored
3597
3644
  block_start_overrides[cm_floored] = bs
3645
+ # Rewrite canonical_intervals[snapped_orig]
3646
+ # to the truncated interval under the
3647
+ # truncated key. issue #76: the
3648
+ # partitioner reads canonical_intervals
3649
+ # for the exact bs/rs; the truncated entry
3650
+ # must reflect the credit-shifted upper
3651
+ # bound (cm_floored) AND the real bs (the
3652
+ # override) so partition + Phase 1.5
3653
+ # render the credit-shortened block
3654
+ # consistently.
3655
+ snapped_orig = _floor_to_ten_minutes(rs)
3656
+ canonical_intervals.pop(snapped_orig, None)
3657
+ canonical_intervals[cm_floored] = (
3658
+ bs, cm_floored,
3659
+ )
3598
3660
  break
3599
3661
  truncated_pairs.append((bs, truncated_R))
3600
3662
 
@@ -3634,7 +3696,16 @@ def _load_recorded_five_hour_windows(
3634
3696
  selected = sorted(
3635
3697
  list(selected_non_truncated) + list(truncated_anchors)
3636
3698
  )
3637
- return selected, block_start_overrides
3699
+ # Filter canonical_intervals down to selected anchors. Raw-only
3700
+ # anchors (selected via weekly_usage_snapshots but absent from
3701
+ # five_hour_blocks) stay out of the map; the partitioner falls
3702
+ # back to (R - 5h, R) for them. issue #76 / spec §1.1 D1.
3703
+ canonical_intervals = {
3704
+ R: canonical_intervals[R]
3705
+ for R in selected
3706
+ if R in canonical_intervals
3707
+ }
3708
+ return selected, block_start_overrides, canonical_intervals
3638
3709
 
3639
3710
 
3640
3711
  def cmd_blocks(args: argparse.Namespace) -> int:
@@ -3679,8 +3750,10 @@ def cmd_blocks(args: argparse.Namespace) -> int:
3679
3750
  # reset R just after ``range_end`` (e.g. the active window when
3680
3751
  # range_end is wall-clock "now") can still anchor entries that fall
3681
3752
  # inside [range_start, range_end].
3682
- recorded_windows, block_start_overrides = _load_recorded_five_hour_windows(
3683
- range_start - BLOCK_DURATION, range_end + BLOCK_DURATION,
3753
+ recorded_windows, block_start_overrides, canonical_intervals = (
3754
+ _load_recorded_five_hour_windows(
3755
+ range_start - BLOCK_DURATION, range_end + BLOCK_DURATION,
3756
+ )
3684
3757
  )
3685
3758
 
3686
3759
  # Group into blocks via the view-model kernel (issue #56). The
@@ -3700,6 +3773,7 @@ def cmd_blocks(args: argparse.Namespace) -> int:
3700
3773
  now_utc=now_utc,
3701
3774
  recorded_windows=recorded_windows,
3702
3775
  block_start_overrides=block_start_overrides,
3776
+ canonical_intervals=canonical_intervals,
3703
3777
  range_start=range_start,
3704
3778
  range_end=range_end,
3705
3779
  display_tz=tz,
@@ -15,4 +15,4 @@ Error generating stack: `+e.message+`
15
15
  `]},t):e.type===`exit`?(0,z.jsxs)(`span`,{className:`update-stream-exit`,children:[`(exited rc=${e.rc??`?`})`,`
16
16
  `]},t):(0,z.jsxs)(`span`,{className:`update-stream-line`,children:[e.data??``,`
17
17
  `]},t))]})}var Co=3e3,wo=1e3;function To(e){if(e==null)return`0s`;let t=Math.max(0,Math.round((Date.now()-e)/1e3));return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}function Eo(){let e=(0,g.useSyncExternalStore)(L,()=>I().update),t=e.runId,n=e.startedAt,r=e.state?.update_command??``,i=e.state?.latest_version??``,[,a]=(0,g.useState)(0);(0,g.useEffect)(()=>{let e=window.setInterval(()=>a(e=>e+1),1e3);return()=>window.clearInterval(e)},[]);let o=(0,g.useRef)(!1);return(0,g.useEffect)(()=>{if(!t)return;let e=null,n=null,r=null,i=!1;o.current=!0;function a(){r!=null&&(window.clearTimeout(r),r=null),o.current=!1}function s(t,n){a();let r={};try{t instanceof MessageEvent&&typeof t.data==`string`&&(r=JSON.parse(t.data))}catch{}if(R({type:`APPEND_UPDATE_STREAM`,event:{type:n,data:typeof r.data==`string`?r.data:void 0,name:typeof r.name==`string`?r.name:void 0,rc:typeof r.rc==`number`?r.rc:void 0,step:typeof r.step==`string`?r.step:void 0,message:typeof r.message==`string`?r.message:void 0,ts:typeof r.ts==`number`?r.ts:void 0}}),n===`exit`){let e=typeof r.rc==`number`?r.rc:-1;e!==0&&R({type:`SET_UPDATE_STATUS`,status:`failed`,errorMessage:`subprocess exited with rc=${e}`})}else n===`execvp`?R({type:`SET_UPDATE_STATUS`,status:`success`}):n===`error_event`?R({type:`SET_UPDATE_STATUS`,status:`failed`,errorMessage:typeof r.message==`string`?r.message:`update worker error`}):n===`done`&&(e&&=(e.close(),null))}function c(){n??=window.setInterval(async()=>{if(!i)try{let e=await fetch(`/api/update/status`);if(!e.ok)return;let t=await e.json(),r=t?.current_run_id??null,i=t?.state??{};if(r===null){let e=i?.current_version,t=i?.latest_version,r=I().update;typeof e==`string`&&typeof t==`string`&&e===t?R({type:`SET_UPDATE_STATUS`,status:`success`}):r.status===`running`&&R({type:`SET_UPDATE_STATUS`,status:`failed`,errorMessage:`update worker exited (stream unavailable)`}),r.stream.length===0&&R({type:`APPEND_UPDATE_STREAM`,event:{type:`stdout`,data:`(SSE stream unavailable; install completed in background — see ~/.local/share/cctally/update.log for full output)`}}),n!=null&&(window.clearInterval(n),n=null)}}catch{}},wo)}r=window.setTimeout(()=>{i||o.current&&(o.current=!1,e&&=(e.close(),null),c())},Co);try{e=new EventSource(`/api/update/stream/${encodeURIComponent(t)}`),e.addEventListener(`message`,e=>s(e,`stdout`)),[`stdout`,`stderr`,`step`,`exit`,`execvp`,`error_event`,`done`,`heartbeat`].forEach(t=>{e.addEventListener(t,e=>s(e,t))}),e.onerror=()=>{o.current&&(a(),e&&=(e.close(),null),c())}}catch{a(),c()}return()=>{i=!0,r!=null&&(window.clearTimeout(r),r=null),n!=null&&(window.clearInterval(n),n=null),e&&=(e.close(),null),o.current=!1,nt()}},[t]),(0,z.jsxs)(`div`,{className:`update-modal-body`,children:[(0,z.jsxs)(`div`,{className:`update-running-row`,children:[(0,z.jsx)(`span`,{className:`update-spinner`,"aria-hidden":`true`,children:`⟳`}),(0,z.jsx)(`code`,{className:`update-cmd update-cmd-inline`,children:r||`updating cctally`}),(0,z.jsxs)(`span`,{className:`update-elapsed`,children:[To(n),` elapsed`]})]}),(0,z.jsx)(Y,{events:e.stream}),(0,z.jsxs)(`p`,{className:`update-stream-cap`,children:[`Output streams over SSE · press Esc to hide (install continues to `,i||`latest`,`)`]})]})}var Do=1500;function Oo(e){if(e==null)return`—`;let t=Math.max(0,Math.round((Date.now()-e)/1e3));return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}function ko(){let e=(0,g.useSyncExternalStore)(L,()=>I().update),t=e.startedAt,n=e.state?.update_command??``,r=e.state?.latest_version??``;return(0,g.useEffect)(()=>{let e=window.setInterval(()=>{nt()},Do);return()=>window.clearInterval(e)},[]),(0,z.jsxs)(`div`,{className:`update-modal-body`,children:[(0,z.jsxs)(`div`,{className:`update-running-row update-running-row-success`,children:[(0,z.jsx)(`span`,{className:`update-check`,"aria-hidden":`true`,children:`✓`}),(0,z.jsx)(`code`,{className:`update-cmd update-cmd-inline`,children:n||`cctally`}),(0,z.jsxs)(`span`,{className:`update-elapsed`,children:[`finished in `,Oo(t)]})]}),(0,z.jsxs)(`div`,{className:`update-row-label`,children:[`Restarting dashboard on the new code`,r?` (${r})`:``,`…`]}),(0,z.jsxs)(`div`,{className:`update-running-row`,children:[(0,z.jsx)(`span`,{className:`update-spinner`,"aria-hidden":`true`,children:`⟳`}),(0,z.jsx)(`span`,{className:`update-success-reconnect`,children:`reconnecting (this page will refresh in a moment)`})]})]})}var Ao=12;function jo(e,t){for(let t=e.length-1;t>=0;t--){let n=e[t];if(n.type===`exit`&&typeof n.rc==`number`)return`exited rc=${n.rc}`;if(n.type===`error_event`)return n.message??`worker error`}return t??`unknown failure`}function Mo(){let e=(0,g.useSyncExternalStore)(L,()=>I().update),[t,n]=(0,g.useState)(`idle`),r=e.state?.update_command??``,i=e.stream.filter(e=>e.type===`stderr`&&e.data).map(e=>e.data).slice(-Ao),a=jo(e.stream,e.errorMessage);function o(){R({type:`RESET_UPDATE_RUN`}),rt()}async function s(){if(r)try{await navigator.clipboard.writeText(r),n(`ok`),window.setTimeout(()=>n(`idle`),1500)}catch{n(`err`),window.setTimeout(()=>n(`idle`),1500)}}return(0,z.jsxs)(`div`,{className:`update-modal-body`,children:[(0,z.jsxs)(`div`,{className:`update-running-row update-running-row-failed`,children:[(0,z.jsx)(`span`,{className:`update-x`,"aria-hidden":`true`,children:`✗`}),(0,z.jsx)(`code`,{className:`update-cmd update-cmd-inline`,children:r||`cctally update`}),(0,z.jsx)(`span`,{className:`update-elapsed`,children:a})]}),i.length>0?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`div`,{className:`update-row-label`,children:[`stderr (last `,i.length,` line`,i.length===1?``:`s`,`)`]}),(0,z.jsx)(`pre`,{className:`update-stream update-stream-fail`,children:i.map((e,t)=>(0,z.jsxs)(`span`,{className:`update-stream-line err`,children:[e,`
18
- `]},t))})]}):(0,z.jsx)(`p`,{className:`update-manual-note`,children:e.errorMessage??`See ~/.local/share/cctally/update.log for the full failure log.`}),(0,z.jsxs)(`p`,{className:`update-stream-cap`,children:[`Full log: `,(0,z.jsx)(`code`,{children:`~/.local/share/cctally/update.log`})]}),(0,z.jsxs)(`div`,{className:`update-actions`,children:[(0,z.jsx)(`button`,{type:`button`,className:`update-btn update-btn-primary`,onClick:o,children:`Retry`}),(0,z.jsx)(`button`,{type:`button`,className:`update-btn`,onClick:s,disabled:!r,children:t===`ok`?`Copied!`:t===`err`?`Copy failed`:`Copy command`}),(0,z.jsx)(`button`,{type:`button`,className:`update-btn`,onClick:()=>ot.close(),children:`Close`})]})]})}var No={idle:`Update available`,running:`Updating cctally`,success:`Update complete`,failed:`Update failed`},Po={idle:`accent-amber`,running:`accent-amber`,success:`accent-green`,failed:`accent-red`};function Fo(){let e=(0,g.useSyncExternalStore)(L,()=>I().update),t=()=>R({type:`CLOSE_UPDATE_MODAL`});if(V((0,g.useMemo)(()=>[{key:`Escape`,scope:`modal`,action:t,when:()=>I().update.modalOpen}],[])),!e.modalOpen||!e.state)return null;let n=e.status,r=Po[n]??`accent-amber`,i=No[n]??`Update`;n===`running`&&e.state.latest_version?i=`Updating cctally → ${e.state.latest_version}`:n===`success`&&e.state.latest_version&&(i=`Update complete → ${e.state.latest_version}`);let a;switch(n){case`running`:a=(0,z.jsx)(Eo,{});break;case`success`:a=(0,z.jsx)(ko,{});break;case`failed`:a=(0,z.jsx)(Mo,{});break;default:a=(0,z.jsx)(So,{});break}return(0,z.jsxs)(`div`,{id:`update-modal-root`,className:`update-modal-root`,children:[(0,z.jsx)(`div`,{className:`modal-backdrop`,onClick:t}),(0,z.jsxs)(`div`,{className:`modal-card update-modal-card ${r}`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`update-modal-title`,children:[(0,z.jsx)(`div`,{className:`modal-handle`,"aria-hidden":`true`}),(0,z.jsxs)(`header`,{className:`modal-header`,children:[(0,z.jsx)(`h2`,{id:`update-modal-title`,children:i}),(0,z.jsx)(`button`,{className:`modal-close`,"aria-label":`Close`,onClick:t,children:`×`})]}),(0,z.jsx)(`div`,{className:`modal-body`,children:a})]})]})}function Io({title:e,accentClass:t,children:n,headerExtras:r}){let i=()=>R({type:`CLOSE_MODAL`});return V((0,g.useMemo)(()=>[{key:`Escape`,scope:`modal`,action:i}],[])),(0,z.jsxs)(`div`,{id:`modal-root`,children:[(0,z.jsx)(`div`,{className:`modal-backdrop`,onClick:i}),(0,z.jsxs)(`div`,{className:`modal-card ${t}`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`modal-title`,children:[(0,z.jsx)(`div`,{className:`modal-handle`,"aria-hidden":`true`}),(0,z.jsxs)(`header`,{className:`modal-header`,children:[(0,z.jsx)(`h2`,{id:`modal-title`,children:e}),r,(0,z.jsx)(`button`,{className:`modal-close`,"aria-label":`Close`,onClick:i,children:`×`})]}),(0,z.jsx)(`div`,{id:`modal-body`,className:`modal-body`,children:n})]})]})}function Lo(e){return e==null||!isFinite(e)?0:Math.max(0,Math.min(100,e))}function Ro(e,t,n){let r=D.dateShort(t,n);return e&&r?`${e} → ${r}`:e||(r?`→ ${r}`:`—`)}function zo(e){if(e==null||!isFinite(e))return[`—`,``];let t=(+e).toFixed(1),n=t.indexOf(`.`);return n===-1?[t,`.0%`]:[t.slice(0,n),t.slice(n)+`%`]}function Bo(e){let t=[],n=[...e].sort((e,t)=>(e.percent??0)-(t.percent??0));for(let e of n)e.percent!=null&&(t.length&&e.percent-(t[t.length-1].percent??0)<3||t.push(e));return t}function Vo(e){if(!Array.isArray(e)||e.length<2)return null;let t=e.map(e=>e.marginal_usd).filter(e=>e!=null&&isFinite(e)),n=t.length?t.reduce((e,t)=>e+t,0)/t.length:null,r=e[e.length-1].percent,i=[];return n!=null&&i.push(`avg marginal $`+n.toFixed(2)),r!=null&&i.push(`latest at `+r+`%`),i.length?i.join(` · `):null}function Ho(e,t){let n=[];for(let t of e)n.push({kind:`milestone`,ts:t.captured_at_utc,data:t});for(let e of t)n.push({kind:`credit`,ts:e.effective_reset_at_utc,data:e});return n.sort((e,t)=>e.ts.localeCompare(t.ts)),n}function Uo(){let e=Ke(),t=Ht(),n={tz:t.resolvedTz,offsetLabel:t.offsetLabel},r=e?.current_week??null,i=e?.header??null,a=Array.isArray(r?.milestones)?r.milestones:[],o=Array.isArray(r?.five_hour_milestones)?r.five_hour_milestones:[],s=Ho(o,Array.isArray(r?.five_hour_block?.credits)?r.five_hour_block.credits:[]),c=Lo(r?.used_pct),[l,u]=zo(r?.used_pct),d=r?Ro(i?.week_label,r.reset_at_utc,n):`—`,f=Bo(a),p=Vo(a);return(0,z.jsx)(Io,{title:`Current Week — per-percent milestones`,accentClass:`accent-green`,headerExtras:(0,z.jsx)(Gt,{panel:`current-week`,panelLabel:`Current week`,triggerId:`current-week-modal`,onClick:()=>R(N(`current-week`,`current-week-modal`))}),children:(0,z.jsxs)(`section`,{className:`modal-current-week`,children:[(0,z.jsx)(`div`,{className:`m-chipstrip`,id:`mcw-badges`,children:(0,z.jsx)(`span`,{className:`m-pill accent-green`,id:`mcw-week-pill`,children:d})}),(0,z.jsxs)(`div`,{className:`mcw-herobar`,children:[(0,z.jsxs)(`div`,{className:`mcw-bignum`,id:`mcw-bignum`,children:[(0,z.jsx)(`span`,{className:`int`,children:l}),(0,z.jsx)(`span`,{className:`unit`,children:u})]}),(0,z.jsxs)(`div`,{className:`mcw-pbar-wrap`,children:[(0,z.jsxs)(`div`,{className:`mcw-pbar`,children:[(0,z.jsx)(`div`,{className:`fill`,id:`mcw-fill`,style:{width:c+`%`}}),(0,z.jsx)(`div`,{className:`ticks`,id:`mcw-ticks`,children:f.map(e=>(0,z.jsx)(`div`,{className:`tick`,"data-p":String(e.percent),style:{left:Lo(e.percent)+`%`}},e.percent))}),(0,z.jsx)(`div`,{className:`marker`,id:`mcw-marker`,style:{left:c+`%`}})]}),(0,z.jsxs)(`div`,{className:`mcw-pscale`,children:[(0,z.jsx)(`span`,{children:`0%`}),(0,z.jsx)(`span`,{children:`25%`}),(0,z.jsx)(`span`,{children:`50%`}),(0,z.jsx)(`span`,{children:`75%`}),(0,z.jsx)(`span`,{children:`100%`})]})]}),(0,z.jsxs)(`div`,{className:`mcw-mini`,id:`mcw-mini`,children:[(0,z.jsxs)(`div`,{className:`s`,children:[(0,z.jsx)(`span`,{className:`k`,children:`spent`}),(0,z.jsx)(`span`,{className:`v v-magenta`,id:`mcw-spent`,children:D.usd2(r?.spent_usd)})]}),(0,z.jsxs)(`div`,{className:`s`,children:[(0,z.jsx)(`span`,{className:`k`,children:`$ / 1%`}),(0,z.jsx)(`span`,{className:`v v-cyan`,id:`mcw-dpp`,children:D.usd3(r?.dollar_per_pct)})]}),(0,z.jsxs)(`div`,{className:`s`,children:[(0,z.jsx)(`span`,{className:`k`,children:`reset`}),(0,z.jsx)(`span`,{className:`v`,id:`mcw-reset`,children:D.datetimeShortZ(r?.reset_at_utc,n)})]})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-ms`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#hash`})}),`Milestones`]}),(0,z.jsxs)(`div`,{className:`mcw-mshead`,children:[(0,z.jsxs)(`span`,{className:`m-pill accent-purple`,id:`mcw-ms-count`,children:[a.length,` crossed`]}),(0,z.jsx)(`span`,{className:`mcw-ms-sub`,id:`mcw-ms-sub`,hidden:!p,children:p??``})]}),a.length===0?(0,z.jsx)(`p`,{className:`empty-state`,id:`mcw-empty`,children:`No milestones yet — earliest crosses at 1\xA0%.`}):(0,z.jsxs)(`table`,{className:`m-histable`,id:`mcw-table`,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{children:`%`}),(0,z.jsxs)(`th`,{children:[`Crossed (`,t.offsetLabel,`)`]}),(0,z.jsx)(`th`,{className:`num`,children:`Cumulative $`}),(0,z.jsx)(`th`,{className:`num`,children:`Marginal $`}),(0,z.jsx)(`th`,{className:`num`,children:`5h %`})]})}),(0,z.jsx)(`tbody`,{id:`mcw-rows`,children:a.map(e=>(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`td`,{children:(0,z.jsx)(`span`,{className:`m-pill accent-purple pct-cell`,children:e.percent??`—`})}),(0,z.jsx)(`td`,{className:`d`,children:D.startedShort(e.crossed_at_utc,n,{noSuffix:!0})}),(0,z.jsx)(`td`,{className:`num`,children:e.cumulative_usd==null?`—`:`$`+e.cumulative_usd.toFixed(2)}),(0,z.jsx)(`td`,{className:`num`,children:(0,z.jsx)(`span`,{className:`m-marginal`,children:e.marginal_usd==null?`—`:`$`+e.marginal_usd.toFixed(2)})}),(0,z.jsx)(`td`,{className:`num`,children:(0,z.jsx)(`span`,{className:`m-fh`,children:e.five_hour_pct_at_cross==null?`—`:Math.round(e.five_hour_pct_at_cross)+`%`})})]},e.percent))})]}),s.length>0&&(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-ms sec-5h`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#activity`})}),`5h milestones`]}),(0,z.jsx)(`div`,{className:`mcw-mshead`,children:(0,z.jsxs)(`span`,{className:`m-pill accent-purple`,id:`mcw-5h-count`,children:[o.length,` crossed`]})}),(0,z.jsxs)(`table`,{className:`m-histable mcw-5h-table`,id:`mcw-5h-table`,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{children:`%`}),(0,z.jsxs)(`th`,{children:[`When (`,t.offsetLabel,`)`]}),(0,z.jsx)(`th`,{className:`num`,children:`Block $`}),(0,z.jsx)(`th`,{className:`num`,children:`Marginal $`}),(0,z.jsx)(`th`,{className:`num`,children:`7d %`})]})}),(0,z.jsx)(`tbody`,{children:s.map((e,t)=>{if(e.kind===`credit`)return(0,z.jsx)(`tr`,{className:`mcw-5h-credit-row`,children:(0,z.jsxs)(`td`,{colSpan:5,className:`mcw-5h-credit-cell`,children:[`⚡ CREDIT\xA0`,` `,e.data.delta_pp>0?`+`:``,e.data.delta_pp.toFixed(0),`pp\xA0@`,` `,D.startedShort(e.ts,n,{noSuffix:!0})]})},`credit-${t}-${e.ts}`);let r=e.data;return(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`td`,{children:(0,z.jsx)(`span`,{className:`m-pill accent-purple pct-cell`,children:r.percent_threshold})}),(0,z.jsx)(`td`,{className:`d`,children:D.startedShort(r.captured_at_utc,n,{noSuffix:!0})}),(0,z.jsx)(`td`,{className:`num`,children:`$`+r.block_cost_usd.toFixed(2)}),(0,z.jsx)(`td`,{className:`num`,children:(0,z.jsx)(`span`,{className:`m-marginal`,children:r.marginal_cost_usd==null?`—`:`$`+r.marginal_cost_usd.toFixed(2)})}),(0,z.jsx)(`td`,{className:`num`,children:(0,z.jsx)(`span`,{className:`m-fh`,children:r.seven_day_pct_at_crossing==null?`—`:Math.round(r.seven_day_pct_at_crossing)+`%`})})]},`fhms-${r.percent_threshold}-${r.reset_event_id}`)})})]})]})]})})}function Wo(e){if(!e)return`—`;let t=e.elapsed_hours,n=e.remaining_hours;if(t==null||n==null)return`—`;let r=t+n;if(r<=0)return`—`;let i=t/r*100;return Math.min(100,i).toFixed(1)+`%`}function Go(e){return e==null||!isFinite(e)?null:e<0?0:e>110?110:e}function Ko(e){return e==null||!isFinite(e)?`—`:e<0?`~`+(+e).toFixed(1)+`%`:(+e).toFixed(1)+`%`}function qo(e,t){for(let t of e)t.trueXPct=t.pos/110*100;if(e.length<2||t<=0){for(let t of e)t.resolvedXPct=t.trueXPct;return}let n=e.slice().sort((e,t)=>e.trueXPct-t.trueXPct),r=n[0],i=n[1],a=r.pillWidthPx/2/t*100,o=i.pillWidthPx/2/t*100,s=8/t*100,c=a+o+s,l=2*c;if(i.trueXPct-r.trueXPct<c){let e=(r.trueXPct+i.trueXPct)/2;r.resolvedXPct=e-l/2,i.resolvedXPct=e+l/2;let t=a,n=100-o;r.resolvedXPct<t&&(r.resolvedXPct=t,i.resolvedXPct-r.resolvedXPct<l&&(i.resolvedXPct=Math.min(n,r.resolvedXPct+l))),i.resolvedXPct>n&&(i.resolvedXPct=n,i.resolvedXPct-r.resolvedXPct<l&&(r.resolvedXPct=Math.max(t,i.resolvedXPct-l)))}else r.resolvedXPct=r.trueXPct,i.resolvedXPct=i.trueXPct}function Jo(e,t,n){(0,g.useEffect)(()=>{let r=e.current,i=t.current;if(!r||!i||!n)return;let a=r.querySelector(`.mfc-pills`),o=r.querySelector(`.mfc-leaders`),s=i.querySelector(`.mfc-rangeband`);if(!a||!o)return;let c=n.week_avg_projection_pct,l=n.recent_24h_projection_pct,u=Go(c),d=Go(l),f=[];u!=null&&c!=null&&f.push({kind:`wa`,pos:u,raw:c}),d!=null&&l!=null&&f.push({kind:`r24`,pos:d,raw:l});let p=new Set(f.map(e=>e.kind));i.querySelectorAll(`.mfc-chev`).forEach(e=>{let t=e.dataset.kind;(!t||!p.has(t))&&e.remove()}),a.querySelectorAll(`.mfc-pill`).forEach(e=>{let t=e.dataset.kind;(!t||!p.has(t))&&e.remove()});let m=f.map(e=>({...e,trueXPct:0,resolvedXPct:0,pillWidthPx:0}));for(let e of m){let t=e.pos/110*100,n=i.querySelector(`.mfc-chev[data-kind="${e.kind}"]`);n||(n=document.createElement(`div`),n.className=`mfc-chev `+e.kind,n.dataset.kind=e.kind,i.appendChild(n)),n.style.left=t+`%`;let r=a.querySelector(`.mfc-pill[data-kind="${e.kind}"]`),o=Ko(e.raw);r?r.textContent!==o&&(r.textContent=o):(r=document.createElement(`div`),r.className=`mfc-pill `+e.kind,r.dataset.kind=e.kind,r.textContent=o,a.appendChild(r)),e.pillEl=r}if(s){let e=!1;if(m.length===2){let t=m[0].pos/110*100,n=m[1].pos/110*100,r=Math.min(t,n),i=Math.max(t,n)-r;i>=.5&&(s.style.left=r+`%`,s.style.width=i+`%`,e=!0)}s.hidden=!e}let h=()=>{for(let e of m)if(!e.pillEl||!e.pillEl.isConnected)return;let e=r.clientWidth;if(e<=0){requestAnimationFrame(h);return}for(let e of m)e.pillWidthPx=e.pillEl.getBoundingClientRect().width;qo(m,e);for(let e of m)e.pillEl.style.left=e.resolvedXPct+`%`;for(;o.firstChild;)o.removeChild(o.firstChild);for(let e of m){let t=document.createElementNS(`http://www.w3.org/2000/svg`,`path`);t.setAttribute(`class`,e.kind),t.setAttribute(`vector-effect`,`non-scaling-stroke`),t.setAttribute(`d`,`M ${e.resolvedXPct} 0 C ${e.resolvedXPct} 10, ${e.trueXPct} 8, ${e.trueXPct} 18`),o.appendChild(t)}};h()},[e,t,n])}function Yo(){let e=Ke()?.forecast??null,t=e?.explain??null,n=(0,g.useRef)(null),r=(0,g.useRef)(null);Jo(n,r,e);let i=(0,z.jsx)(Gt,{panel:`forecast`,panelLabel:`Forecast`,triggerId:`forecast-modal`,onClick:()=>R(N(`forecast`,`forecast-modal`))});if(!e)return(0,z.jsx)(Io,{title:`Forecast — explain`,accentClass:`accent-purple`,headerExtras:i,children:(0,z.jsx)(`section`,{className:`modal-forecast`,children:(0,z.jsx)(`p`,{className:`empty-state`,id:`mfc-empty`,children:`No forecast data yet.`})})});let a=St(e.verdict),o=a?`m-pill ${a.accent}`:`m-pill`,s=a?`${a.glyph} ${a.label}`:`—`,c=`m-pill`,l=`—`,u=!0;e.confidence===`high`?(c=`m-pill accent-blue`,l=`high confidence`,u=!1):e.confidence===`low`&&(c=`m-pill accent-red`,l=`low confidence`,u=!1);let d=t?.rates,f=t?.week;return(0,z.jsx)(Io,{title:`Forecast — explain`,accentClass:`accent-purple`,headerExtras:i,children:(0,z.jsxs)(`section`,{className:`modal-forecast`,children:[(0,z.jsxs)(`div`,{className:`m-chipstrip`,id:`mfc-chips`,children:[(0,z.jsx)(`span`,{className:o,id:`mfc-verdict`,children:s}),(0,z.jsx)(`span`,{className:c,id:`mfc-confidence`,hidden:u,children:l})]}),(0,z.jsxs)(`div`,{className:`m-hero cols-2`,children:[(0,z.jsxs)(`div`,{className:`m-kv kv-wa`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#gauge`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`mfc-wa-pct`,children:D.pct1(e.week_avg_projection_pct)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Week-avg projection`}),(0,z.jsx)(`div`,{className:`sub`,id:`mfc-wa-sub`,children:D.ratePctPerHour(d?.week_average_pct_per_hour)})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-r24`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#zap`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`mfc-r24-pct`,children:D.pct1(e.recent_24h_projection_pct)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Recent-24h projection`}),(0,z.jsx)(`div`,{className:`sub`,id:`mfc-r24-sub`,children:D.ratePctPerHour(d?.recent_24h_pct_per_hour)})]})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-range`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#bar-chart`})}),`Range vs. caps`]}),(0,z.jsxs)(`div`,{className:`mfc-rangewrap`,id:`mfc-rangewrap`,ref:n,children:[(0,z.jsx)(`div`,{className:`mfc-pills`,id:`mfc-pills`}),(0,z.jsx)(`svg`,{className:`mfc-leaders`,id:`mfc-leaders`,viewBox:`0 0 100 18`,preserveAspectRatio:`none`,"aria-hidden":`true`}),(0,z.jsxs)(`div`,{className:`mfc-rangetrack`,id:`mfc-rangetrack`,ref:r,children:[(0,z.jsx)(`div`,{className:`mfc-zone safe`}),(0,z.jsx)(`div`,{className:`mfc-zone warn`}),(0,z.jsx)(`div`,{className:`mfc-zone over`}),(0,z.jsx)(`div`,{className:`mfc-rangeband`,id:`mfc-rangeband`,hidden:!0}),(0,z.jsx)(`div`,{className:`mfc-bound b90`,children:(0,z.jsx)(`div`,{className:`lbl`,children:`90%`})}),(0,z.jsx)(`div`,{className:`mfc-bound b100`,children:(0,z.jsx)(`div`,{className:`lbl`,children:`100%`})})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-rates`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#activity`})}),`Rates`]}),(0,z.jsxs)(`div`,{className:`mfc-kvgrid`,children:[(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`$ / 1%`}),(0,z.jsx)(`span`,{className:`v v-cyan`,id:`mfc-dpp`,children:D.usd3(d?.dollars_per_percent)})]}),(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`week done`}),(0,z.jsx)(`span`,{className:`v v-green`,id:`mfc-wkdone`,children:Wo(f)})]}),(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`elapsed`}),(0,z.jsx)(`span`,{className:`v v-green`,id:`mfc-elapsed`,children:D.hours1(f?.elapsed_hours)})]}),(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`remaining`}),(0,z.jsx)(`span`,{className:`v`,id:`mfc-remain`,children:D.hours1(f?.remaining_hours)})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-bud`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#dollar`})}),`Daily budgets to stay under`]}),(0,z.jsxs)(`div`,{className:`mfc-kvgrid mfc-kvgrid-single`,children:[(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`@ 100% cap`}),(0,z.jsx)(`span`,{className:`v v-magenta`,id:`mfc-bud100`,children:D.usd2PerDay(e.budget_100_per_day_usd)})]}),(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`@ 90% cap`}),(0,z.jsx)(`span`,{className:`v v-amber`,id:`mfc-bud90`,children:D.usd2PerDay(e.budget_90_per_day_usd)})]})]})]})})}function Xo(e){let t=Math.max(1,Math.round(e/4));return`${e} week${e===1?``:`s`} · ${t} month${t===1?``:`s`}`}function Zo(e){let t=e.findIndex(e=>e&&e.is_current);return t>=0?t:e.length-1}function Qo(e,t){let n=e.filter((e,n)=>n!==t).map(e=>e.dollar_per_pct).filter(e=>e!=null&&isFinite(e));if(n.length<4)return null;let r=n.slice(-4).sort((e,t)=>e-t);return(r[1]+r[2])/2}function $o(e){if(!e.length)return null;let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2?t[n]:(t[n-1]+t[n])/2}function es(e,t){let n=[];if(!e.length)return n;let r={left:44,right:14,top:12,bottom:22},i=600-r.left-r.right,a=140-r.top-r.bottom,o=e.length,s=e=>r.left+(o===1?i:e/(o-1)*i),c=e.map(e=>e.dollar_per_pct).filter(e=>e!=null&&isFinite(e)),l=c.length?Math.min(...c)*.96:0,u=c.length?Math.max(...c)*1.04:1;u-l<1e-6&&(l-=.01,u+=.01);let d=e=>r.top+a*(1-(e-l)/(u-l)),f=e.map(e=>e.used_pct).filter(e=>e!=null&&isFinite(e)),p=f.length?Math.min(...f)*.96:0,m=f.length?Math.max(...f)*1.04:100;m-p<1e-6&&(--p,m+=1);let h=e=>r.top+a*(1-(e-p)/(m-p));if(n.push({el:`line`,attrs:{class:`mtr-axis`,x1:r.left,y1:r.top+a,x2:600-r.right,y2:r.top+a},key:`axis`}),c.length){let e=$o(c);e!=null&&(n.push({el:`line`,attrs:{class:`mtr-hl`,x1:r.left,y1:d(e),x2:600-r.right,y2:d(e)},key:`med-line`}),n.push({el:`text`,attrs:{class:`mtr-medlabel`,x:r.left+2,y:d(e)-3},text:`median $`+e.toFixed(2),key:`med-label`}))}{let t=[];e.forEach((e,n)=>{e.used_pct!=null&&isFinite(e.used_pct)&&t.push(`${s(n)},${h(e.used_pct)}`)}),t.length>=2&&n.push({el:`polyline`,attrs:{class:`mtr-trendline-dim`,points:t.join(` `)},key:`poly-used`})}{let t=[];e.forEach((e,n)=>{e.dollar_per_pct!=null&&isFinite(e.dollar_per_pct)&&t.push(`${s(n)},${d(e.dollar_per_pct)}`)}),t.length>=2&&n.push({el:`polyline`,attrs:{class:`mtr-trendline`,points:t.join(` `)},key:`poly-dpp`})}e.forEach((e,r)=>{if(e.dollar_per_pct==null||!isFinite(e.dollar_per_pct))return;let i=r===t;n.push({el:`circle`,attrs:{class:`mtr-trenddot`+(i?` cur`:``),cx:s(r),cy:d(e.dollar_per_pct),r:i?5:3},key:`dot-${r}`})}),c.length&&(n.push({el:`text`,attrs:{class:`mtr-ylabel`,x:3,y:r.top+8},text:`$`+(u/1.04).toFixed(2),key:`ymax`}),n.push({el:`text`,attrs:{class:`mtr-ylabel`,x:3,y:r.top+a},text:`$`+(l/.96).toFixed(2),key:`ymin`}));let g=e[t];return g&&g.dollar_per_pct!=null&&isFinite(g.dollar_per_pct)&&n.push({el:`text`,attrs:{class:`mtr-curlabel`,x:Math.max(r.left+4,s(t)-22),y:Math.min(138,d(g.dollar_per_pct)+16)},text:`$`+g.dollar_per_pct.toFixed(2),key:`curlabel`}),n}function ts(e,t){return t===0?`Now`+(e.label?` · `+e.label:``):`W−`+t+(e.label?` · `+e.label:``)}function ns(e){return e==null||!isFinite(e)?{cls:`flat`,text:`—`}:e>5e-4?{cls:`up`,text:`+`+e.toFixed(2)}:e<-5e-4?{cls:`down`,text:e.toFixed(2)}:{cls:`flat`,text:`0.00`}}function rs(e){return e==null||!isFinite(e)?{cls:`delta-flat`,iconHref:`/static/icons.svg#minus`,text:`—`}:e<-5e-4?{cls:`delta-down`,iconHref:`/static/icons.svg#trending-down`,text:`−$`+Math.abs(e).toFixed(3)}:e>5e-4?{cls:`delta-up`,iconHref:`/static/icons.svg#trending-up`,text:`+$`+e.toFixed(3)}:{cls:`delta-flat`,iconHref:`/static/icons.svg#minus`,text:`$0.000`}}function is(){let e=Ke(),t=oe(e),n=(0,z.jsx)(Gt,{panel:`trend`,panelLabel:`Trend`,triggerId:`trend-modal`,onClick:()=>R(N(`trend`,`trend-modal`))});if(!t.length)return(0,z.jsx)(Io,{title:`Trend — 12-week history`,accentClass:`accent-amber`,headerExtras:n,children:(0,z.jsx)(`section`,{className:`modal-trend`,children:(0,z.jsx)(`p`,{className:`empty-state`,id:`mtr-empty`,children:`No history data yet.`})})});let r=Zo(t),i=t[r],a=e?.trend?.history_median_dpp,o=a!=null&&isFinite(a)?a:Qo(t,r),s=rs(i&&i.dollar_per_pct!=null&&o!=null?i.dollar_per_pct-o:null),c=es(t,r),l=t.some(e=>e.used_pct!=null&&isFinite(e.used_pct)),u=t.length;return(0,z.jsx)(Io,{title:`Trend — 12-week history`,accentClass:`accent-amber`,headerExtras:n,children:(0,z.jsxs)(`section`,{className:`modal-trend`,children:[(0,z.jsx)(`div`,{className:`m-chipstrip`,children:(0,z.jsx)(`span`,{className:`m-pill accent-amber`,id:`mtr-weeks-pill`,children:Xo(u)})}),(0,z.jsxs)(`div`,{className:`m-hero cols-3`,children:[(0,z.jsxs)(`div`,{className:`m-kv kv-cur`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#dollar`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`mtr-cur`,children:i&&i.dollar_per_pct!=null?`$`+i.dollar_per_pct.toFixed(3):`—`}),(0,z.jsx)(`div`,{className:`lbl`,children:`Current $ / 1%`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-med`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#minus`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`mtr-med`,children:o==null?`—`:`$`+o.toFixed(3)}),(0,z.jsx)(`div`,{className:`lbl`,children:`4-week median`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-delta ${s.cls}`,id:`mtr-delta-kv`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:s.iconHref})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`mtr-delta`,children:s.text}),(0,z.jsx)(`div`,{className:`lbl`,children:`vs median`})]})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-spark`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#trending-down`})}),`12-week history · $/1%`,(0,z.jsxs)(`span`,{className:`mtr-legend`+(l?``:` legend-no-used`),"aria-hidden":`true`,children:[(0,z.jsx)(`span`,{className:`sw sw-dpp`}),(0,z.jsx)(`span`,{className:`sw-lbl`,children:`$/1%`}),(0,z.jsx)(`span`,{className:`sw sw-used`}),(0,z.jsx)(`span`,{className:`sw-lbl`,children:`used %`})]})]}),(0,z.jsxs)(`div`,{className:`mtr-sparkhero`,children:[(0,z.jsx)(`svg`,{id:`mtr-svg`,viewBox:`0 0 600 140`,preserveAspectRatio:`none`,"aria-hidden":`true`,children:c.map(e=>{let{el:t,attrs:n,text:r,key:i}=e,a={};for(let e in n)a[e===`class`?`className`:e]=n[e];return t===`line`?(0,z.jsx)(`line`,{...a},i):t===`polyline`?(0,z.jsx)(`polyline`,{...a},i):t===`circle`?(0,z.jsx)(`circle`,{...a},i):(0,z.jsx)(`text`,{...a,children:r},i)})}),(0,z.jsx)(`div`,{className:`mtr-sparkaxis`,id:`mtr-sparkaxis`,children:u>0?(0,z.jsxs)(g.Fragment,{children:[(0,z.jsxs)(`span`,{children:[`W−`,u-1]}),(0,z.jsxs)(`span`,{children:[`W−`,Math.floor((u-1)/2)]}),(0,z.jsx)(`span`,{children:`Now`})]}):null})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-tbl`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#hash`})}),`Weekly detail`]}),(0,z.jsxs)(`div`,{className:`mtr-tbl-head`,children:[(0,z.jsxs)(`span`,{className:`m-pill accent-purple`,id:`mtr-tbl-count`,children:[u,` weeks`]}),(0,z.jsx)(`span`,{className:`mtr-tbl-sub`,children:`current row highlighted · negative Δ = $/1% down vs prior week`})]}),(0,z.jsxs)(`table`,{className:`m-histable`,id:`mtr-table`,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{children:`Week`}),(0,z.jsx)(`th`,{className:`num`,children:`Used %`}),(0,z.jsx)(`th`,{className:`num`,children:`$ / 1%`}),(0,z.jsx)(`th`,{className:`num`,children:`Δ $/1%`})]})}),(0,z.jsx)(`tbody`,{id:`mtr-rows`,children:t.map((e,t)=>{let n=ts(e,u-1-t),r=e.used_pct==null?`—`:Math.round(e.used_pct)+`%`,i=e.dollar_per_pct==null?`—`:`$`+e.dollar_per_pct.toFixed(2),a=ns(e.delta);return(0,z.jsxs)(`tr`,{className:e.is_current?`cur`:void 0,children:[(0,z.jsx)(`td`,{children:(0,z.jsx)(`span`,{className:`wlab`,children:n})}),(0,z.jsx)(`td`,{className:`num usedpct`,children:r}),(0,z.jsx)(`td`,{className:`num dpp`,children:i}),(0,z.jsx)(`td`,{className:`num delta ${a.cls}`,children:a.text})]},e.label+`|`+t)})})]})]})})}var as=/(^|\/)(subagents\/|agent-)/;function os(){return(0,g.useSyncExternalStore)(L,()=>I().snapshot?.generated_at??``)}function ss(){let e=(0,g.useSyncExternalStore)(L,()=>I().openSessionId),t=os(),[n,r]=(0,g.useState)(null),[i,a]=(0,g.useState)(!0),[o,s]=(0,g.useState)(null),c=(0,g.useRef)(null),l=(0,g.useRef)(!1),u=(0,g.useRef)(null);return(0,g.useEffect)(()=>{u.current=e??I().snapshot?.sessions?.rows?.[0]?.session_id??null,l.current=!1},[e]),(0,g.useEffect)(()=>{let e=u.current;if(!e){a(!1),s(`No session available.`),r(null),c.current=null;return}let t=c.current!==e||n==null;c.current=e,t&&(a(!0),s(null),r(null));let i=new AbortController;return fetch(`/api/session/${encodeURIComponent(e)}`,{signal:i.signal}).then(async e=>{if(e.status===404){(t||l.current)&&(a(!1),s(`Session not found (the cache may have rolled forward).`),r(null)),l.current=!0;return}if(!e.ok)throw Error(`HTTP `+e.status);let n=await e.json();l.current=!1,r(n),s(null),a(!1)}).catch(e=>{e.name!==`AbortError`&&(l.current=!1,t&&(s(`Failed to load: `+e.message),a(!1)))}),()=>i.abort()},[e,t]),(0,z.jsx)(Io,{title:`Session detail`,accentClass:`accent-orange`,headerExtras:(0,z.jsx)(Gt,{panel:`sessions`,panelLabel:`Session`,triggerId:`session-modal`,onClick:()=>R(N(`sessions`,`session-modal`))}),children:(0,z.jsxs)(`section`,{className:`modal-sessions`,children:[i?(0,z.jsx)(`div`,{className:`modal-loading`,id:`msess-loading`,children:`Loading session detail…`}):null,o?(0,z.jsx)(`div`,{className:`modal-error`,id:`msess-error`,children:o}):null,!i&&!o&&n?(0,z.jsx)(cs,{detail:n}):null]})})}function cs({detail:e}){let t=Array.isArray(e.source_paths)?e.source_paths:[],n=[],r=[];t.forEach(e=>{as.test(e)?r.push(e):n.push(e)});let i=e.cost_total_usd??0,a=[[`Input`,e.input_tokens,null],[`Output`,e.output_tokens,null],[`Cache creation`,e.cache_creation_tokens,null],[`Cache read`,e.cache_read_tokens,null],[`Cache hit %`,e.cache_hit_pct,`cache-hit`]].filter(e=>e[1]!=null),o=!e.models||e.models.length===0,s=!e.cost_per_model||e.cost_per_model.length===0;return(0,z.jsxs)(`div`,{className:`modal-content`,id:`msess-content`,children:[(0,z.jsx)(`div`,{className:`m-chipstrip`,children:(0,z.jsx)(`span`,{className:`msess-badge`,id:`msess-id`,"aria-label":`Session ID`,children:e.session_id??`—`})}),(0,z.jsxs)(`div`,{className:`m-hero cols-3`,children:[(0,z.jsxs)(`div`,{className:`m-kv kv-cost`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#dollar`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`msess-cost`,children:e.cost_total_usd==null?`—`:`$`+e.cost_total_usd.toFixed(2)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Total cost`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-dur`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#clock`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`msess-dur`,children:e.duration_min==null?`—`:e.duration_min+` min`}),(0,z.jsx)(`div`,{className:`lbl`,children:`Duration`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-proj`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#folder`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`msess-project`,title:e.project_path??``,"aria-label":`Project`,children:e.project_label??e.project_path??`—`}),(0,z.jsx)(`div`,{className:`lbl`,children:`Project`})]})]})]}),(0,z.jsxs)(`div`,{className:`msess-ts`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#calendar`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`span`,{className:`k`,children:`started`}),(0,z.jsx)(`span`,{className:`v`,id:`msess-started`,children:e.started_utc??`—`})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`span`,{className:`k`,children:`last activity`}),(0,z.jsx)(`span`,{className:`v`,id:`msess-last`,children:e.last_activity_utc??`—`})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-tok`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#hash`})}),`Tokens`]}),(0,z.jsx)(`div`,{className:`msess-tok-grid`,id:`msess-tokens`,children:a.map(([e,t,n])=>(0,z.jsxs)(`div`,{className:`msess-tok-tile`+(n?` `+n:``),children:[(0,z.jsx)(`div`,{className:`lbl`,children:e}),(0,z.jsx)(`div`,{className:`n`,children:n===`cache-hit`?t.toFixed(1)+`%`:t.toLocaleString(`en-US`)}),n===`cache-hit`?(0,z.jsx)(`div`,{className:`bar`,children:(0,z.jsx)(`div`,{className:`fill`,style:{width:Math.max(0,Math.min(t,100))+`%`}})}):null]},e))}),o?null:(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-mod`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#sparkles`})}),`Models`]}),(0,z.jsx)(`div`,{className:`m-chipstrip`,id:`msess-models`,children:(e.models||[]).map(e=>(0,z.jsx)(`span`,{className:`chip `+ln(e.name),children:e.name},e.name))})]}),s?null:(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-costm`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#pie-chart`})}),`Cost by model`]}),(0,z.jsxs)(`div`,{className:`msess-costm`,children:[(0,z.jsx)(`div`,{className:`bar`,id:`msess-cost-bar`,children:(e.cost_per_model||[]).map(e=>{let t=i>0&&e.cost_usd!=null?e.cost_usd/i*100:0;return(0,z.jsx)(`div`,{className:`seg `+ln(e.model),style:{width:t+`%`}},e.model)})}),(0,z.jsx)(`div`,{className:`legend`,id:`msess-cost-legend`,children:(e.cost_per_model||[]).map(e=>{let t=i>0&&e.cost_usd!=null?e.cost_usd/i*100:0;return(0,z.jsxs)(`div`,{className:`lg`,children:[(0,z.jsx)(`span`,{className:`sw `+ln(e.model)}),(0,z.jsx)(`span`,{className:`name`,children:e.model}),(0,z.jsx)(`span`,{className:`v`,children:e.cost_usd==null?`—`:`$`+e.cost_usd.toFixed(3)}),(0,z.jsxs)(`span`,{className:`pct`,children:[Math.round(t),`%`]})]},e.model)})})]})]}),t.length>0?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-src`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#file-text`})}),`Source files`]}),(0,z.jsxs)(`div`,{className:`msess-src`,id:`msess-src`,children:[(0,z.jsxs)(`div`,{className:`src-head`,children:[(0,z.jsxs)(`span`,{className:`count-pill`,children:[t.length,` file`,t.length===1?``:`s`]}),(0,z.jsxs)(`span`,{className:`sub`,children:[n.length,` primary`,r.length>0?(0,z.jsxs)(z.Fragment,{children:[` `,(0,z.jsx)(`span`,{className:`dot`,children:`·`}),` `,(0,z.jsxs)(`span`,{className:`subcount`,children:[r.length,` subagent`,r.length===1?``:`s`]})]}):null]})]}),n.length>0?n.map(e=>(0,z.jsx)(`div`,{className:`primary-path`,children:e},e)):r.length>0?(0,z.jsxs)(`div`,{className:`src-empty-primary`,children:[`No primary path resolved · `,r.length,` subagent path`,r.length===1?``:`s`,` below`]}):null,r.length>0?(0,z.jsxs)(`details`,{className:`subagents`,open:n.length===0,children:[(0,z.jsxs)(`summary`,{children:[`Show `,r.length,` subagent path`,r.length===1?``:`s`]}),(0,z.jsx)(`ul`,{className:`paths`,children:r.map(e=>(0,z.jsx)(`li`,{children:e},e))})]}):null]})]}):null]})}function ls({row:e,variant:t,accentClass:n}){let r=Ht(),i={tz:r.resolvedTz,offsetLabel:r.offsetLabel},a=(e,t)=>`${D.datetimeShort(e,i)} → ${D.datetimeShort(t,i)}`,o=e.delta_cost_pct==null?`flat`:e.delta_cost_pct>0?`up`:e.delta_cost_pct<0?`down`:`flat`,s=t===`weekly`?`week`:t===`monthly`?`month`:`day`,c=t===`daily`?`Today`:`Now`;return(0,z.jsxs)(`div`,{className:`detail-card ${n}`,children:[(0,z.jsxs)(`div`,{className:`head`,children:[(0,z.jsxs)(`div`,{className:`big`,children:[e.label,e.is_current&&(0,z.jsx)(`span`,{className:`pill-current`,children:c})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`span`,{className:`cost`,style:{color:`var(--text)`,fontWeight:700},children:D.usd2(e.cost_usd)}),` `,e.delta_cost_pct==null?(0,z.jsx)(`span`,{className:`delta flat`,children:`—`}):(0,z.jsxs)(`span`,{className:`delta ${o}`,children:[D.deltaPct(e.delta_cost_pct),` vs prior `,s]})]})]}),t===`weekly`&&e.week_start_at&&e.week_end_at&&(0,z.jsxs)(`div`,{className:`window`,children:[`Subscription window: `,a(e.week_start_at,e.week_end_at)]}),(0,z.jsx)(`div`,{className:`model-stack`,role:`presentation`,children:e.models.map(e=>(0,z.jsx)(`span`,{className:e.chip,style:{width:`${e.cost_pct}%`}},e.model))}),(0,z.jsx)(`div`,{className:`chips`,children:e.models.map(e=>(0,z.jsxs)(`span`,{className:`chip ${e.chip}`,children:[e.display,` `,Math.round(e.cost_pct),`% · `,D.usd2(e.cost_usd)]},e.model))}),(0,z.jsxs)(`div`,{className:`tokens-row`,children:[(0,z.jsxs)(`div`,{className:`t`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Input`}),(0,z.jsx)(`span`,{className:`v`,children:D.compact(e.input_tokens)})]}),(0,z.jsxs)(`div`,{className:`t`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Output`}),(0,z.jsx)(`span`,{className:`v`,children:D.compact(e.output_tokens)})]}),(0,z.jsxs)(`div`,{className:`t`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Cache+`}),(0,z.jsx)(`span`,{className:`v`,children:D.compact(e.cache_creation_tokens)})]}),(0,z.jsxs)(`div`,{className:`t`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Cache-read`}),(0,z.jsx)(`span`,{className:`v`,children:D.compact(e.cache_read_tokens)})]}),(0,z.jsxs)(`div`,{className:`t`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Total`}),(0,z.jsx)(`span`,{className:`v`,children:D.compact(e.total_tokens)})]}),e.cache_hit_pct!=null&&(0,z.jsxs)(`div`,{className:`t cache`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Cache hit`}),(0,z.jsxs)(`span`,{className:`v`,children:[e.cache_hit_pct.toFixed(1),`%`]}),(0,z.jsx)(`div`,{className:`bar`,children:(0,z.jsx)(`div`,{className:`fill`,style:{width:`${Math.min(100,Math.max(0,e.cache_hit_pct))}%`}})})]})]}),t===`weekly`&&(0,z.jsxs)(`div`,{className:`stats2`,children:[(0,z.jsxs)(`div`,{className:`s`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Used %`}),(0,z.jsx)(`span`,{className:`v`,children:D.pct0(e.used_pct)})]}),(0,z.jsxs)(`div`,{className:`s`,children:[(0,z.jsx)(`span`,{className:`k`,children:`$/1%`}),(0,z.jsx)(`span`,{className:`v`,children:D.usd2(e.dollar_per_pct)})]})]})]})}function us(e){return e==null||e===0?`num`:e>0?`num delta-up`:`num delta-down`}function ds(e){let t=new Set,n=[];for(let r of e.models)t.has(r.chip)||(t.add(r.chip),n.push(r.chip));return n}function fs({row:e}){let t=ds(e),n=t.slice(0,3),r=t.length>3?t.length-3:0;return(0,z.jsxs)(`span`,{className:`models-chips`,children:[n.map(e=>(0,z.jsx)(`span`,{className:`chip ${e}`,children:e},e)),r>0&&(0,z.jsxs)(`span`,{className:`models-chips-more`,children:[`…+`,r]})]})}function ps({rows:e,variant:t,accentClass:n,selectedIndex:r,onSelect:i}){return(0,z.jsxs)(`table`,{className:`history-table history-table--${t} ${n}`,role:`grid`,"aria-rowcount":e.length,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{children:t===`weekly`?`Week`:`Month`}),(0,z.jsx)(`th`,{children:`Models`}),(0,z.jsx)(`th`,{className:`num`,children:`Cost (USD)`}),t===`weekly`&&(0,z.jsx)(`th`,{className:`num`,children:`Used %`}),t===`weekly`&&(0,z.jsx)(`th`,{className:`num`,children:`$/1%`}),(0,z.jsx)(`th`,{className:`num`,children:`Δ`})]})}),(0,z.jsx)(`tbody`,{children:e.map((e,n)=>(0,z.jsxs)(`tr`,{className:n===r?`selected`:void 0,"aria-rowindex":n+1,"aria-selected":n===r,onClick:()=>i(n),children:[(0,z.jsxs)(`td`,{children:[e.label,n===r?` ▶`:``]}),(0,z.jsx)(`td`,{children:(0,z.jsx)(fs,{row:e})}),(0,z.jsx)(`td`,{className:`num`,children:D.usd2(e.cost_usd)}),t===`weekly`&&(0,z.jsx)(`td`,{className:`num`,children:D.pct0(e.used_pct)}),t===`weekly`&&(0,z.jsx)(`td`,{className:`num`,children:D.usd2(e.dollar_per_pct)}),(0,z.jsx)(`td`,{className:us(e.delta_cost_pct),children:D.deltaPct(e.delta_cost_pct)})]},e.label))})]})}function ms(){let e=Ke()?.weekly?.rows??[],[t,n]=(0,g.useState)(0),r=e.length;(0,g.useEffect)(()=>zt([{key:`ArrowDown`,scope:`modal`,when:()=>I().openModal===`weekly`,action:()=>n(e=>Math.min(e+1,Math.max(0,r-1)))},{key:`ArrowUp`,scope:`modal`,when:()=>I().openModal===`weekly`,action:()=>n(e=>Math.max(e-1,0))}]),[r]);let i=(0,z.jsx)(Gt,{panel:`weekly`,panelLabel:`Weekly`,triggerId:`weekly-modal`,onClick:()=>R(N(`weekly`,`weekly-modal`))});if(r===0)return(0,z.jsx)(Io,{title:`Weekly history · last 12`,accentClass:`accent-cyan`,headerExtras:i,children:(0,z.jsx)(`div`,{className:`panel-empty`,children:`No usage history yet.`})});let a=e[Math.min(t,r-1)];return(0,z.jsxs)(Io,{title:`Weekly history · last 12`,accentClass:`accent-cyan`,headerExtras:i,children:[(0,z.jsx)(ls,{row:a,variant:`weekly`,accentClass:`accent-cyan`}),(0,z.jsx)(ps,{rows:e,variant:`weekly`,accentClass:`accent-cyan`,selectedIndex:t,onSelect:n})]})}function hs(){let e=Ke()?.monthly?.rows??[],[t,n]=(0,g.useState)(0),r=e.length;(0,g.useEffect)(()=>zt([{key:`ArrowDown`,scope:`modal`,when:()=>I().openModal===`monthly`,action:()=>n(e=>Math.min(e+1,Math.max(0,r-1)))},{key:`ArrowUp`,scope:`modal`,when:()=>I().openModal===`monthly`,action:()=>n(e=>Math.max(e-1,0))}]),[r]);let i=(0,z.jsx)(Gt,{panel:`monthly`,panelLabel:`Monthly`,triggerId:`monthly-modal`,onClick:()=>R(N(`monthly`,`monthly-modal`))});if(r===0)return(0,z.jsx)(Io,{title:`Monthly history · last 12`,accentClass:`accent-pink`,headerExtras:i,children:(0,z.jsx)(`div`,{className:`panel-empty`,children:`No usage history yet.`})});let a=e[Math.min(t,r-1)];return(0,z.jsxs)(Io,{title:`Monthly history · last 12`,accentClass:`accent-pink`,headerExtras:i,children:[(0,z.jsx)(ls,{row:a,variant:`monthly`,accentClass:`accent-pink`}),(0,z.jsx)(ps,{rows:e,variant:`monthly`,accentClass:`accent-pink`,selectedIndex:t,onSelect:n})]})}var gs=720,_s=180,vs={left:46,right:20,top:18,bottom:20};function ys(e){return e===0?`$0`:e<10?`$`+e.toFixed(2):`$`+Math.round(e).toString()}function bs(){return(0,g.useSyncExternalStore)(L,()=>I().snapshot?.generated_at??``)}function xs({detail:e}){let t=bs(),n=Ht(),r={tz:n.resolvedTz,offsetLabel:n.offsetLabel},i=Date.parse(e.start_at),a=Date.parse(e.end_at)-i||1,o=e=>vs.left+(Date.parse(e)-i)/a*(gs-vs.left-vs.right),s=Math.max(e.cost_usd,e.projection?.total_cost_usd??0),c=e=>{let t=vs.top,n=_s-vs.bottom;return s<=0?n:n-e/s*(n-t)},l=[];for(let e=0;e<=5;e++)l.push(new Date(i+e*36e5).toISOString());let u=e.samples.length>0?e.samples[e.samples.length-1].cum:0,d=e.is_active?t||new Date().toISOString():null,f=[];if(e.samples.length>0){f.push([o(e.start_at),c(0)]);for(let t of e.samples)f.push([o(t.t),c(t.cum)]);d&&f.push([o(d),c(u)])}let p=f.map(([e,t])=>`${e.toFixed(1)},${t.toFixed(1)}`).join(` `),m=f.length>0?`M ${p.replace(/ /g,` L `)} L ${f[f.length-1][0].toFixed(1)},${c(0).toFixed(1)} Z`:``,h=s<=0?[0]:[0,s/2,s];return(0,z.jsx)(`div`,{className:`mblock-timeline`,children:(0,z.jsxs)(`svg`,{viewBox:`0 0 ${gs} ${_s}`,style:{width:`100%`,height:`auto`},role:`img`,"aria-label":`Cumulative cost over the 5-hour block window`,children:[h.map(e=>(0,z.jsx)(`text`,{x:8,y:c(e)+4,fill:`var(--text-dim)`,fontSize:10,children:ys(e)},e)),(0,z.jsx)(`line`,{x1:vs.left,y1:vs.top,x2:vs.left,y2:_s-vs.bottom,stroke:`var(--border-soft)`,strokeWidth:.8}),(0,z.jsx)(`line`,{x1:vs.left,y1:_s-vs.bottom,x2:gs-vs.right,y2:_s-vs.bottom,stroke:`var(--border-soft)`,strokeWidth:.8}),l.slice(1,-1).map(e=>(0,z.jsx)(`line`,{x1:o(e),y1:vs.top,x2:o(e),y2:_s-vs.bottom,stroke:`var(--border-soft)`,strokeDasharray:`2 3`,strokeWidth:.5},e)),l.map(e=>(0,z.jsx)(`text`,{x:o(e)-14,y:_s-5,fill:`var(--text-dim)`,fontSize:9,children:D.timeHHmm(e,r,{noSuffix:!0})},e)),f.length>0?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`path`,{d:m,fill:`var(--accent-green)`,opacity:.12}),(0,z.jsx)(`polyline`,{points:p,fill:`none`,stroke:`var(--accent-green)`,strokeWidth:2}),(0,z.jsx)(`circle`,{cx:f[f.length-1][0],cy:f[f.length-1][1],r:3,fill:`var(--accent-green)`})]}):(0,z.jsx)(`text`,{x:gs/2,y:_s/2,fill:`var(--text-faint)`,fontSize:11,textAnchor:`middle`,children:`No spend recorded yet in this block.`}),e.is_active&&e.projection&&d&&f.length>0?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`polyline`,{points:`${o(d).toFixed(1)},${c(u).toFixed(1)} ${o(e.end_at).toFixed(1)},${c(e.projection.total_cost_usd).toFixed(1)}`,fill:`none`,stroke:`var(--accent-amber)`,strokeWidth:1.5,strokeDasharray:`5 4`,opacity:.85}),(0,z.jsx)(`circle`,{cx:o(e.end_at),cy:c(e.projection.total_cost_usd),r:3,fill:`var(--accent-amber)`,opacity:.85}),(0,z.jsxs)(`text`,{x:o(e.end_at)-50,y:c(e.projection.total_cost_usd)-6,fill:`var(--accent-amber)`,fontSize:9,children:[`proj $`,e.projection.total_cost_usd.toFixed(2)]}),(0,z.jsx)(`line`,{x1:o(d),y1:vs.top,x2:o(d),y2:_s-vs.bottom,stroke:`var(--accent-amber)`,strokeWidth:1.2}),(0,z.jsx)(`text`,{x:o(d)+4,y:vs.top+10,fill:`var(--accent-amber)`,fontSize:9,children:`now`})]}):null]})})}function Ss(){return(0,g.useSyncExternalStore)(L,()=>I().snapshot?.generated_at??``)}function Cs(e,t){let n=Date.parse(e.start_at),r=e.is_active?Date.parse(t)||Date.now():e.actual_end_at?Date.parse(e.actual_end_at):Date.parse(e.end_at),i=Math.max(0,Math.floor((r-n)/6e4)),a=Math.floor(i/60),o=i%60;return`${a}h ${String(o).padStart(2,`0`)}m`}function ws(e,t,n){return`${D.timeHHmm(e,n)} → ${D.timeHHmm(t,n)}`}function Ts(){let e=(0,g.useSyncExternalStore)(L,()=>I().openBlockStartAt),t=Ss(),n=Ht(),r={tz:n.resolvedTz,offsetLabel:n.offsetLabel},[i,a]=(0,g.useState)(null),[o,s]=(0,g.useState)(!0),[c,l]=(0,g.useState)(null),u=(0,g.useRef)(null),d=(0,g.useRef)(!1),f=(0,g.useRef)(null);return(0,g.useEffect)(()=>{f.current=e??null,d.current=!1},[e]),(0,g.useEffect)(()=>{let e=f.current;if(!e){s(!1),l(`No block bound.`),a(null),u.current=null;return}let t=u.current!==e||i==null;u.current=e,t&&(s(!0),l(null),a(null));let n=new AbortController;return fetch(`/api/block/${encodeURIComponent(e)}`,{signal:n.signal}).then(async e=>{if(e.status===404){(t||d.current)&&(s(!1),l(`Block not found (the cache may have rolled forward).`),a(null)),d.current=!0;return}if(!e.ok)throw Error(`HTTP `+e.status);let n=await e.json();d.current=!1,a(n),l(null),s(!1)}).catch(e=>{e.name!==`AbortError`&&(d.current=!1,t&&(l(`Failed to load: `+e.message),s(!1)))}),()=>n.abort()},[e,t]),(0,z.jsx)(Io,{title:i?`${i.anchor===`heuristic`?`~ `:``}Block · ${i.label}`:`Block`,accentClass:`accent-blue`,headerExtras:(0,z.jsx)(Gt,{panel:`blocks`,panelLabel:`5-hour block`,triggerId:`block-modal`,onClick:()=>R(N(`blocks`,`block-modal`))}),children:(0,z.jsxs)(`section`,{className:`modal-block`,children:[o?(0,z.jsx)(`div`,{className:`modal-loading`,children:`Loading block detail…`}):null,c?(0,z.jsx)(`div`,{className:`modal-error`,children:c}):null,!o&&!c&&i?(0,z.jsx)(Es,{detail:i,generatedAt:t,ctx:r}):null]})})}function Es({detail:e,generatedAt:t,ctx:n}){let r=e.cost_usd??0;return(0,z.jsxs)(`div`,{className:`modal-content`,children:[(0,z.jsxs)(`div`,{className:`m-chipstrip`,children:[e.is_active?(0,z.jsx)(`span`,{className:`m-pill accent-green`,children:`● Active`}):null,e.anchor===`heuristic`?(0,z.jsx)(`span`,{className:`m-pill accent-amber`,children:`~ heuristic anchor`}):null,(0,z.jsx)(`span`,{className:`m-pill accent-blue`,children:ws(e.start_at,e.end_at,n)}),(0,z.jsxs)(`span`,{className:`m-pill`,children:[e.entries_count.toLocaleString(`en-US`),` `,e.entries_count===1?`entry`:`entries`]})]}),(0,z.jsxs)(`div`,{className:`m-hero `+(e.is_active?`cols-4`:`cols-3`),children:[(0,z.jsxs)(`div`,{className:`m-kv kv-cost`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#dollar`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,children:D.usd2(e.cost_usd)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Total cost`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-dur`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#clock`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,children:Cs(e,t)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Elapsed`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#hash`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,children:e.total_tokens.toLocaleString(`en-US`)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Total tokens`})]})]}),e.is_active?(0,z.jsxs)(`div`,{className:`m-kv kv-proj`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#crystal-ball`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,children:e.projection?D.usd2(e.projection.total_cost_usd):`—`}),(0,z.jsxs)(`div`,{className:`lbl`,children:[`Projected`,e.projection?` · ${e.projection.remaining_minutes}m left`:``]})]})]}):null]}),(0,z.jsx)(xs,{detail:e}),(0,z.jsxs)(`h3`,{className:`m-sec sec-tok`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#hash`})}),`Tokens`]}),(0,z.jsxs)(`div`,{className:`msess-tok-grid mblock-tok-grid`,children:[(0,z.jsxs)(`div`,{className:`msess-tok-tile`,children:[(0,z.jsx)(`div`,{className:`lbl`,children:`Input`}),(0,z.jsx)(`div`,{className:`n`,children:e.input_tokens.toLocaleString(`en-US`)})]}),(0,z.jsxs)(`div`,{className:`msess-tok-tile`,children:[(0,z.jsx)(`div`,{className:`lbl`,children:`Output`}),(0,z.jsx)(`div`,{className:`n`,children:e.output_tokens.toLocaleString(`en-US`)})]}),(0,z.jsxs)(`div`,{className:`msess-tok-tile`,children:[(0,z.jsx)(`div`,{className:`lbl`,children:`Cache create`}),(0,z.jsx)(`div`,{className:`n`,children:e.cache_creation_tokens.toLocaleString(`en-US`)})]}),(0,z.jsxs)(`div`,{className:`msess-tok-tile`,children:[(0,z.jsx)(`div`,{className:`lbl`,children:`Cache read`}),(0,z.jsx)(`div`,{className:`n`,children:e.cache_read_tokens.toLocaleString(`en-US`)})]}),e.cache_hit_pct==null?null:(0,z.jsxs)(`div`,{className:`msess-tok-tile cache-hit`,children:[(0,z.jsx)(`div`,{className:`lbl`,children:`Cache hit %`}),(0,z.jsxs)(`div`,{className:`n`,children:[e.cache_hit_pct.toFixed(1),`%`]}),(0,z.jsx)(`div`,{className:`bar`,children:(0,z.jsx)(`div`,{className:`fill`,style:{width:Math.min(100,Math.max(0,e.cache_hit_pct))+`%`}})})]})]}),e.models.length>0?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-costm`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#pie-chart`})}),`Cost by model`]}),(0,z.jsxs)(`div`,{className:`msess-costm`,children:[(0,z.jsx)(`div`,{className:`bar`,children:e.models.map(e=>{let t=r>0?e.cost_usd/r*100:0;return(0,z.jsx)(`div`,{className:`seg `+ln(e.model),style:{width:t+`%`}},e.model)})}),(0,z.jsx)(`div`,{className:`legend`,children:e.models.map(e=>{let t=r>0?e.cost_usd/r*100:0;return(0,z.jsxs)(`div`,{className:`lg`,children:[(0,z.jsx)(`span`,{className:`sw `+ln(e.model)}),(0,z.jsx)(`span`,{className:`name`,children:e.display}),(0,z.jsxs)(`span`,{className:`v`,children:[`$`,e.cost_usd.toFixed(2)]}),(0,z.jsxs)(`span`,{className:`pct`,children:[Math.round(t),`%`]})]},e.model)})})]})]}):null,e.is_active&&e.burn_rate&&e.projection?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-burn`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#crystal-ball`})}),`Burn rate & projection`]}),(0,z.jsxs)(`div`,{className:`mblock-burn`,children:[(0,z.jsxs)(`div`,{className:`row`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Burn rate`}),(0,z.jsx)(`span`,{className:`v amber`,children:D.usd2(e.burn_rate.cost_per_hour)}),(0,z.jsx)(`span`,{className:`dim`,children:`/ hr`}),(0,z.jsx)(`span`,{className:`sep`,children:`·`}),(0,z.jsx)(`span`,{className:`v cyan`,children:Math.round(e.burn_rate.tokens_per_minute).toLocaleString(`en-US`)}),(0,z.jsx)(`span`,{className:`dim`,children:`tok / min`})]}),(0,z.jsxs)(`div`,{className:`row`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Projection`}),(0,z.jsx)(`span`,{className:`v amber`,children:D.usd2(e.projection.total_cost_usd)}),(0,z.jsx)(`span`,{className:`dim`,children:`total`}),(0,z.jsx)(`span`,{className:`sep`,children:`·`}),(0,z.jsx)(`span`,{className:`v cyan`,children:e.projection.total_tokens.toLocaleString(`en-US`)}),(0,z.jsx)(`span`,{className:`dim`,children:`tok`}),(0,z.jsx)(`span`,{className:`sep`,children:`·`}),(0,z.jsxs)(`span`,{className:`v`,children:[e.projection.remaining_minutes,` min`]}),(0,z.jsx)(`span`,{className:`dim`,children:`remaining`})]})]})]}):null]})}function Ds({rows:e,selectedDate:t,onSelect:n}){let r=[...e].reverse(),i=r.reduce((e,t)=>Math.max(e,t.cost_usd),0),a=r.length>0?Os(r[0].date):``,o=r.length>0?Os(r[r.length-1].date):``,s=r.find(e=>e.is_today),c=s?`${Os(s.date)} · today`:``;return(0,z.jsxs)(`section`,{className:`daily-modal-bars`,"aria-label":`30-day cost`,children:[(0,z.jsxs)(`div`,{className:`daily-modal-bars-head`,children:[(0,z.jsxs)(`span`,{children:[`30-day cost · selected: `,t?Os(t):`—`]}),(0,z.jsx)(`span`,{className:`hint`,children:`↑↓ navigate · click any bar`})]}),(0,z.jsx)(`div`,{className:`daily-modal-bars-grid`,role:`img`,"aria-label":`30-day cost histogram`,children:r.map(e=>{let r=e.cost_usd<=0,a=e.date===t,o=r?4:i>0?e.cost_usd/i*100:0,s=[`bar`,r?`zero`:``,a?`sel`:``,e.is_today?`today`:``].filter(Boolean).join(` `);return(0,z.jsx)(`button`,{"data-date":e.date,className:s,style:{height:`${o}%`},disabled:r,"aria-pressed":a,"aria-label":`${e.label} cost ${e.cost_usd>0?D.usd2(e.cost_usd):`no usage`}`,title:e.cost_usd>0?`${e.label} · ${D.usd2(e.cost_usd)}`:`${e.label} · —`,onClick:()=>{r||n(e.date)}},e.date)})}),r.length>0&&(0,z.jsxs)(`div`,{className:`daily-modal-bars-axis`,children:[(0,z.jsx)(`span`,{children:a}),c&&(0,z.jsx)(`span`,{children:c}),(0,z.jsx)(`span`,{children:o})]})]})}function Os(e){let t=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`],n=e.split(`-`).map(Number);return`${t[n[1]-1]} ${n[2]}`}function ks(){let e=Ke()?.daily?.rows??[],t=(0,g.useSyncExternalStore)(L,()=>I().openDailyDate),[n,r]=(0,g.useState)(null);(0,g.useEffect)(()=>{t&&r(t)},[]);let i=new Set(e.map(e=>e.date)),a=e[0]?.date??null,o=n&&i.has(n)?n:a;(0,g.useEffect)(()=>zt([{key:`ArrowDown`,scope:`modal`,when:()=>I().openModal===`daily`,action:()=>{let t=o;if(!t)return;let n=e.findIndex(e=>e.date===t);n<0||n>=e.length-1||r(e[n+1].date)}},{key:`ArrowUp`,scope:`modal`,when:()=>I().openModal===`daily`,action:()=>{let t=o;if(!t)return;let n=e.findIndex(e=>e.date===t);n<=0||r(e[n-1].date)}}]),[e,o]);let s=(0,z.jsx)(Gt,{panel:`daily`,panelLabel:`Daily`,triggerId:`daily-modal`,onClick:()=>R(N(`daily`,`daily-modal`))});if(e.length===0)return(0,z.jsx)(Io,{title:`Daily history · last 30`,accentClass:`accent-indigo`,headerExtras:s,children:(0,z.jsx)(`div`,{className:`panel-empty`,children:`No usage history yet.`})});let c=e.findIndex(e=>e.date===o),l=c>=0?c:0,u=e[l],d=e[l+1],f=As(u,d);return(0,z.jsxs)(Io,{title:`Daily history · last 30`,accentClass:`accent-indigo`,headerExtras:s,children:[(0,z.jsx)(Ds,{rows:e,selectedDate:o,onSelect:r}),(0,z.jsx)(ls,{row:f,variant:`daily`,accentClass:`accent-indigo`})]})}function As(e,t){let n=t&&t.cost_usd>0?(e.cost_usd-t.cost_usd)/t.cost_usd:null;return{label:e.label,cost_usd:e.cost_usd,total_tokens:e.total_tokens,input_tokens:e.input_tokens,output_tokens:e.output_tokens,cache_creation_tokens:e.cache_creation_tokens,cache_read_tokens:e.cache_read_tokens,used_pct:null,dollar_per_pct:null,delta_cost_pct:n,is_current:e.is_today,models:e.models,cache_hit_pct:e.cache_hit_pct}}var js=[`#d946ef`,`#c084fc`,`#60a5fa`,`#fbbf24`,`#22d3ee`],Ms=`#64748b`,Ns=5,Ps=400,Fs=150;function Is({trend:e,yMode:t,windowWeeks:n,onProjectSelect:r}){let i=(0,g.useMemo)(()=>{let t=Math.max(0,Math.min(n,e.window_weeks)),r=e.weeks.slice(-t),i=e.projects.map(e=>{let n=e.weekly_cost.slice(-t),r=n.reduce((e,t)=>e+t,0);return{key:e.key,weekly:n,cost:r,color:``}}).sort((e,t)=>t.cost-e.cost),a=i.slice(0,Ns).map((e,t)=>({...e,color:js[t]??Ms})),o=i.slice(Ns),s=r.map((e,t)=>o.reduce((e,n)=>e+(n.weekly[t]??0),0)),c=s.reduce((e,t)=>e+t,0),l=[...a];return o.length>0&&c>0&&l.push({key:`(other)`,weekly:s,cost:c,color:Ms}),{weeks:r,series:l}},[e,n]),a=on();if(i.weeks.length===0||i.series.length===0)return(0,z.jsxs)(`div`,{className:`panel-empty`,children:[`No project activity in the last `,n,` week`,n===1?``:`s`,`.`]});let o=i.weeks.length,s=i.weeks.map((e,t)=>i.series.reduce((e,n)=>e+(n.weekly[t]??0),0)),c=t===`share`?100:Math.max(...s,.01),l=(e,t=`left`)=>o<=1?t===`left`?Ps*.1:Ps*.9:e/(o-1)*Ps,u=Array(o).fill(0),d=i.series.map(e=>{let n=[];for(let e=0;e<o;e++){let t=Fs-u[e]/c*Fs;n.push(`${l(e,`left`).toFixed(2)},${t.toFixed(2)}`),o===1&&n.push(`${l(e,`right`).toFixed(2)},${t.toFixed(2)}`)}for(let r=o-1;r>=0;r--){let i=s[r]??0,a=t===`share`?i>0?(e.weekly[r]??0)/i*100:0:e.weekly[r]??0;u[r]+=a;let d=Fs-u[r]/c*Fs;o===1&&n.push(`${l(r,`right`).toFixed(2)},${d.toFixed(2)}`),n.push(`${l(r,`left`).toFixed(2)},${d.toFixed(2)}`)}return{color:e.color,key:e.key,points:n.join(` `)}}),f=i.weeks.map(e=>(0,z.jsx)(`span`,{children:e.week_label},e.week_start_date));return(0,z.jsxs)(`div`,{className:`projects-trend`,children:[(0,z.jsx)(`svg`,{viewBox:`0 0 ${Ps} ${Fs}`,preserveAspectRatio:`none`,role:`img`,"aria-label":`Stacked area: project ${t===`share`?`share %`:`cost`} over ${o} weeks`,children:d.map(e=>{let t=e.key===`(other)`;return(0,z.jsx)(`polygon`,{fill:e.color,opacity:t?.5:.65,points:e.points,"data-series-key":e.key,onClick:()=>{t||r?.(e.key)},style:{cursor:t?`default`:`pointer`}},e.key)})}),(0,z.jsx)(`div`,{className:`projects-trend-xaxis`,children:f}),(0,z.jsx)(`div`,{className:`projects-trend-legend`,children:i.series.map(e=>{let t=e.key===`(other)`,n=(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`span`,{className:`sw`,style:{background:e.color}}),e.key]});return a&&!t?(0,z.jsx)(`button`,{type:`button`,className:`projects-trend-legend-item`,"data-series-key":e.key,onClick:()=>r?.(e.key),children:n},e.key):(0,z.jsx)(`span`,{className:`projects-trend-legend-item`,"data-series-key":e.key,children:n},e.key)})})]})}function Ls(e,t){let[n,r]=(0,g.useState)(null),[i,a]=(0,g.useState)(!1),[o,s]=(0,g.useState)(null),c=Ke()?.generated_at??``,l=(0,g.useRef)(0),u=(0,g.useRef)(null),d=(0,g.useRef)(null),f=(0,g.useRef)(!1);return(0,g.useEffect)(()=>{if(!e){r(null),a(!1),s(null),l.current=0,u.current=null,d.current=null,f.current=!1;return}let i=u.current!==e||d.current!==t,o=i||n==null;if(o&&f.current&&!i)return;o&&(a(!0),s(null)),i&&(l.current=0),u.current=e,d.current=t,f.current=!0;let c=new AbortController,p=`/api/project/${encodeURIComponent(e)}?weeks=${t}`;return fetch(p,{signal:c.signal}).then(async e=>{if(e.status===404){l.current+=1,l.current>=2?(r(null),s(`Project no longer in cache — close this drill.`),a(!1)):o&&(s(`Couldn't load project detail — will retry on next tick.`),a(!1));return}if(!e.ok){o&&(s(`Couldn't load project detail — will retry on next tick.`),a(!1));return}l.current=0,r(await e.json()),s(null),a(!1)}).catch(e=>{e?.name!==`AbortError`&&o&&(s(`Couldn't load project detail — will retry on next tick.`),a(!1))}).finally(()=>{f.current=!1}),()=>c.abort()},[e,t,c]),{data:n,loading:i,error:o}}function Rs({projectKey:e,windowWeeks:t}){let{data:n,loading:r,error:i}=Ls(e,t),a=Ht(),o={tz:a.resolvedTz,offsetLabel:a.offsetLabel},s=n!=null&&n.key!==e;if(r&&!n||s)return(0,z.jsx)(`div`,{className:`panel-empty`,children:`Loading…`});if(i&&!n)return(0,z.jsx)(`div`,{className:`panel-empty`,children:i});if(!n)return null;let c=n.models[0]?.cost_usd??0,l=c>0?c:1,u=Math.max(0,n.sessions_total-n.sessions.length);return(0,z.jsxs)(`div`,{className:`projects-drill`,"data-testid":`projects-drill`,"aria-live":`polite`,children:[(0,z.jsx)(`div`,{className:`projects-drill-head`,children:(0,z.jsxs)(`span`,{className:`title`,children:[`▾ `,n.key,` · `,n.sessions_total,` session`,n.sessions_total===1?``:`s`,` · `,D.usd2(n.window_cost_usd),` (`,t,`w)`]})}),(0,z.jsxs)(`div`,{className:`projects-drill-grid`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`section-label`,children:`Models (this project)`}),n.models.length===0?(0,z.jsx)(`div`,{className:`muted`,children:`No model data for this window.`}):n.models.map(e=>{let t={"--w":`${e.cost_usd/l*100}%`};return(0,z.jsxs)(`div`,{className:`drill-bar-row`,children:[(0,z.jsx)(`span`,{className:`chip ${ln(e.model)}`,children:e.model}),(0,z.jsx)(`div`,{className:`drill-bar`,style:t}),(0,z.jsx)(`span`,{className:`cost ${un(e.cost_usd)}`,children:D.usd2(e.cost_usd)})]},e.model)})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`section-label`,children:`Recent sessions →`}),n.sessions.length===0?(0,z.jsx)(`div`,{className:`muted`,children:`No sessions for this window.`}):n.sessions.map((e,t)=>(0,z.jsxs)(`button`,{"data-testid":`drill-session-${t}`,className:`drill-session-row`,onClick:()=>R({type:`OPEN_MODAL`,kind:`session`,sessionId:e.session_id}),children:[(0,z.jsx)(`span`,{className:`started`,children:D.datetimeShort(e.last_activity_at,o)}),(0,z.jsx)(`span`,{className:`chip ${ln(e.primary_model)}`,children:e.primary_model}),(0,z.jsx)(`span`,{className:`cost ${un(e.cost_usd)}`,children:D.usd2(e.cost_usd)})]},e.session_id)),(0,z.jsxs)(`div`,{className:`drill-session-footer`,children:[u>0&&(0,z.jsxs)(`span`,{className:`muted`,children:[`+`,u,` more`]}),(0,z.jsx)(`button`,{type:`button`,"data-testid":`drill-show-in-sessions`,className:`drill-show-in-sessions`,onClick:()=>{R({type:`SET_FILTER`,text:n.key}),R({type:`CLOSE_MODAL`})},children:`Show in Sessions →`})]})]})]})]})}var zs=(e,t)=>e<t?-1:+(e>t),Bs=[{id:`project`,label:`Project`,defaultDirection:`asc`,compare:(e,t)=>zs(e.key,t.key),className:`project`},{id:`sessions`,label:`Sessions`,defaultDirection:`desc`,numeric:!0,compare:(e,t)=>e.sessionsCount-t.sessionsCount},{id:`first_seen`,label:`First seen`,defaultDirection:`asc`,nullKey:e=>e.firstSeenAt,compare:(e,t)=>zs(e.firstSeenAt,t.firstSeenAt),className:`started`},{id:`last_seen`,label:`Last seen`,defaultDirection:`desc`,nullKey:e=>e.lastSeenAt,compare:(e,t)=>zs(e.lastSeenAt,t.lastSeenAt),className:`started`},{id:`cost`,label:`Cost`,defaultDirection:`desc`,numeric:!0,compare:(e,t)=>e.windowCost-t.windowCost},{id:`used_pct`,label:`Used %`,defaultDirection:`desc`,numeric:!0,nullKey:e=>e.windowPct,compare:(e,t)=>e.windowPct-t.windowPct},{id:`share_of_window`,label:`% of week`,defaultDirection:`desc`,numeric:!0,nullKey:e=>e.shareOfWindow,compare:(e,t)=>e.shareOfWindow-t.shareOfWindow}],Vs=[{column:`cost`,direction:`desc`,label:`cost`,arrow:`↓`},{column:`sessions`,direction:`desc`,label:`sessions`,arrow:`↓`},{column:`used_pct`,direction:`desc`,label:`used`,arrow:`↓`},{column:`share_of_window`,direction:`desc`,label:`share`,arrow:`↓`},{column:`first_seen`,direction:`desc`,label:`first`,arrow:`↓`},{column:`last_seen`,direction:`desc`,label:`last`,arrow:`↓`},{column:`project`,direction:`asc`,label:`project`,arrow:`↑`}],Hs=[1,4,8,12];function Us(){let e=Ke(),t=Ht(),n={tz:t.resolvedTz,offsetLabel:t.offsetLabel},r=(0,g.useSyncExternalStore)(L,()=>I().openProjectKey),i=(0,g.useSyncExternalStore)(L,()=>I().prefs.projectsWindowWeeks),a=(0,g.useSyncExternalStore)(L,()=>I().prefs.projectsTrendYMode),o=(0,g.useSyncExternalStore)(L,()=>I().prefs.projectsSortOverride),[s,c]=(0,g.useState)(r??null),[l,u]=(0,g.useState)(!1);(0,g.useEffect)(()=>{if(r){c(r);return}s||c(e?.projects?.current_week?.rows?.[0]?.key??null)},[r,e?.projects?.current_week?.rows]);let d=e?.projects?.trend??null,f=i,p=d?.window_weeks??0,m=(e,t)=>{R({type:`SAVE_PREFS`,patch:{[e]:t}})},h=e=>{c(t=>t===e?null:e)},_=(d?.projects??[]).map(e=>{let t=e.weekly_cost.slice(-i),n=e.weekly_pct.slice(-i),r=e.sessions_per_week.slice(-i),a=e.first_seen_per_week.slice(-i),o=e.last_seen_per_week.slice(-i),s=t.reduce((e,t)=>e+t,0),c=n.reduce((e,t)=>t==null?e:(e??0)+t,null),l=r.reduce((e,t)=>e+t,0),u=a.reduce((e,t)=>t==null?e:e==null||t<e?t:e,null),d=o.reduce((e,t)=>t==null?e:e==null||t>e?t:e,null);return{key:e.key,sessionsCount:l,firstSeenAt:u,lastSeenAt:d,windowCost:s,windowPct:c,shareOfWindow:null}}),v=_.reduce((e,t)=>e+t.windowCost,0);for(let e of _)e.shareOfWindow=v>0?e.windowCost/v*100:null;let y=o?de(_,Bs,o):de(_,Bs,{column:`cost`,direction:`desc`}),b=y.filter(e=>e.windowCost>0).slice(0,10),x=y.length-b.length,S=l?y:b,C=x>0,w=on(),T=(()=>{if(!o)return 0;let e=Vs.findIndex(e=>e.column===o.column&&e.direction===o.direction);return e===-1?0:e})(),ee=()=>{let e=Vs[(T+1)%Vs.length];R({type:`SET_TABLE_SORT`,table:`projects`,override:{column:e.column,direction:e.direction}})},te=Vs[T];return V([{key:`1`,scope:`modal`,action:()=>m(`projectsWindowWeeks`,1)},{key:`4`,scope:`modal`,action:()=>m(`projectsWindowWeeks`,4)},{key:`8`,scope:`modal`,action:()=>m(`projectsWindowWeeks`,8)},{key:`0`,scope:`modal`,action:()=>m(`projectsWindowWeeks`,12)},{key:`s`,scope:`modal`,action:()=>m(`projectsTrendYMode`,a===`share`?`absolute`:`share`)},{key:`ArrowUp`,scope:`modal`,action:()=>{if(S.length===0)return;let e=S.findIndex(e=>e.key===s);c(S[e<=0?S.length-1:e-1].key)}},{key:`ArrowDown`,scope:`modal`,action:()=>{if(S.length===0)return;let e=S.findIndex(e=>e.key===s);c(S[e===-1||e===S.length-1?0:e+1].key)}},{key:`Enter`,scope:`modal`,action:()=>{s?c(null):S.length>0&&c(S[0].key)}}]),(0,z.jsx)(Io,{title:`Projects · last ${i}w`,accentClass:`accent-magenta`,headerExtras:(0,z.jsx)(Gt,{panel:`projects`,panelLabel:`Projects`,triggerId:`projects-modal`,dataTestId:`share-icon-projects-modal`,onClick:()=>R(N(`projects`,`projects-modal`,{windowWeeks:i}))}),children:(0,z.jsxs)(`div`,{className:`projects-modal-body`,children:[(0,z.jsxs)(`div`,{className:`projects-controls`,role:`radiogroup`,"aria-label":`Window`,children:[Hs.map(e=>(0,z.jsxs)(`button`,{type:`button`,role:`radio`,"aria-checked":i===e,className:`pill ${i===e?`on`:``}`,onClick:()=>m(`projectsWindowWeeks`,e),children:[e,`w`]},`window-${e}`)),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`|`}),(0,z.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":a===`share`,className:`pill ${a===`share`?`on`:``}`,onClick:()=>m(`projectsTrendYMode`,`share`),children:`share %`}),(0,z.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":a===`absolute`,className:`pill ${a===`absolute`?`on`:``}`,onClick:()=>m(`projectsTrendYMode`,`absolute`),children:`$ absolute`})]}),p>0&&p<f&&(0,z.jsxs)(`div`,{className:`projects-notice`,children:[`Showing `,p,` week`,p===1?``:`s`,` (need more history for the full window).`]}),d?(0,z.jsx)(Is,{trend:d,yMode:a,windowWeeks:i,onProjectSelect:e=>c(e)}):(0,z.jsx)(`div`,{className:`panel-empty`,children:`Projects trend unavailable.`}),w&&(0,z.jsxs)(`button`,{type:`button`,className:`projects-mobile-sort`,"data-testid":`projects-mobile-sort`,onClick:ee,"aria-label":`Cycle sort column`,children:[`Sort: `,te.label,` `,te.arrow]}),(0,z.jsxs)(`table`,{className:`projects-table`,children:[(0,z.jsx)(tn,{columns:Bs,override:o,onChange:e=>R({type:`SET_TABLE_SORT`,table:`projects`,override:e}),accentVar:`--accent-magenta`}),(0,z.jsx)(`tbody`,{children:S.map(e=>(0,z.jsxs)(g.Fragment,{children:[(0,z.jsxs)(`tr`,{"data-testid":`projects-table-row`,"data-cost":e.windowCost,"data-sessions":e.sessionsCount,"aria-expanded":s===e.key,className:s===e.key?`selected`:``,onClick:()=>h(e.key),children:[(0,z.jsx)(`td`,{className:`project`,children:e.key}),(0,z.jsx)(`td`,{children:e.sessionsCount}),(0,z.jsx)(`td`,{className:`started first-seen`,children:D.dateShort(e.firstSeenAt,n)??`—`}),(0,z.jsx)(`td`,{className:`started last-seen`,children:D.dateShort(e.lastSeenAt,n)??`—`}),(0,z.jsx)(`td`,{className:un(e.windowCost),children:D.usd2(e.windowCost)}),(0,z.jsx)(`td`,{children:e.windowPct==null?`—`:D.pct0(e.windowPct)}),(0,z.jsx)(`td`,{children:e.shareOfWindow==null?`—`:D.pct0(e.shareOfWindow)})]}),w&&s===e.key&&(0,z.jsx)(`tr`,{className:`projects-drill-row`,"aria-hidden":`false`,children:(0,z.jsx)(`td`,{colSpan:7,children:(0,z.jsx)(Rs,{projectKey:e.key,windowWeeks:i})})})]},e.key))})]}),C&&(0,z.jsx)(`button`,{type:`button`,className:`projects-table-toggle`,"data-testid":`projects-table-toggle`,"aria-expanded":l,onClick:()=>u(e=>!e),children:l?`Show top 10 active`:`Show all ${y.length} projects (+${x})`}),!w&&s&&(0,z.jsx)(Rs,{projectKey:s,windowWeeks:i}),(0,z.jsxs)(`div`,{className:`projects-modal-footer-hint`,"data-testid":`projects-modal-footer-hint`,"aria-live":`off`,children:[(0,z.jsxs)(`span`,{children:[(0,z.jsx)(`kbd`,{children:`1`}),`/`,(0,z.jsx)(`kbd`,{children:`4`}),`/`,(0,z.jsx)(`kbd`,{children:`8`}),`/`,(0,z.jsx)(`kbd`,{children:`0`}),` window`]}),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`·`}),(0,z.jsxs)(`span`,{children:[(0,z.jsx)(`kbd`,{children:`↑↓`}),` row`]}),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`·`}),(0,z.jsxs)(`span`,{children:[(0,z.jsx)(`kbd`,{children:`Enter`}),` drill`]}),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`·`}),(0,z.jsxs)(`span`,{children:[(0,z.jsx)(`kbd`,{children:`s`}),` share/$`]}),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`·`}),(0,z.jsxs)(`span`,{children:[(0,z.jsx)(`kbd`,{children:`Esc`}),` close`]}),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`·`}),(0,z.jsx)(yt,{})]})]})})}var Ws=100;function Gs({alert:e,ctx:t}){if(e.axis===`weekly`){let n=e.context.week_start_date?D.weekStart(e.context.week_start_date,t):null,r=e.context.dollars_per_percent;return(0,z.jsxs)(`span`,{className:`alert-context alert-context--weekly`,children:[n?`Week of ${n}`:`Week —`,r!=null&&(0,z.jsxs)(z.Fragment,{children:[` · `,(0,z.jsxs)(`span`,{className:`num`,children:[`$`,r.toFixed(2),`/1%`]})]})]})}return(0,z.jsxs)(`span`,{className:`alert-context alert-context--five-hour`,children:[`Block `,e.context.block_start_at?D.timeOnly(e.context.block_start_at,t):`—`]})}function Ks({alert:e}){let t=e.axis===`weekly`?e.context.cumulative_cost_usd:e.context.block_cost_usd;return(0,z.jsx)(`span`,{className:`num`,children:D.usd2(t??null)})}function qs(){let e=(0,g.useSyncExternalStore)(L,()=>I().alerts),t=Ht(),n={tz:t.resolvedTz,offsetLabel:t.offsetLabel},r=e.slice(0,Ws);return r.length===0?(0,z.jsx)(Io,{title:`Recent alerts`,accentClass:`accent-amber`,children:(0,z.jsx)(`div`,{className:`panel-empty`,children:`No alerts yet. Alerts appear when usage crosses 90% or 95%.`})}):(0,z.jsx)(Io,{title:`Recent alerts`,accentClass:`accent-amber`,children:(0,z.jsxs)(`div`,{className:`alerts-modal-body`,children:[(0,z.jsxs)(`table`,{className:`alerts-table`,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{scope:`col`,children:`%`}),(0,z.jsx)(`th`,{scope:`col`,children:`Axis`}),(0,z.jsx)(`th`,{scope:`col`,children:`Cost`}),(0,z.jsx)(`th`,{scope:`col`,children:`Context`}),(0,z.jsx)(`th`,{scope:`col`,children:`Alerted`})]})}),(0,z.jsx)(`tbody`,{children:r.map(e=>{let t=e.threshold>=95?`red`:`amber`;return(0,z.jsxs)(`tr`,{className:`alert-modal-row`,children:[(0,z.jsxs)(`td`,{className:`alert-threshold severity-${t} ${t} num`,children:[e.threshold,`%`]}),(0,z.jsx)(`td`,{children:(0,z.jsx)(`span`,{className:`chip chip--${e.axis}`,children:e.axis===`weekly`?`WEEKLY`:`5H-BLOCK`})}),(0,z.jsx)(`td`,{className:`num`,children:(0,z.jsx)(Ks,{alert:e})}),(0,z.jsx)(`td`,{children:(0,z.jsx)(Gs,{alert:e,ctx:n})}),(0,z.jsx)(`td`,{className:`alert-when`,children:D.relativeOrAbsolute(e.alerted_at,n)})]},e.id)})})]}),e.length>Ws&&(0,z.jsxs)(`div`,{className:`alerts-modal-foot`,children:[`Showing `,Ws,` of `,e.length,` most recent`]})]})})}function Js(){let e=(0,g.useSyncExternalStore)(L,()=>I().openModal);if(!e)return null;switch(e){case`current-week`:return(0,z.jsx)(Uo,{});case`forecast`:return(0,z.jsx)(Yo,{});case`trend`:return(0,z.jsx)(is,{});case`session`:return(0,z.jsx)(ss,{});case`weekly`:return(0,z.jsx)(ms,{});case`monthly`:return(0,z.jsx)(hs,{});case`block`:return(0,z.jsx)(Ts,{});case`daily`:return(0,z.jsx)(ks,{});case`projects`:return(0,z.jsx)(Us,{});case`alerts`:return(0,z.jsx)(qs,{})}}var X=class extends Error{code;constructor(e,t,n,r){super(n),this.status=e,this.field=t,this.code=r}};async function Ys(e){if(!e.ok){let t={};try{t=await e.json()}catch{}throw new X(e.status,t.field,t.error??`HTTP ${e.status}`,t.code)}return e.json()}async function Xs(e,t){return Ys(await fetch(`/api/share/templates?panel=${encodeURIComponent(e)}`,{signal:t?.signal}))}async function Zs(e,t){return Ys(await fetch(`/api/share/render`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),signal:t?.signal}))}var Qs=[{id:`recap`,label:`Recap`,placeholderDescription:`Text + tiny chart`},{id:`visual`,label:`Visual`,placeholderDescription:`Coming in M2`},{id:`detail`,label:`Detail`,placeholderDescription:`Coming in M2`}];function $s(e){return e.endsWith(`-recap`)?`recap`:e.endsWith(`-visual`)?`visual`:e.endsWith(`-detail`)?`detail`:null}function ec({panel:e,templates:t,error:n,selectedTemplateId:r,onSelect:i}){if(n)return(0,z.jsx)(`div`,{className:`share-gallery-error`,role:`alert`,children:n});let a={};for(let e of t??[]){let t=$s(e.id);t&&(a[t]=e)}return(0,z.jsx)(`div`,{className:`share-gallery`,role:`radiogroup`,"aria-label":`Report template`,children:Qs.map(e=>{let n=a[e.id];if(t==null)return(0,z.jsxs)(`div`,{className:`share-tile share-tile-skeleton`,"aria-hidden":`true`,children:[(0,z.jsx)(`div`,{className:`share-tile-skeleton-bar`}),(0,z.jsx)(`div`,{className:`share-tile-skeleton-bar short`})]},e.id);if(!n)return(0,z.jsxs)(`button`,{type:`button`,className:`share-tile share-tile-disabled`,disabled:!0,"aria-disabled":`true`,role:`radio`,"aria-checked":`false`,title:`${e.label} — ${e.placeholderDescription}`,children:[(0,z.jsx)(`div`,{className:`share-tile-label`,children:e.label}),(0,z.jsx)(`div`,{className:`share-tile-desc`,children:e.placeholderDescription})]},e.id);let o=n.id===r;return(0,z.jsxs)(`button`,{type:`button`,className:`share-tile`+(o?` share-tile-selected`:``),role:`radio`,"aria-checked":o,"data-template-id":n.id,onClick:()=>i(n.id),children:[(0,z.jsx)(`div`,{className:`share-tile-label`,children:n.label}),(0,z.jsx)(`div`,{className:`share-tile-desc`,children:n.description})]},e.id)})})}function tc({options:e,onChange:t}){let n=n=>t({...e,...n}),r=n=>t({...e,period:{...e.period,...n}}),i=e=>{if(e===``){n({top_n:null});return}let t=Number.parseInt(e,10);Number.isNaN(t)||n({top_n:Math.max(1,t)})};return(0,z.jsxs)(`div`,{className:`share-knobs`,children:[(0,z.jsxs)(`div`,{className:`share-knob`,children:[(0,z.jsx)(`label`,{htmlFor:`share-knob-period`,children:`Period`}),(0,z.jsxs)(`select`,{id:`share-knob-period`,value:e.period.kind,onChange:e=>r({kind:e.target.value}),children:[(0,z.jsx)(`option`,{value:`current`,children:`This week`}),(0,z.jsx)(`option`,{value:`previous`,children:`Previous week`}),(0,z.jsx)(`option`,{value:`custom`,children:`Custom`})]}),e.period.kind===`custom`?(0,z.jsxs)(`div`,{className:`share-knob-period-custom`,children:[(0,z.jsxs)(`label`,{className:`share-knob-sublabel`,children:[(0,z.jsx)(`span`,{children:`Start`}),(0,z.jsx)(`input`,{type:`date`,value:e.period.start?.slice(0,10)??``,onChange:e=>r({start:e.target.value}),"aria-label":`Custom period start date`})]}),(0,z.jsxs)(`label`,{className:`share-knob-sublabel`,children:[(0,z.jsx)(`span`,{children:`End`}),(0,z.jsx)(`input`,{type:`date`,value:e.period.end?.slice(0,10)??``,onChange:e=>r({end:e.target.value}),"aria-label":`Custom period end date`})]})]}):null]}),(0,z.jsxs)(`div`,{className:`share-knob`,children:[(0,z.jsx)(`span`,{className:`share-knob-label`,children:`Theme`}),(0,z.jsxs)(`div`,{className:`share-knob-radiogroup`,role:`radiogroup`,"aria-label":`Theme`,children:[(0,z.jsxs)(`label`,{className:`share-knob-radio`,children:[(0,z.jsx)(`input`,{type:`radio`,name:`share-theme`,value:`light`,checked:e.theme===`light`,onChange:()=>n({theme:`light`})}),(0,z.jsx)(`span`,{children:`Light`})]}),(0,z.jsxs)(`label`,{className:`share-knob-radio`,children:[(0,z.jsx)(`input`,{type:`radio`,name:`share-theme`,value:`dark`,checked:e.theme===`dark`,onChange:()=>n({theme:`dark`})}),(0,z.jsx)(`span`,{children:`Dark`})]})]})]}),(0,z.jsxs)(`div`,{className:`share-knob`,children:[(0,z.jsx)(`label`,{htmlFor:`share-knob-topn`,children:`Top-N`}),(0,z.jsx)(`input`,{id:`share-knob-topn`,type:`number`,min:1,step:1,inputMode:`numeric`,value:e.top_n??``,onChange:e=>i(e.target.value),"aria-label":`Top-N`})]}),(0,z.jsxs)(`div`,{className:`share-knob`,children:[(0,z.jsx)(`span`,{className:`share-knob-label`,children:`Projects`}),(0,z.jsx)(`button`,{type:`button`,className:`share-knob-allowlist-stub`,disabled:!0,"aria-disabled":`true`,title:`Project allowlist — coming in M3+`,children:`All projects`})]}),(0,z.jsx)(`div`,{className:`share-knob`,children:(0,z.jsxs)(`label`,{className:`share-knob-checkbox`,children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:e.show_chart,onChange:e=>n({show_chart:e.target.checked}),"aria-label":`Include chart in export`}),(0,z.jsx)(`span`,{children:`Show chart`})]})}),(0,z.jsx)(`div`,{className:`share-knob`,children:(0,z.jsxs)(`label`,{className:`share-knob-checkbox`,children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:e.show_table,onChange:e=>n({show_table:e.target.checked}),"aria-label":`Include table in export`}),(0,z.jsx)(`span`,{children:`Show table`})]})}),(0,z.jsx)(`div`,{className:`share-knob`,children:(0,z.jsxs)(`label`,{className:`share-knob-checkbox`,children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:!e.reveal_projects,onChange:e=>n({reveal_projects:!e.target.checked}),"aria-label":`Anonymize project names on export`}),(0,z.jsx)(`span`,{children:`Anon on export`})]})})]})}var nc=200,rc={status:`idle`,body:``,contentType:``,errorMessage:null,errorField:null};function ic({panel:e,templateId:t,options:n}){let[r,i]=(0,g.useState)(rc),a=(0,g.useRef)(null),o=(0,g.useRef)(0);return(0,g.useEffect)(()=>{if(!t){i(rc);return}i(e=>({...e,status:`loading`}));let r=++o.current,s=setTimeout(()=>{a.current?.abort();let s=new AbortController;a.current=s,Zs({panel:e,template_id:t,options:{...n,reveal_projects:!0}},{signal:s.signal}).then(e=>{r===o.current&&i({status:`ready`,body:e.body,contentType:e.content_type,errorMessage:null,errorField:null})}).catch(e=>{if(r===o.current&&!(e&&typeof e==`object`&&e.name===`AbortError`)){if(e instanceof X){i({status:`error`,body:``,contentType:``,errorMessage:e.message??`HTTP ${e.status}`,errorField:e.field??null});return}i({status:`error`,body:``,contentType:``,errorMessage:e.message??`Unknown error`,errorField:null})}})},nc);return()=>{clearTimeout(s)}},[e,t,n]),(0,g.useEffect)(()=>()=>{a.current?.abort()},[]),t?r.status===`error`?(0,z.jsxs)(`div`,{className:`share-preview share-preview-error`,role:`alert`,children:[(0,z.jsx)(`div`,{className:`share-preview-error-title`,children:`Preview failed`}),(0,z.jsxs)(`div`,{className:`share-preview-error-message`,children:[r.errorMessage,r.errorField?(0,z.jsxs)(`span`,{className:`share-preview-error-field`,children:[` `,`(field: `,r.errorField,`)`]}):null]})]}):r.status===`loading`||r.status===`idle`?(0,z.jsx)(`div`,{className:`share-preview share-preview-loading`,"aria-busy":`true`,children:`Rendering preview…`}):n.format===`md`?(0,z.jsx)(`pre`,{className:`share-preview share-preview-md`,"aria-label":`Markdown preview`,children:r.body}):(0,z.jsx)(`iframe`,{className:`share-preview share-preview-iframe`,title:`Report preview (decorative)`,tabIndex:-1,sandbox:`allow-same-origin`,srcDoc:r.body}):(0,z.jsx)(`div`,{className:`share-preview share-preview-empty`,children:`Select a template to preview.`})}var ac={"current-week":`Current week`,trend:`Trend`,weekly:`Weekly`,daily:`Daily`,monthly:`Monthly`,blocks:`5-hour blocks`,forecast:`Forecast`,sessions:`Sessions`,projects:`Projects`};function oc(e){return ac[e]}function sc(e){switch(e){case`md`:return`md`;case`html`:return`html`;case`svg`:return`svg`}}async function cc(e){if(!e.ok){let t={};try{t=await e.json()}catch{}throw new X(e.status,t.field,t.error??`HTTP ${e.status}`)}return e.json()}async function lc(e){return cc(await fetch(`/api/share/presets`,{signal:e?.signal}))}async function uc(e,t){return cc(await fetch(`/api/share/presets`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),signal:t?.signal}))}async function dc(e,t,n){let r=await fetch(`/api/share/presets/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,{method:`DELETE`,signal:n?.signal});if(!r.ok){let e={};try{e=await r.json()}catch{}throw new X(r.status,void 0,e.error??`HTTP ${r.status}`)}}async function fc(e){return cc(await fetch(`/api/share/history`,{signal:e?.signal}))}async function Z(e,t){return cc(await fetch(`/api/share/history`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),signal:t?.signal}))}function pc({panel:e,templateId:t,options:n,onSaved:r,onCancel:i}){let[a,o]=(0,g.useState)(``),[s,c]=(0,g.useState)(!1),[l,u]=(0,g.useState)(null);async function d(){let i=a.trim();if(!i){u(`Name is required`);return}if(i.length>64){u(`Name must be 64 characters or fewer`);return}if(i.includes(`/`)){u(`Name cannot contain '/'`);return}c(!0),u(null);try{await uc({panel:e,name:i,template_id:t,options:n}),R({type:`SHOW_STATUS_TOAST`,text:`Saved preset "${i}"`}),r()}catch(e){u((e instanceof X?e.message??`HTTP ${e.status}`:e.message)??`Save failed`)}finally{c(!1)}}return(0,z.jsxs)(`div`,{className:`share-save-popover`,role:`dialog`,"aria-label":`Save preset`,children:[(0,z.jsxs)(`label`,{className:`share-save-label`,children:[`Preset name`,(0,z.jsx)(`input`,{type:`text`,className:`share-save-input`,autoFocus:!0,value:a,maxLength:64,disabled:s,onChange:e=>o(e.target.value),onKeyDown:e=>{e.key===`Enter`?(e.preventDefault(),e.stopPropagation(),d()):e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),i())}})]}),l?(0,z.jsx)(`div`,{className:`share-save-error`,role:`alert`,children:l}):null,(0,z.jsxs)(`div`,{className:`share-save-actions`,children:[(0,z.jsx)(`button`,{type:`button`,onClick:i,disabled:s,children:`Cancel`}),(0,z.jsx)(`button`,{type:`button`,onClick:()=>void d(),disabled:s,children:s?`Saving…`:`Save`})]})]})}async function mc(e,t,n){let r=new Blob([e],{type:`image/svg+xml`}),i=URL.createObjectURL(r);try{let e=new Image;e.src=i,await e.decode();let r=document.createElement(`canvas`);r.width=e.naturalWidth*t,r.height=e.naturalHeight*t;let a=r.getContext(`2d`);if(!a)throw Error(`Could not acquire 2D canvas context`);a.fillStyle=n,a.fillRect(0,0,r.width,r.height),a.scale(t,t),a.drawImage(e,0,0);let o=await new Promise(e=>{r.toBlob(t=>e(t),`image/png`)});if(o)return o;let s=r.toDataURL(`image/png`);return(await fetch(s)).blob()}finally{URL.revokeObjectURL(i)}}function hc(e){let t=document.createElement(`iframe`);t.setAttribute(`aria-hidden`,`true`),t.style.cssText=`position:fixed;right:0;bottom:0;width:0;height:0;border:0`,document.body.appendChild(t);let n=t.contentDocument;if(!n)throw Error(`iframe contentDocument unavailable`);n.open(),n.write(e),n.close();try{t.contentWindow?.focus(),t.contentWindow?.print()}catch{let t=window.open(``,`_blank`,`noopener,noreferrer`);t&&(t.document.open(),t.document.write(e),t.document.close())}setTimeout(()=>t.remove(),1e3)}function gc(e){Z({panel:e.panel,template_id:e.template_id,options:e.options,format:e.options.format,destination:e.destination}).catch(()=>{})}function _c(e){return e===`light`?`#ffffff`:`#0f172a`}function vc(e,t){return`cctally-${e}-${new Date().toISOString().slice(0,10).replaceAll(`-`,``)}.${sc(t)}`}function yc(e){switch(e){case`md`:return`text/markdown;charset=utf-8`;case`html`:return`text/html;charset=utf-8`;case`svg`:return`image/svg+xml;charset=utf-8`}}function bc(e,t){let n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=e,r.style.display=`none`,document.body.appendChild(r),r.click(),document.body.removeChild(r),setTimeout(()=>URL.revokeObjectURL(n),0)}function xc({panel:e,templateId:t,options:n,onOptionsChange:r}){let[i,a]=(0,g.useState)(null),[o,s]=(0,g.useState)(null),[c,l]=(0,g.useState)(!1),u=(0,g.useRef)(null);(0,g.useEffect)(()=>()=>{u.current!=null&&clearTimeout(u.current)},[]);let[d,f]=(0,g.useState)(!1),p=(0,g.useRef)(null);(0,g.useEffect)(()=>{if(!d)return;function e(e){let t=p.current;t&&(t.contains(e.target)||f(!1))}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[d]),(0,g.useEffect)(()=>{s(null)},[n.format,t]);let m=t==null||i!=null,h=e=>R({type:`SHOW_STATUS_TOAST`,text:e}),_=async()=>{if(!t)throw Error(`no template selected`);return{body:(await Zs({panel:e,template_id:t,options:n})).body,format:n.format}},v=async()=>{if(!(m||!t)){a(`copy`),s(null);try{let{body:r}=await _();if(!navigator.clipboard||typeof navigator.clipboard.writeText!=`function`)throw Error(`Clipboard API unavailable in this browser`);await navigator.clipboard.writeText(r),h(`Copied`),gc({panel:e,template_id:t,options:n,destination:`copy`})}catch(e){s(`Copy failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},y=async()=>{if(!(m||!t)){a(`download`),s(null);try{let{body:r,format:i}=await _(),a=new Blob([r],{type:yc(i)});bc(vc(e,i),a),h(`Downloaded`),gc({panel:e,template_id:t,options:n,destination:`download`})}catch(e){s(`Download failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},b=async()=>{if(!(m||!t)){a(`basket`),s(null);try{let r=await Zs({panel:e,template_id:t,options:n}),i=xe({panel:e,template_id:t,options:n,added_at:new Date().toISOString(),data_digest_at_add:r.snapshot.data_digest,kernel_version:r.snapshot.kernel_version,label_hint:oc(e)});R({type:`BASKET_ADD`,item:i});let a=I().basket;if(a.rejectedReason===`capacity`)return;l(!0),u.current!=null&&clearTimeout(u.current),u.current=setTimeout(()=>l(!1),800),R({type:`SHOW_STATUS_TOAST`,text:`Added ${i.label_hint} to basket (${a.items.length})`})}catch(e){s(`Add to basket failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},x=async()=>{if(!(m||!t)){a(`open`),s(null);try{let{body:r,format:i}=await _(),a=new Blob([r],{type:yc(i)}),o=URL.createObjectURL(a);window.open(o,`_blank`,`noopener,noreferrer`),gc({panel:e,template_id:t,options:n,destination:`open`})}catch(e){s(`Open failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},S=async()=>{if(!(!t||n.format!==`svg`||m)){a(`png`),s(null);try{let{body:r}=await _(),i=await mc(r,2,_c(n.theme));bc(vc(e,`svg`).replace(/\.svg$/,`.png`),i),h(`PNG downloaded`),gc({panel:e,template_id:t,options:n,destination:`png`})}catch(e){s(`PNG export failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},C=async()=>{if(!(!t||n.format!==`html`||m)){a(`print`),s(null);try{let{body:r}=await _();hc(r),gc({panel:e,template_id:t,options:n,destination:`print`})}catch(e){s(`Print failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},w=n.format===`md`&&!m,T=(n.format===`html`||n.format===`svg`)&&!m,ee=n.format===`svg`&&!m,te=n.format===`html`&&!m;return(0,z.jsxs)(`div`,{className:`share-actions`,children:[(0,z.jsxs)(`div`,{className:`share-format-row`,role:`radiogroup`,"aria-label":`Export format`,children:[(0,z.jsx)(`span`,{className:`share-format-label`,children:`Format:`}),[`md`,`html`,`svg`].map(e=>(0,z.jsxs)(`label`,{className:`share-format-radio`,children:[(0,z.jsx)(`input`,{type:`radio`,name:`share-format`,value:e,checked:n.format===e,onChange:()=>r({...n,format:e})}),(0,z.jsx)(`span`,{children:e})]},e))]}),(0,z.jsxs)(`div`,{className:`share-action-row`,children:[(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-copy`,onClick:v,disabled:!w,title:n.format===`md`?i===`copy`?`Copying…`:`Copy to clipboard`:`Copy is available for Markdown only`,children:i===`copy`?`Copying…`:`Copy`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-download`,onClick:y,disabled:m,title:i===`download`?`Downloading…`:`Download file`,children:i===`download`?`Downloading…`:`Download`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-open`,onClick:x,disabled:!T,title:n.format===`html`||n.format===`svg`?i===`open`?`Opening…`:`Open in new tab`:`Open is available for HTML/SVG`,children:i===`open`?`Opening…`:`Open`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-png`,onClick:S,disabled:!ee,title:n.format===`svg`?i===`png`?`Rasterizing…`:`Download PNG (rasterized from SVG)`:`PNG export — available for SVG format only`,children:i===`png`?`Rasterizing…`:`PNG`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-print`,onClick:C,disabled:!te,title:n.format===`html`?i===`print`?`Opening print dialog…`:`Open the browser print dialog (save as PDF)`:`Print → PDF — available for HTML format only`,children:i===`print`?`Printing…`:`Print → PDF`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-basket${c?` share-action-basket-added`:``}`,onClick:b,disabled:m,title:m&&t==null?`Pick a template first`:i===`basket`?`Adding to basket…`:`Add this section to the report basket`,children:c?`✓ Added`:i===`basket`?`Adding…`:`+ Basket`})]}),(0,z.jsxs)(`div`,{className:`share-save-preset-row`,ref:p,children:[(0,z.jsx)(`button`,{type:`button`,className:`share-save-preset`,disabled:t==null||i!=null,onClick:()=>f(e=>!e),"aria-haspopup":`dialog`,"aria-expanded":d,title:t==null?`Pick a template first`:`Save the current recipe as a named preset`,children:`Save preset…`}),d&&t?(0,z.jsx)(pc,{panel:e,templateId:t,options:n,onSaved:()=>f(!1),onCancel:()=>f(!1)}):null]}),o?(0,z.jsx)(`div`,{className:`share-action-error`,role:`alert`,children:o}):null]})}function Sc(e){let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString()}function Cc({panel:e,onPick:t,onManage:n}){let[r,i]=(0,g.useState)(!1),[a,o]=(0,g.useState)({}),[s,c]=(0,g.useState)([]),[l,u]=(0,g.useState)(null),d=(0,g.useRef)(null);(0,g.useEffect)(()=>{if(!r)return;let t=new AbortController;return u(null),Promise.all([lc({signal:t.signal}),fc({signal:t.signal})]).then(([t,n])=>{o(t.presets[e]??{}),c(n.history.filter(t=>t.panel===e).slice().reverse())}).catch(e=>{e?.name!==`AbortError`&&u((e instanceof X?e.message??`HTTP ${e.status}`:e.message)??`Failed to load presets`)}),()=>t.abort()},[r,e]),(0,g.useEffect)(()=>{if(!r)return;function e(e){let t=d.current;t&&(t.contains(e.target)||i(!1))}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[r]);let f=Object.keys(a).sort();return(0,z.jsxs)(`div`,{className:`share-presets-dropdown`,ref:d,children:[(0,z.jsx)(`button`,{type:`button`,className:`share-presets-trigger`,"aria-haspopup":`menu`,"aria-expanded":r,onClick:()=>i(e=>!e),children:`presets ▾`}),r?(0,z.jsxs)(`div`,{className:`share-presets-menu`,role:`menu`,children:[l?(0,z.jsx)(`div`,{className:`share-presets-error`,role:`alert`,children:l}):null,f.length===0&&!l?(0,z.jsx)(`div`,{className:`share-presets-empty`,children:`No saved presets yet.`}):null,f.length>0?(0,z.jsx)(`ul`,{className:`share-presets-list`,children:f.map(e=>(0,z.jsx)(`li`,{children:(0,z.jsx)(`button`,{type:`button`,role:`menuitem`,className:`share-presets-item`,onClick:()=>{t(a[e].template_id,a[e].options),i(!1)},children:e})},e))}):null,s.length>0?(0,z.jsxs)(`div`,{className:`share-presets-history`,children:[(0,z.jsx)(`div`,{className:`share-presets-history-heading`,role:`presentation`,children:`Recent shares`}),(0,z.jsx)(`ul`,{className:`share-presets-history-list`,children:s.map(e=>(0,z.jsx)(`li`,{children:(0,z.jsxs)(`button`,{type:`button`,role:`menuitem`,className:`share-presets-history-item`,onClick:()=>{t(e.template_id,e.options),i(!1)},title:`${e.template_id} · ${e.format??`unknown`} · ${e.exported_at}`,children:[(0,z.jsx)(`span`,{className:`share-presets-history-template`,children:e.template_id}),(0,z.jsxs)(`span`,{className:`share-presets-history-meta`,children:[` · `,e.format??`unknown`,` · `,Sc(e.exported_at)]})]})},e.recipe_id))})]}):null,(0,z.jsx)(`div`,{className:`share-presets-footer`,children:(0,z.jsx)(`button`,{type:`button`,role:`menuitem`,className:`share-presets-manage`,onClick:()=>{n(),i(!1)},children:`Manage presets…`})})]}):null]})}var wc=`share-manage-presets-title`;function Tc({open:e,onClose:t}){let[n,r]=(0,g.useState)([]),[i,a]=(0,g.useState)(!1),[o,s]=(0,g.useState)(null);V((0,g.useMemo)(()=>e?[{key:`Escape`,scope:`modal`,action:t}]:[],[e,t]));let c=(0,g.useRef)(null),l=(0,g.useRef)(!1);(0,g.useEffect)(()=>{if(e)l.current||(l.current=!0,c.current=document.activeElement);else if(l.current){l.current=!1;let e=c.current;if(c.current=null,e&&typeof e.focus==`function`&&document.contains(e))e.focus();else{let e=document.activeElement;e&&typeof e.blur==`function`&&e.blur(),document.body.focus()}}},[e]),(0,g.useEffect)(()=>{if(!e)return;let t=!1;return s(null),(async()=>{try{let e=await lc();if(t)return;let n=[];for(let[t,r]of Object.entries(e.presets))for(let[e,i]of Object.entries(r))n.push({panel:t,name:e,record:i});n.sort((e,t)=>e.panel===t.panel?e.name.localeCompare(t.name):e.panel.localeCompare(t.panel)),r(n)}catch(e){if(t)return;s((e instanceof X?e.message??`HTTP ${e.status}`:e.message)??`Failed to load presets`)}})(),()=>{t=!0}},[e]);async function u(e){a(!0),s(null);try{await dc(e.panel,e.name),r(t=>t.filter(t=>!(t.panel===e.panel&&t.name===e.name))),R({type:`SHOW_STATUS_TOAST`,text:`Deleted preset "${e.name}"`})}catch(e){s((e instanceof X?e.message??`HTTP ${e.status}`:e.message)??`Delete failed`)}finally{a(!1)}}async function d(e,t){a(!0),s(null);try{await uc({panel:e.panel,name:t,template_id:e.record.template_id,options:e.record.options}),await dc(e.panel,e.name),r(n=>n.map(n=>n.panel===e.panel&&n.name===e.name?{...n,name:t}:n)),R({type:`SHOW_STATUS_TOAST`,text:`Renamed to "${t}"`})}catch(e){s((e instanceof X?e.message??`HTTP ${e.status}`:e.message)??`Rename failed`)}finally{a(!1)}}return e?(0,z.jsxs)(`div`,{className:`share-manage-modal`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":wc,onClick:e=>e.stopPropagation(),children:[(0,z.jsxs)(`div`,{className:`share-manage-header`,children:[(0,z.jsx)(`h2`,{id:wc,children:`Manage presets`}),(0,z.jsx)(`button`,{type:`button`,onClick:t,"aria-label":`Close`,className:`share-manage-close`,children:`⤬`})]}),o?(0,z.jsx)(`div`,{className:`share-manage-error`,role:`alert`,children:o}):null,n.length===0&&!o?(0,z.jsx)(`p`,{className:`share-manage-empty`,children:`No saved presets yet.`}):null,n.length>0?(0,z.jsxs)(`table`,{className:`share-manage-table`,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{children:`Panel`}),(0,z.jsx)(`th`,{children:`Name`}),(0,z.jsx)(`th`,{children:`Saved at`}),(0,z.jsx)(`th`,{})]})}),(0,z.jsx)(`tbody`,{children:n.map(e=>(0,z.jsx)(Ec,{row:e,busy:i,onDelete:()=>void u(e),onRename:t=>void d(e,t)},`${e.panel}/${e.name}`))})]}):null]}):null}function Ec({row:e,busy:t,onDelete:n,onRename:r}){let[i,a]=(0,g.useState)(!1),[o,s]=(0,g.useState)(e.name),c=()=>{let t=o.trim();if(!t||t===e.name){s(e.name),a(!1);return}r(t),a(!1)};return(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`td`,{children:oc(e.panel)}),(0,z.jsx)(`td`,{children:i?(0,z.jsx)(`input`,{className:`share-manage-name-input`,autoFocus:!0,value:o,disabled:t,maxLength:64,onChange:e=>s(e.target.value),onKeyDown:t=>{t.key===`Enter`?(t.preventDefault(),c()):t.key===`Escape`&&(t.preventDefault(),t.stopPropagation(),s(e.name),a(!1))}}):(0,z.jsx)(`span`,{children:e.name})}),(0,z.jsx)(`td`,{children:e.record.saved_at}),(0,z.jsxs)(`td`,{className:`share-manage-actions`,children:[(0,z.jsx)(`button`,{type:`button`,disabled:t,onClick:()=>{i?(s(e.name),a(!1)):a(!0)},children:i?`Cancel`:`Rename`}),(0,z.jsx)(`button`,{type:`button`,disabled:t,onClick:n,children:`Delete`})]})]})}function Dc(){return{format:`md`,theme:`light`,reveal_projects:!1,no_branding:!1,top_n:5,period:{kind:`current`},project_allowlist:null,show_chart:!0,show_table:!0}}function Oc(e,t){if(!t)return e;let n={...e,...t};return t.period&&(n.period={...e.period,...t.period}),n}function kc({panel:e,onClose:t,initialParams:n}){let r=oc(e),[i,a]=(0,g.useState)(null),[o,s]=(0,g.useState)(null),[c,l]=(0,g.useState)(null),[u,d]=(0,g.useState)(()=>{let e=Dc();return n?.windowWeeks==null?e:{...e,windowWeeks:n.windowWeeks}}),f=(0,g.useRef)(!1),[p,m]=(0,g.useState)(!1),h=`share-modal-title`;V((0,g.useMemo)(()=>[{key:`Escape`,scope:`overlay`,when:()=>!p&&I().composerModal===null,action:t}],[t,p])),(0,g.useEffect)(()=>{let t=!1;return a(null),s(null),Xs(e).then(e=>{if(t)return;a(e.templates);let n=e.templates[0];n&&(l(n.id),f.current||d(e=>Oc(e,n.default_options)))}).catch(e=>{t||s(e instanceof X?`Couldn't load templates: ${e.message??`HTTP ${e.status}`}`:`Couldn't load templates: ${e.message}`)}),()=>{t=!0}},[e]),(0,g.useEffect)(()=>{if(!i||!c||f.current)return;let e=i.find(e=>e.id===c);e&&d(t=>Oc(t,e.default_options))},[c,i]);let _=e=>{f.current=!0,d(e)};return(0,z.jsxs)(`div`,{className:`share-modal`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":h,onClick:e=>e.stopPropagation(),children:[(0,z.jsx)(`header`,{className:`share-modal-header`,children:(0,z.jsxs)(`h2`,{id:h,children:[`Share `,r,` report`]})}),(0,z.jsxs)(`div`,{className:`share-modal-body`,children:[(0,z.jsxs)(`section`,{className:`share-section share-gallery-section`,"aria-label":`Template gallery`,children:[(0,z.jsx)(`div`,{className:`share-gallery-header`,children:(0,z.jsx)(Cc,{panel:e,onPick:(e,t)=>{l(e),f.current=!0,d(e=>({...e,...t}))},onManage:()=>m(!0)})}),(0,z.jsx)(ec,{panel:e,templates:i,error:o,selectedTemplateId:c,onSelect:e=>l(e)})]}),(0,z.jsxs)(`section`,{className:`share-section share-main-section`,children:[(0,z.jsx)(`div`,{className:`share-knobs-col`,"aria-label":`Render options`,children:(0,z.jsx)(tc,{options:u,onChange:_})}),(0,z.jsx)(`div`,{className:`share-preview-col`,"aria-label":`Live preview`,children:(0,z.jsx)(ic,{panel:e,templateId:c,options:u})})]})]}),(0,z.jsx)(`footer`,{className:`share-modal-footer`,children:(0,z.jsx)(xc,{panel:e,templateId:c,options:u,onOptionsChange:_})}),(0,z.jsx)(`button`,{type:`button`,className:`share-modal-close`,"aria-label":`Close share modal`,onClick:t,children:`⤬`}),(0,z.jsx)(Tc,{open:p,onClose:()=>m(!1)})]})}function Ac(e,t){return{title:t.title,theme:t.theme,format:t.format,no_branding:t.no_branding,reveal_projects:t.reveal_projects,sections:e.map(e=>({snapshot:{panel:e.panel,template_id:e.template_id,options:e.options,data_digest_at_add:e.data_digest_at_add,kernel_version:e.kernel_version}}))}}async function jc(e,t){let n=await fetch(`/api/share/compose`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),signal:t?.signal});if(!n.ok){let e={};try{e=await n.json()}catch{}throw new X(n.status,e.field,e.error??`HTTP ${n.status}`,e.code)}return n.json()}function Mc({items:e,results:t,kernelVersion:n,onRefresh:r,onRemove:i,onPreviewOnly:a}){let o=jr(Ar(ji,{activationConstraint:{distance:4}}),Ar(Ei,{coordinateGetter:eo}));function s(t){if(!t.over||t.active.id===t.over.id)return;let n=e.findIndex(e=>e.id===t.active.id),r=e.findIndex(e=>e.id===t.over.id);n<0||r<0||R({type:`BASKET_REORDER`,fromIdx:n,toIdx:r})}return(0,z.jsx)(Ta,{sensors:o,collisionDetection:zr,onDragEnd:s,children:(0,z.jsx)(Ha,{items:e.map(e=>e.id),strategy:za,children:(0,z.jsx)(`ul`,{className:`composer-section-list`,children:e.map((e,o)=>(0,z.jsx)(Nc,{item:e,result:t[o],kernelVersion:n,onRefresh:r,onRemove:i,onPreviewOnly:a},e.id))})})})}function Nc({item:e,result:t,kernelVersion:n,onRefresh:r,onRemove:i,onPreviewOnly:a}){let{attributes:o,listeners:s,setNodeRef:c,transform:l,transition:u,isDragging:d}=Xa({id:e.id}),f=so(),p={transform:gr.Transform.toString(l),transition:f?void 0:u,opacity:d?.4:1},[m,h]=(0,g.useState)(!1),_=t?.drift_detected,v=e.kernel_version!==n,y=!!(_||v);return(0,z.jsxs)(`li`,{ref:c,style:p,className:`composer-section-row`,children:[(0,z.jsx)(`button`,{className:`composer-drag-handle`,"aria-label":`Reorder ${e.label_hint}`,type:`button`,...o,...s,children:`≡`}),(0,z.jsx)(`span`,{className:`composer-section-label`,children:e.label_hint}),y?(0,z.jsx)(`span`,{className:`composer-outdated-badge`,title:_&&v?`Data and kernel both shifted since add-time. Refresh to update.`:_?`Data has changed since this section was added. Refresh to update.`:`Kernel updated since this section was added. Refresh to re-render at the new version.`,children:`Outdated`}):null,(0,z.jsxs)(`div`,{className:`composer-section-actions`,children:[(0,z.jsx)(`button`,{type:`button`,"aria-haspopup":`menu`,"aria-expanded":m,onClick:()=>h(e=>!e),"aria-label":`Actions for ${e.label_hint}`,children:`⋯`}),m?(0,z.jsxs)(`ul`,{role:`menu`,className:`composer-section-menu`,children:[(0,z.jsx)(`li`,{children:(0,z.jsx)(`button`,{type:`button`,onClick:()=>{a(e.id),h(!1)},children:`Preview only this`})}),(0,z.jsx)(`li`,{children:(0,z.jsx)(`button`,{type:`button`,onClick:()=>{r(e.id),h(!1)},children:`Refresh from current data`})}),(0,z.jsx)(`li`,{children:(0,z.jsx)(`button`,{type:`button`,onClick:()=>{i(e.id),h(!1)},"aria-label":`Remove ${e.label_hint}`,children:`Remove`})})]}):null]})]})}function Pc(e,t){return t&&e>0}function Fc(e){return`cctally-report-${new Date().toISOString().slice(0,10).replaceAll(`-`,``)}.${e===`md`?`md`:e}`}function Ic(e){switch(e){case`md`:return`text/markdown;charset=utf-8`;case`html`:return`text/html;charset=utf-8`;case`svg`:return`image/svg+xml;charset=utf-8`}}function Lc(e){return e===`light`?`#ffffff`:`#0f172a`}function Rc(e,t){let n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=e,r.style.display=`none`,document.body.appendChild(r),r.click(),document.body.removeChild(r),setTimeout(()=>URL.revokeObjectURL(n),0)}var zc=200;function Bc(){return I().composerModal}function Vc(){return I().basket}var Q=`composer-modal-title`;function Hc(){let e=(0,g.useSyncExternalStore)(L,Bc),t=(0,g.useSyncExternalStore)(L,Vc),n=on(),r=(0,g.useRef)(null),i=(0,g.useRef)(!1),[a,o]=(0,g.useState)(``),[s,c]=(0,g.useState)(`light`),[l,u]=(0,g.useState)(`html`),[d,f]=(0,g.useState)(!0),[p,m]=(0,g.useState)(!1),[h,_]=(0,g.useState)(null),[v,y]=(0,g.useState)(null),[b,x]=(0,g.useState)(!1),S=(0,g.useRef)(null),[C,w]=(0,g.useState)(null),[T,ee]=(0,g.useState)(null);(0,g.useEffect)(()=>{ee(null)},[l,s,d,p]),V((0,g.useMemo)(()=>[{key:`Escape`,scope:`overlay`,when:()=>I().composerModal!==null,action:()=>R(ve())}],[])),(0,g.useEffect)(()=>{e?.open&&a===``&&o(`cctally report — ${new Date().toISOString().slice(0,10)}`)},[e?.open,a]),(0,g.useEffect)(()=>{if(e?.open)i.current||(i.current=!0,r.current=document.activeElement);else if(i.current){i.current=!1;let e=r.current;if(r.current=null,e&&typeof e.focus==`function`&&document.contains(e))e.focus();else{let e=document.activeElement;e&&typeof e.blur==`function`&&e.blur(),document.body.focus()}}},[e?.open]),(0,g.useEffect)(()=>{if(!e?.open||t.items.length===0||a===``)return;let n=setTimeout(()=>{S.current?.abort();let e=new AbortController;S.current=e,x(!0),y(null),jc(Ac(t.items,{title:a,theme:s,format:l,no_branding:p,reveal_projects:!d}),{signal:e.signal}).then(t=>{e.signal.aborted||_(t)}).catch(t=>{t?.name!==`AbortError`&&(e.signal.aborted||y(t instanceof X?t.message??`HTTP ${t.status}`:t.message))}).finally(()=>{e.signal.aborted||x(!1)})},zc);return()=>clearTimeout(n)},[e?.open,t.items,a,s,l,d,p]);async function te(e){let n=t.items.findIndex(t=>t.id===e);if(n<0)return;let r=t.items[n];try{let t=await Zs({panel:r.panel,template_id:r.template_id,options:{...r.options,reveal_projects:!d}}),i=xe({panel:r.panel,template_id:r.template_id,options:r.options,added_at:new Date().toISOString(),data_digest_at_add:t.snapshot.data_digest,kernel_version:t.snapshot.kernel_version,label_hint:r.label_hint,id:r.id});R({type:`BASKET_REMOVE`,id:e}),R({type:`BASKET_ADD`,item:i});let a=I().basket.items.length-1;a!==n&&R({type:`BASKET_REORDER`,fromIdx:a,toIdx:n})}catch(e){y(`Refresh failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}}let E=async e=>{let n=await jc(Ac(t.items,{title:a,theme:s,format:e,no_branding:p,reveal_projects:!d}));return{body:n.body,content_type:n.content_type}},D=e=>R({type:`SHOW_STATUS_TOAST`,text:e}),O=async(e,t,n)=>{if(C==null){w(e),ee(null);try{await t()}catch(e){ee(`${n} failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{w(null)}}},ne=()=>O(`copy`,async()=>{let{body:e}=await E(`md`);if(!navigator.clipboard||typeof navigator.clipboard.writeText!=`function`)throw Error(`Clipboard API unavailable in this browser`);await navigator.clipboard.writeText(e),D(`Copied`)},`Copy`),k=()=>O(`download`,async()=>{let{body:e}=await E(l),t=new Blob([e],{type:Ic(l)});Rc(Fc(l),t),D(`Downloaded`)},`Download`),re=()=>O(`open`,async()=>{let{body:e}=await E(l),t=new Blob([e],{type:Ic(l)}),n=URL.createObjectURL(t);window.open(n,`_blank`,`noopener,noreferrer`)},`Open`),A=()=>O(`png`,async()=>{let{body:e}=await E(`svg`),t=await mc(e,2,Lc(s));Rc(Fc(`svg`).replace(/\.svg$/,`.png`),t),D(`PNG downloaded`)},`PNG export`),ie=()=>O(`print`,async()=>{let{body:e}=await E(`html`);hc(e)},`Print`),ae=C==null&&l===`md`&&t.items.length>0,oe=C==null&&t.items.length>0,se=C==null&&(l===`html`||l===`svg`)&&t.items.length>0,j=C==null&&l===`svg`&&t.items.length>0,ce=C==null&&l===`html`&&t.items.length>0,le=!d,ue=Pc(t.items.length,le),de=le?t.items.length:0;return e?.open?t.items.length===0?(0,z.jsxs)(`div`,{className:`composer-modal composer-modal-empty${n?` composer-modal-mobile`:``}`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":Q,children:[(0,z.jsxs)(`header`,{className:`composer-modal-header`,children:[(0,z.jsx)(`h2`,{id:Q,children:`Compose report`}),(0,z.jsx)(`button`,{type:`button`,className:`composer-modal-close`,onClick:()=>R(ve()),"aria-label":`Close`,children:`⤬`})]}),(0,z.jsx)(`p`,{className:`composer-empty-message`,children:`Basket is empty. Open any panel's share menu and pick + Basket to add a section.`})]}):(0,z.jsxs)(`div`,{className:`composer-modal${n?` composer-modal-mobile`:``}`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":Q,children:[(0,z.jsxs)(`header`,{className:`composer-modal-header`,children:[(0,z.jsx)(`h2`,{id:Q,children:`Compose report`}),(0,z.jsx)(`button`,{type:`button`,className:`composer-modal-close`,onClick:()=>R(ve()),"aria-label":`Close`,children:`⤬`})]}),(0,z.jsxs)(`div`,{className:`composer-knobs`,children:[(0,z.jsxs)(`label`,{children:[`Title`,(0,z.jsx)(`input`,{type:`text`,value:a,onChange:e=>o(e.target.value)})]}),(0,z.jsxs)(`label`,{children:[`Theme`,(0,z.jsxs)(`select`,{value:s,onChange:e=>c(e.target.value),children:[(0,z.jsx)(`option`,{value:`light`,children:`light`}),(0,z.jsx)(`option`,{value:`dark`,children:`dark`})]})]}),(0,z.jsxs)(`label`,{children:[`Format`,(0,z.jsxs)(`select`,{value:l,onChange:e=>u(e.target.value),children:[(0,z.jsx)(`option`,{value:`html`,children:`html`}),(0,z.jsx)(`option`,{value:`md`,children:`md`}),(0,z.jsx)(`option`,{value:`svg`,children:`svg`})]})]}),(0,z.jsxs)(`label`,{children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:d,onChange:e=>f(e.target.checked)}),`Anon on export`]}),(0,z.jsxs)(`label`,{children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:p,onChange:e=>m(e.target.checked)}),`No branding`]})]}),ue?(0,z.jsxs)(`div`,{className:`composer-anon-banner`,role:`status`,"aria-live":`polite`,children:[(0,z.jsxs)(`span`,{children:[de,` section`,de===1?``:`s`,` contain real project names. They will appear in the export.`]}),(0,z.jsx)(`button`,{type:`button`,onClick:()=>f(!0),children:`Anonymize all`})]}):null,(0,z.jsxs)(`div`,{className:`composer-body`,children:[(0,z.jsx)(Mc,{items:t.items,results:h?.snapshot.section_results??[],kernelVersion:h?.snapshot.kernel_version??1,onRefresh:e=>{te(e)},onRemove:e=>R({type:`BASKET_REMOVE`,id:e}),onPreviewOnly:e=>{}}),(0,z.jsx)(`iframe`,{className:`composer-preview`,title:`Combined preview`,tabIndex:-1,sandbox:`allow-same-origin`,srcDoc:h?.body??`<p>Composing&hellip;</p>`})]}),b?(0,z.jsx)(`div`,{className:`composer-busy`,children:`Composing…`}):null,v?(0,z.jsx)(`div`,{className:`composer-error`,role:`alert`,children:v}):null,T?(0,z.jsx)(`div`,{className:`composer-error`,role:`alert`,children:T}):null,(0,z.jsxs)(`footer`,{className:`composer-actions`,children:[(0,z.jsxs)(`div`,{className:`composer-export-row`,children:[(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-copy`,onClick:ne,disabled:!ae,title:l===`md`?C===`copy`?`Copying…`:`Copy composed report to clipboard`:`Copy is available for Markdown only`,children:C===`copy`?`Copying…`:`Copy`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-download`,onClick:k,disabled:!oe,title:C===`download`?`Downloading…`:`Download composed report`,children:C===`download`?`Downloading…`:`Download`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-open`,onClick:re,disabled:!se,title:l===`html`||l===`svg`?C===`open`?`Opening…`:`Open composed report in new tab`:`Open is available for HTML/SVG`,children:C===`open`?`Opening…`:`Open`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-png`,onClick:A,disabled:!j,title:l===`svg`?C===`png`?`Rasterizing…`:`Download composed report as PNG`:`PNG export — available for SVG format only`,children:C===`png`?`Rasterizing…`:`PNG`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-print`,onClick:ie,disabled:!ce,title:l===`html`?C===`print`?`Opening print dialog…`:`Open the browser print dialog (save as PDF)`:`Print → PDF — available for HTML format only`,children:C===`print`?`Printing…`:`Print → PDF`})]}),(0,z.jsx)(`button`,{type:`button`,className:`composer-clear-all`,onClick:()=>R({type:`BASKET_CLEAR`}),children:`Clear all`})]})]}):null}function Uc(){let e=(0,g.useSyncExternalStore)(L,()=>I().shareModal),t=(0,g.useRef)(null),n=(0,g.useRef)(!1);(0,g.useEffect)(()=>{if(e)n.current||(n.current=!0,t.current=(e.triggerId?document.getElementById(e.triggerId):null)??document.activeElement);else if(n.current){n.current=!1;let e=t.current;if(t.current=null,e&&typeof e.focus==`function`&&document.contains(e))e.focus();else{let e=document.activeElement;e&&typeof e.blur==`function`&&e.blur(),document.body.focus()}}},[e]);let r=()=>R(ge());return(0,z.jsxs)(z.Fragment,{children:[e?(0,z.jsx)(`div`,{id:`share-modal-root`,className:`share-overlay`,onClick:e=>{e.stopPropagation(),e.target===e.currentTarget&&r()},children:(0,z.jsx)(kc,{panel:e.panel,initialParams:e.params,onClose:r})}):null,(0,z.jsx)(Hc,{})]})}function Wc(){let e=(0,g.useSyncExternalStore)(L,()=>I().prefs.panelOrder);return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(Ot,{}),(0,z.jsx)(ho,{items:e,children:(0,z.jsx)(`div`,{className:`grid`,children:e.map((e,t)=>(0,z.jsx)(co,{id:e,index:t},e))})}),(0,z.jsx)(Pt,{}),(0,z.jsx)(Mn,{}),(0,z.jsx)(In,{}),(0,z.jsx)(Js,{}),(0,z.jsx)(Uc,{}),(0,z.jsx)(Fo,{}),(0,z.jsx)(_o,{}),(0,z.jsx)(Un,{})]})}function Gc(e){let t=I().prefs.panelOrder,n=e-1;if(n<0||n>=t.length)return;let r=kn[t[n]];r&&r.openAction()}var Kc=`Click a panel first, then press S to share it.`;function qc(){return typeof window>`u`||!window.matchMedia?!1:window.matchMedia(an).matches}function Jc(){if(typeof document>`u`)return null;let e=document.activeElement;if(!e||!(e instanceof Element))return null;let t=e.closest(`[data-panel-kind]`);return t?t.getAttribute(`data-panel-kind`):null}function Yc(){return{key:`S`,scope:`global`,when:()=>{let e=I();return!(qc()||e.shareModal!==null||e.composerModal!==null||e.openModal!==null||e.update.modalOpen||e.inputMode!==null)},action:()=>{let e=Jc();if(e===null){R({type:`SHOW_STATUS_TOAST`,text:Kc});return}if(!j.has(e))return;let t=e;R(N(t,`${t}-panel`))}}}function Xc(){return typeof window>`u`||!window.matchMedia?!1:window.matchMedia(an).matches}function Zc(){return{key:`B`,scope:`global`,when:()=>{let e=I();return!(Xc()||e.shareModal!==null||e.composerModal!==null||e.openModal!==null||e.update.modalOpen||e.inputMode!==null)},action:()=>R(_e())}}function Qc(){return[Zc()]}mt(),nt(),Bt();var $=()=>{let e=I();return!e.update.modalOpen&&!e.doctorModalOpen};zt([{key:`1`,scope:`global`,when:$,action:()=>Gc(1)},{key:`2`,scope:`global`,when:$,action:()=>Gc(2)},{key:`3`,scope:`global`,when:$,action:()=>Gc(3)},{key:`4`,scope:`global`,when:$,action:()=>Gc(4)},{key:`5`,scope:`global`,when:$,action:()=>Gc(5)},{key:`6`,scope:`global`,when:$,action:()=>Gc(6)},{key:`7`,scope:`global`,when:$,action:()=>Gc(7)},{key:`8`,scope:`global`,when:$,action:()=>Gc(8)},{key:`9`,scope:`global`,when:$,action:()=>Gc(9)},{key:`0`,scope:`global`,when:$,action:()=>Gc(10)},{key:`r`,scope:`global`,when:$,action:()=>Et()},{key:`q`,scope:`global`,when:$,action:Nt},{key:`n`,scope:`global`,when:$,action:()=>jt(1)},{key:`N`,scope:`global`,when:$,action:()=>jt(-1)},{key:`d`,scope:`global`,when:()=>{let e=I();return!(e.openModal!==null||e.update.modalOpen||e.inputMode!==null)},action:()=>R({type:`OPEN_DOCTOR_MODAL`})},Yc(),...Qc(),{key:`c`,scope:`sessions`,when:()=>!I().openModal,action:()=>{let e=I().prefs.sessionsCollapsed;R({type:`SAVE_PREFS`,patch:{sessionsCollapsed:!e}})}}]);var $c=document.getElementById(`root`);if(!$c)throw Error(`missing #root`);(0,_.createRoot)($c).render((0,z.jsx)(g.StrictMode,{children:(0,z.jsx)(Wc,{})}));
18
+ `]},t))})]}):(0,z.jsx)(`p`,{className:`update-manual-note`,children:e.errorMessage??`See ~/.local/share/cctally/update.log for the full failure log.`}),(0,z.jsxs)(`p`,{className:`update-stream-cap`,children:[`Full log: `,(0,z.jsx)(`code`,{children:`~/.local/share/cctally/update.log`})]}),(0,z.jsxs)(`div`,{className:`update-actions`,children:[(0,z.jsx)(`button`,{type:`button`,className:`update-btn update-btn-primary`,onClick:o,children:`Retry`}),(0,z.jsx)(`button`,{type:`button`,className:`update-btn`,onClick:s,disabled:!r,children:t===`ok`?`Copied!`:t===`err`?`Copy failed`:`Copy command`}),(0,z.jsx)(`button`,{type:`button`,className:`update-btn`,onClick:()=>ot.close(),children:`Close`})]})]})}var No={idle:`Update available`,running:`Updating cctally`,success:`Update complete`,failed:`Update failed`},Po={idle:`accent-amber`,running:`accent-amber`,success:`accent-green`,failed:`accent-red`};function Fo(){let e=(0,g.useSyncExternalStore)(L,()=>I().update),t=()=>R({type:`CLOSE_UPDATE_MODAL`});if(V((0,g.useMemo)(()=>[{key:`Escape`,scope:`modal`,action:t,when:()=>I().update.modalOpen}],[])),!e.modalOpen||!e.state)return null;let n=e.status,r=Po[n]??`accent-amber`,i=No[n]??`Update`;n===`running`&&e.state.latest_version?i=`Updating cctally → ${e.state.latest_version}`:n===`success`&&e.state.latest_version&&(i=`Update complete → ${e.state.latest_version}`);let a;switch(n){case`running`:a=(0,z.jsx)(Eo,{});break;case`success`:a=(0,z.jsx)(ko,{});break;case`failed`:a=(0,z.jsx)(Mo,{});break;default:a=(0,z.jsx)(So,{});break}return(0,z.jsxs)(`div`,{id:`update-modal-root`,className:`update-modal-root`,children:[(0,z.jsx)(`div`,{className:`modal-backdrop`,onClick:t}),(0,z.jsxs)(`div`,{className:`modal-card update-modal-card ${r}`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`update-modal-title`,children:[(0,z.jsx)(`div`,{className:`modal-handle`,"aria-hidden":`true`}),(0,z.jsxs)(`header`,{className:`modal-header`,children:[(0,z.jsx)(`h2`,{id:`update-modal-title`,children:i}),(0,z.jsx)(`button`,{className:`modal-close`,"aria-label":`Close`,onClick:t,children:`×`})]}),(0,z.jsx)(`div`,{className:`modal-body`,children:a})]})]})}function Io({title:e,accentClass:t,children:n,headerExtras:r}){let i=()=>R({type:`CLOSE_MODAL`});return V((0,g.useMemo)(()=>[{key:`Escape`,scope:`modal`,action:i}],[])),(0,z.jsxs)(`div`,{id:`modal-root`,children:[(0,z.jsx)(`div`,{className:`modal-backdrop`,onClick:i}),(0,z.jsxs)(`div`,{className:`modal-card ${t}`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`modal-title`,children:[(0,z.jsx)(`div`,{className:`modal-handle`,"aria-hidden":`true`}),(0,z.jsxs)(`header`,{className:`modal-header`,children:[(0,z.jsx)(`h2`,{id:`modal-title`,children:e}),r,(0,z.jsx)(`button`,{className:`modal-close`,"aria-label":`Close`,onClick:i,children:`×`})]}),(0,z.jsx)(`div`,{id:`modal-body`,className:`modal-body`,children:n})]})]})}function Lo(e){return e==null||!isFinite(e)?0:Math.max(0,Math.min(100,e))}function Ro(e,t,n){let r=D.dateShort(t,n);return e&&r?`${e} → ${r}`:e||(r?`→ ${r}`:`—`)}function zo(e){if(e==null||!isFinite(e))return[`—`,``];let t=(+e).toFixed(1),n=t.indexOf(`.`);return n===-1?[t,`.0%`]:[t.slice(0,n),t.slice(n)+`%`]}function Bo(e){let t=[],n=[...e].sort((e,t)=>(e.percent??0)-(t.percent??0));for(let e of n)e.percent!=null&&(t.length&&e.percent-(t[t.length-1].percent??0)<3||t.push(e));return t}function Vo(e){if(!Array.isArray(e)||e.length<2)return null;let t=e.map(e=>e.marginal_usd).filter(e=>e!=null&&isFinite(e)),n=t.length?t.reduce((e,t)=>e+t,0)/t.length:null,r=e[e.length-1].percent,i=[];return n!=null&&i.push(`avg marginal $`+n.toFixed(2)),r!=null&&i.push(`latest at `+r+`%`),i.length?i.join(` · `):null}function Ho(e,t){let n=[];for(let t of e)n.push({kind:`milestone`,ts:t.captured_at_utc,data:t});for(let e of t)n.push({kind:`credit`,ts:e.effective_reset_at_utc,data:e});return n.sort((e,t)=>e.ts.localeCompare(t.ts)),n}function Uo(){let e=Ke(),t=Ht(),n={tz:t.resolvedTz,offsetLabel:t.offsetLabel},r=e?.current_week??null,i=e?.header??null,a=Array.isArray(r?.milestones)?r.milestones:[],o=Array.isArray(r?.five_hour_milestones)?r.five_hour_milestones:[],s=Ho(o,Array.isArray(r?.five_hour_block?.credits)?r.five_hour_block.credits:[]),c=Lo(r?.used_pct),[l,u]=zo(r?.used_pct),d=r?Ro(i?.week_label,r.reset_at_utc,n):`—`,f=Bo(a),p=Vo(a);return(0,z.jsx)(Io,{title:`Current Week — per-percent milestones`,accentClass:`accent-green`,headerExtras:(0,z.jsx)(Gt,{panel:`current-week`,panelLabel:`Current week`,triggerId:`current-week-modal`,onClick:()=>R(N(`current-week`,`current-week-modal`))}),children:(0,z.jsxs)(`section`,{className:`modal-current-week`,children:[(0,z.jsx)(`div`,{className:`m-chipstrip`,id:`mcw-badges`,children:(0,z.jsx)(`span`,{className:`m-pill accent-green`,id:`mcw-week-pill`,children:d})}),(0,z.jsxs)(`div`,{className:`mcw-herobar`,children:[(0,z.jsxs)(`div`,{className:`mcw-bignum`,id:`mcw-bignum`,children:[(0,z.jsx)(`span`,{className:`int`,children:l}),(0,z.jsx)(`span`,{className:`unit`,children:u})]}),(0,z.jsxs)(`div`,{className:`mcw-pbar-wrap`,children:[(0,z.jsxs)(`div`,{className:`mcw-pbar`,children:[(0,z.jsx)(`div`,{className:`fill`,id:`mcw-fill`,style:{width:c+`%`}}),(0,z.jsx)(`div`,{className:`ticks`,id:`mcw-ticks`,children:f.map(e=>(0,z.jsx)(`div`,{className:`tick`,"data-p":String(e.percent),style:{left:Lo(e.percent)+`%`}},e.percent))}),(0,z.jsx)(`div`,{className:`marker`,id:`mcw-marker`,style:{left:c+`%`}})]}),(0,z.jsxs)(`div`,{className:`mcw-pscale`,children:[(0,z.jsx)(`span`,{children:`0%`}),(0,z.jsx)(`span`,{children:`25%`}),(0,z.jsx)(`span`,{children:`50%`}),(0,z.jsx)(`span`,{children:`75%`}),(0,z.jsx)(`span`,{children:`100%`})]})]}),(0,z.jsxs)(`div`,{className:`mcw-mini`,id:`mcw-mini`,children:[(0,z.jsxs)(`div`,{className:`s`,children:[(0,z.jsx)(`span`,{className:`k`,children:`spent`}),(0,z.jsx)(`span`,{className:`v v-magenta`,id:`mcw-spent`,children:D.usd2(r?.spent_usd)})]}),(0,z.jsxs)(`div`,{className:`s`,children:[(0,z.jsx)(`span`,{className:`k`,children:`$ / 1%`}),(0,z.jsx)(`span`,{className:`v v-cyan`,id:`mcw-dpp`,children:D.usd3(r?.dollar_per_pct)})]}),(0,z.jsxs)(`div`,{className:`s`,children:[(0,z.jsx)(`span`,{className:`k`,children:`reset`}),(0,z.jsx)(`span`,{className:`v`,id:`mcw-reset`,children:D.datetimeShortZ(r?.reset_at_utc,n)})]})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-ms`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#hash`})}),`Milestones`]}),(0,z.jsxs)(`div`,{className:`mcw-mshead`,children:[(0,z.jsxs)(`span`,{className:`m-pill accent-purple`,id:`mcw-ms-count`,children:[a.length,` crossed`]}),(0,z.jsx)(`span`,{className:`mcw-ms-sub`,id:`mcw-ms-sub`,hidden:!p,children:p??``})]}),a.length===0?(0,z.jsx)(`p`,{className:`empty-state`,id:`mcw-empty`,children:`No milestones yet — earliest crosses at 1\xA0%.`}):(0,z.jsxs)(`table`,{className:`m-histable`,id:`mcw-table`,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{children:`%`}),(0,z.jsxs)(`th`,{children:[`Crossed (`,t.offsetLabel,`)`]}),(0,z.jsx)(`th`,{className:`num`,children:`Cumulative $`}),(0,z.jsx)(`th`,{className:`num`,children:`Marginal $`}),(0,z.jsx)(`th`,{className:`num`,children:`5h %`})]})}),(0,z.jsx)(`tbody`,{id:`mcw-rows`,children:a.map(e=>(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`td`,{children:(0,z.jsx)(`span`,{className:`m-pill accent-purple pct-cell`,children:e.percent??`—`})}),(0,z.jsx)(`td`,{className:`d`,children:D.startedShort(e.crossed_at_utc,n,{noSuffix:!0})}),(0,z.jsx)(`td`,{className:`num`,children:e.cumulative_usd==null?`—`:`$`+e.cumulative_usd.toFixed(2)}),(0,z.jsx)(`td`,{className:`num`,children:(0,z.jsx)(`span`,{className:`m-marginal`,children:e.marginal_usd==null?`—`:`$`+e.marginal_usd.toFixed(2)})}),(0,z.jsx)(`td`,{className:`num`,children:(0,z.jsx)(`span`,{className:`m-fh`,children:e.five_hour_pct_at_cross==null?`—`:Math.round(e.five_hour_pct_at_cross)+`%`})})]},e.percent))})]}),s.length>0&&(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-ms sec-5h`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#activity`})}),`5h milestones`]}),(0,z.jsx)(`div`,{className:`mcw-mshead`,children:(0,z.jsxs)(`span`,{className:`m-pill accent-purple`,id:`mcw-5h-count`,children:[o.length,` crossed`]})}),(0,z.jsxs)(`table`,{className:`m-histable mcw-5h-table`,id:`mcw-5h-table`,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{children:`%`}),(0,z.jsxs)(`th`,{children:[`When (`,t.offsetLabel,`)`]}),(0,z.jsx)(`th`,{className:`num`,children:`Block $`}),(0,z.jsx)(`th`,{className:`num`,children:`Marginal $`}),(0,z.jsx)(`th`,{className:`num`,children:`7d %`})]})}),(0,z.jsx)(`tbody`,{children:s.map((e,t)=>{if(e.kind===`credit`)return(0,z.jsx)(`tr`,{className:`mcw-5h-credit-row`,children:(0,z.jsxs)(`td`,{colSpan:5,className:`mcw-5h-credit-cell`,children:[`⚡ CREDIT\xA0`,` `,e.data.delta_pp>0?`+`:``,e.data.delta_pp.toFixed(0),`pp\xA0@`,` `,D.startedShort(e.ts,n,{noSuffix:!0})]})},`credit-${t}-${e.ts}`);let r=e.data;return(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`td`,{children:(0,z.jsx)(`span`,{className:`m-pill accent-purple pct-cell`,children:r.percent_threshold})}),(0,z.jsx)(`td`,{className:`d`,children:D.startedShort(r.captured_at_utc,n,{noSuffix:!0})}),(0,z.jsx)(`td`,{className:`num`,children:`$`+r.block_cost_usd.toFixed(2)}),(0,z.jsx)(`td`,{className:`num`,children:(0,z.jsx)(`span`,{className:`m-marginal`,children:r.marginal_cost_usd==null?`—`:`$`+r.marginal_cost_usd.toFixed(2)})}),(0,z.jsx)(`td`,{className:`num`,children:(0,z.jsx)(`span`,{className:`m-fh`,children:r.seven_day_pct_at_crossing==null?`—`:Math.round(r.seven_day_pct_at_crossing)+`%`})})]},`fhms-${r.percent_threshold}-${r.reset_event_id}`)})})]})]})]})})}function Wo(e){if(!e)return`—`;let t=e.elapsed_hours,n=e.remaining_hours;if(t==null||n==null)return`—`;let r=t+n;if(r<=0)return`—`;let i=t/r*100;return Math.min(100,i).toFixed(1)+`%`}function Go(e){return e==null||!isFinite(e)?null:e<0?0:e>110?110:e}function Ko(e){return e==null||!isFinite(e)?`—`:e<0?`~`+(+e).toFixed(1)+`%`:(+e).toFixed(1)+`%`}function qo(e,t){for(let t of e)t.trueXPct=t.pos/110*100;if(e.length<2||t<=0){for(let t of e)t.resolvedXPct=t.trueXPct;return}let n=e.slice().sort((e,t)=>e.trueXPct-t.trueXPct),r=n[0],i=n[1],a=r.pillWidthPx/2/t*100,o=i.pillWidthPx/2/t*100,s=8/t*100,c=a+o+s,l=2*c;if(i.trueXPct-r.trueXPct<c){let e=(r.trueXPct+i.trueXPct)/2;r.resolvedXPct=e-l/2,i.resolvedXPct=e+l/2;let t=a,n=100-o;r.resolvedXPct<t&&(r.resolvedXPct=t,i.resolvedXPct-r.resolvedXPct<l&&(i.resolvedXPct=Math.min(n,r.resolvedXPct+l))),i.resolvedXPct>n&&(i.resolvedXPct=n,i.resolvedXPct-r.resolvedXPct<l&&(r.resolvedXPct=Math.max(t,i.resolvedXPct-l)))}else r.resolvedXPct=r.trueXPct,i.resolvedXPct=i.trueXPct}function Jo(e,t,n){(0,g.useEffect)(()=>{let r=e.current,i=t.current;if(!r||!i||!n)return;let a=r.querySelector(`.mfc-pills`),o=r.querySelector(`.mfc-leaders`),s=i.querySelector(`.mfc-rangeband`);if(!a||!o)return;let c=n.week_avg_projection_pct,l=n.recent_24h_projection_pct,u=Go(c),d=Go(l),f=[];u!=null&&c!=null&&f.push({kind:`wa`,pos:u,raw:c}),d!=null&&l!=null&&f.push({kind:`r24`,pos:d,raw:l});let p=new Set(f.map(e=>e.kind));i.querySelectorAll(`.mfc-chev`).forEach(e=>{let t=e.dataset.kind;(!t||!p.has(t))&&e.remove()}),a.querySelectorAll(`.mfc-pill`).forEach(e=>{let t=e.dataset.kind;(!t||!p.has(t))&&e.remove()});let m=f.map(e=>({...e,trueXPct:0,resolvedXPct:0,pillWidthPx:0}));for(let e of m){let t=e.pos/110*100,n=i.querySelector(`.mfc-chev[data-kind="${e.kind}"]`);n||(n=document.createElement(`div`),n.className=`mfc-chev `+e.kind,n.dataset.kind=e.kind,i.appendChild(n)),n.style.left=t+`%`;let r=a.querySelector(`.mfc-pill[data-kind="${e.kind}"]`),o=Ko(e.raw);r?r.textContent!==o&&(r.textContent=o):(r=document.createElement(`div`),r.className=`mfc-pill `+e.kind,r.dataset.kind=e.kind,r.textContent=o,a.appendChild(r)),e.pillEl=r}if(s){let e=!1;if(m.length===2){let t=m[0].pos/110*100,n=m[1].pos/110*100,r=Math.min(t,n),i=Math.max(t,n)-r;i>=.5&&(s.style.left=r+`%`,s.style.width=i+`%`,e=!0)}s.hidden=!e}let h=()=>{for(let e of m)if(!e.pillEl||!e.pillEl.isConnected)return;let e=r.clientWidth;if(e<=0){requestAnimationFrame(h);return}for(let e of m)e.pillWidthPx=e.pillEl.getBoundingClientRect().width;qo(m,e);for(let e of m)e.pillEl.style.left=e.resolvedXPct+`%`;for(;o.firstChild;)o.removeChild(o.firstChild);for(let e of m){let t=document.createElementNS(`http://www.w3.org/2000/svg`,`path`);t.setAttribute(`class`,e.kind),t.setAttribute(`vector-effect`,`non-scaling-stroke`),t.setAttribute(`d`,`M ${e.resolvedXPct} 0 C ${e.resolvedXPct} 10, ${e.trueXPct} 8, ${e.trueXPct} 18`),o.appendChild(t)}};h()},[e,t,n])}function Yo(){let e=Ke()?.forecast??null,t=e?.explain??null,n=(0,g.useRef)(null),r=(0,g.useRef)(null);Jo(n,r,e);let i=(0,z.jsx)(Gt,{panel:`forecast`,panelLabel:`Forecast`,triggerId:`forecast-modal`,onClick:()=>R(N(`forecast`,`forecast-modal`))});if(!e)return(0,z.jsx)(Io,{title:`Forecast — explain`,accentClass:`accent-purple`,headerExtras:i,children:(0,z.jsx)(`section`,{className:`modal-forecast`,children:(0,z.jsx)(`p`,{className:`empty-state`,id:`mfc-empty`,children:`No forecast data yet.`})})});let a=St(e.verdict),o=a?`m-pill ${a.accent}`:`m-pill`,s=a?`${a.glyph} ${a.label}`:`—`,c=`m-pill`,l=`—`,u=!0;e.confidence===`high`?(c=`m-pill accent-blue`,l=`high confidence`,u=!1):e.confidence===`low`&&(c=`m-pill accent-red`,l=`low confidence`,u=!1);let d=t?.rates,f=t?.week;return(0,z.jsx)(Io,{title:`Forecast — explain`,accentClass:`accent-purple`,headerExtras:i,children:(0,z.jsxs)(`section`,{className:`modal-forecast`,children:[(0,z.jsxs)(`div`,{className:`m-chipstrip`,id:`mfc-chips`,children:[(0,z.jsx)(`span`,{className:o,id:`mfc-verdict`,children:s}),(0,z.jsx)(`span`,{className:c,id:`mfc-confidence`,hidden:u,children:l})]}),(0,z.jsxs)(`div`,{className:`m-hero cols-2`,children:[(0,z.jsxs)(`div`,{className:`m-kv kv-wa`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#gauge`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`mfc-wa-pct`,children:D.pct1(e.week_avg_projection_pct)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Week-avg projection`}),(0,z.jsx)(`div`,{className:`sub`,id:`mfc-wa-sub`,children:D.ratePctPerHour(d?.week_average_pct_per_hour)})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-r24`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#zap`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`mfc-r24-pct`,children:D.pct1(e.recent_24h_projection_pct)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Recent-24h projection`}),(0,z.jsx)(`div`,{className:`sub`,id:`mfc-r24-sub`,children:D.ratePctPerHour(d?.recent_24h_pct_per_hour)})]})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-range`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#bar-chart`})}),`Range vs. caps`]}),(0,z.jsxs)(`div`,{className:`mfc-rangewrap`,id:`mfc-rangewrap`,ref:n,children:[(0,z.jsx)(`div`,{className:`mfc-pills`,id:`mfc-pills`}),(0,z.jsx)(`svg`,{className:`mfc-leaders`,id:`mfc-leaders`,viewBox:`0 0 100 18`,preserveAspectRatio:`none`,"aria-hidden":`true`}),(0,z.jsxs)(`div`,{className:`mfc-rangetrack`,id:`mfc-rangetrack`,ref:r,children:[(0,z.jsx)(`div`,{className:`mfc-zone safe`}),(0,z.jsx)(`div`,{className:`mfc-zone warn`}),(0,z.jsx)(`div`,{className:`mfc-zone over`}),(0,z.jsx)(`div`,{className:`mfc-rangeband`,id:`mfc-rangeband`,hidden:!0}),(0,z.jsx)(`div`,{className:`mfc-bound b90`,children:(0,z.jsx)(`div`,{className:`lbl`,children:`90%`})}),(0,z.jsx)(`div`,{className:`mfc-bound b100`,children:(0,z.jsx)(`div`,{className:`lbl`,children:`100%`})})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-rates`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#activity`})}),`Rates`]}),(0,z.jsxs)(`div`,{className:`mfc-kvgrid`,children:[(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`$ / 1%`}),(0,z.jsx)(`span`,{className:`v v-cyan`,id:`mfc-dpp`,children:D.usd3(d?.dollars_per_percent)})]}),(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`week done`}),(0,z.jsx)(`span`,{className:`v v-green`,id:`mfc-wkdone`,children:Wo(f)})]}),(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`elapsed`}),(0,z.jsx)(`span`,{className:`v v-green`,id:`mfc-elapsed`,children:D.hours1(f?.elapsed_hours)})]}),(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`remaining`}),(0,z.jsx)(`span`,{className:`v`,id:`mfc-remain`,children:D.hours1(f?.remaining_hours)})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-bud`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#dollar`})}),`Daily budgets to stay under`]}),(0,z.jsxs)(`div`,{className:`mfc-kvgrid mfc-kvgrid-single`,children:[(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`@ 100% cap`}),(0,z.jsx)(`span`,{className:`v v-magenta`,id:`mfc-bud100`,children:D.usd2PerDay(e.budget_100_per_day_usd)})]}),(0,z.jsxs)(`div`,{className:`mfc-krow`,children:[(0,z.jsx)(`span`,{className:`l`,children:`@ 90% cap`}),(0,z.jsx)(`span`,{className:`v v-amber`,id:`mfc-bud90`,children:D.usd2PerDay(e.budget_90_per_day_usd)})]})]})]})})}function Xo(e){let t=Math.max(1,Math.round(e/4));return`${e} week${e===1?``:`s`} · ${t} month${t===1?``:`s`}`}function Zo(e){let t=e.findIndex(e=>e&&e.is_current);return t>=0?t:e.length-1}function Qo(e,t){let n=e.filter((e,n)=>n!==t).map(e=>e.dollar_per_pct).filter(e=>e!=null&&isFinite(e));if(n.length<4)return null;let r=n.slice(-4).sort((e,t)=>e-t);return(r[1]+r[2])/2}function $o(e){if(!e.length)return null;let t=[...e].sort((e,t)=>e-t),n=Math.floor(t.length/2);return t.length%2?t[n]:(t[n-1]+t[n])/2}function es(e,t){let n=[];if(!e.length)return n;let r={left:44,right:14,top:12,bottom:22},i=600-r.left-r.right,a=140-r.top-r.bottom,o=e.length,s=e=>r.left+(o===1?i:e/(o-1)*i),c=e.map(e=>e.dollar_per_pct).filter(e=>e!=null&&isFinite(e)),l=c.length?Math.min(...c)*.96:0,u=c.length?Math.max(...c)*1.04:1;u-l<1e-6&&(l-=.01,u+=.01);let d=e=>r.top+a*(1-(e-l)/(u-l)),f=e.map(e=>e.used_pct).filter(e=>e!=null&&isFinite(e)),p=f.length?Math.min(...f)*.96:0,m=f.length?Math.max(...f)*1.04:100;m-p<1e-6&&(--p,m+=1);let h=e=>r.top+a*(1-(e-p)/(m-p));if(n.push({el:`line`,attrs:{class:`mtr-axis`,x1:r.left,y1:r.top+a,x2:600-r.right,y2:r.top+a},key:`axis`}),c.length){let e=$o(c);e!=null&&(n.push({el:`line`,attrs:{class:`mtr-hl`,x1:r.left,y1:d(e),x2:600-r.right,y2:d(e)},key:`med-line`}),n.push({el:`text`,attrs:{class:`mtr-medlabel`,x:r.left+2,y:d(e)-3},text:`median $`+e.toFixed(2),key:`med-label`}))}{let t=[];e.forEach((e,n)=>{e.used_pct!=null&&isFinite(e.used_pct)&&t.push(`${s(n)},${h(e.used_pct)}`)}),t.length>=2&&n.push({el:`polyline`,attrs:{class:`mtr-trendline-dim`,points:t.join(` `)},key:`poly-used`})}{let t=[];e.forEach((e,n)=>{e.dollar_per_pct!=null&&isFinite(e.dollar_per_pct)&&t.push(`${s(n)},${d(e.dollar_per_pct)}`)}),t.length>=2&&n.push({el:`polyline`,attrs:{class:`mtr-trendline`,points:t.join(` `)},key:`poly-dpp`})}e.forEach((e,r)=>{if(e.dollar_per_pct==null||!isFinite(e.dollar_per_pct))return;let i=r===t;n.push({el:`circle`,attrs:{class:`mtr-trenddot`+(i?` cur`:``),cx:s(r),cy:d(e.dollar_per_pct),r:i?5:3},key:`dot-${r}`})}),c.length&&(n.push({el:`text`,attrs:{class:`mtr-ylabel`,x:3,y:r.top+8},text:`$`+(u/1.04).toFixed(2),key:`ymax`}),n.push({el:`text`,attrs:{class:`mtr-ylabel`,x:3,y:r.top+a},text:`$`+(l/.96).toFixed(2),key:`ymin`}));let g=e[t];return g&&g.dollar_per_pct!=null&&isFinite(g.dollar_per_pct)&&n.push({el:`text`,attrs:{class:`mtr-curlabel`,x:Math.max(r.left+4,s(t)-22),y:Math.min(138,d(g.dollar_per_pct)+16)},text:`$`+g.dollar_per_pct.toFixed(2),key:`curlabel`}),n}function ts(e,t){return t===0?`Now`+(e.label?` · `+e.label:``):`W−`+t+(e.label?` · `+e.label:``)}function ns(e){return e==null||!isFinite(e)?{cls:`flat`,text:`—`}:e>5e-4?{cls:`up`,text:`+`+e.toFixed(2)}:e<-5e-4?{cls:`down`,text:e.toFixed(2)}:{cls:`flat`,text:`0.00`}}function rs(e){return e==null||!isFinite(e)?{cls:`delta-flat`,iconHref:`/static/icons.svg#minus`,text:`—`}:e<-5e-4?{cls:`delta-down`,iconHref:`/static/icons.svg#trending-down`,text:`−$`+Math.abs(e).toFixed(3)}:e>5e-4?{cls:`delta-up`,iconHref:`/static/icons.svg#trending-up`,text:`+$`+e.toFixed(3)}:{cls:`delta-flat`,iconHref:`/static/icons.svg#minus`,text:`$0.000`}}function is(){let e=Ke(),t=oe(e),n=(0,z.jsx)(Gt,{panel:`trend`,panelLabel:`Trend`,triggerId:`trend-modal`,onClick:()=>R(N(`trend`,`trend-modal`))});if(!t.length)return(0,z.jsx)(Io,{title:`Trend — 12-week history`,accentClass:`accent-amber`,headerExtras:n,children:(0,z.jsx)(`section`,{className:`modal-trend`,children:(0,z.jsx)(`p`,{className:`empty-state`,id:`mtr-empty`,children:`No history data yet.`})})});let r=Zo(t),i=t[r],a=e?.trend?.history_median_dpp,o=a!=null&&isFinite(a)?a:Qo(t,r),s=rs(i&&i.dollar_per_pct!=null&&o!=null?i.dollar_per_pct-o:null),c=es(t,r),l=t.some(e=>e.used_pct!=null&&isFinite(e.used_pct)),u=t.length;return(0,z.jsx)(Io,{title:`Trend — 12-week history`,accentClass:`accent-amber`,headerExtras:n,children:(0,z.jsxs)(`section`,{className:`modal-trend`,children:[(0,z.jsx)(`div`,{className:`m-chipstrip`,children:(0,z.jsx)(`span`,{className:`m-pill accent-amber`,id:`mtr-weeks-pill`,children:Xo(u)})}),(0,z.jsxs)(`div`,{className:`m-hero cols-3`,children:[(0,z.jsxs)(`div`,{className:`m-kv kv-cur`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#dollar`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`mtr-cur`,children:i&&i.dollar_per_pct!=null?`$`+i.dollar_per_pct.toFixed(3):`—`}),(0,z.jsx)(`div`,{className:`lbl`,children:`Current $ / 1%`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-med`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#minus`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`mtr-med`,children:o==null?`—`:`$`+o.toFixed(3)}),(0,z.jsx)(`div`,{className:`lbl`,children:`4-week median`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-delta ${s.cls}`,id:`mtr-delta-kv`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:s.iconHref})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`mtr-delta`,children:s.text}),(0,z.jsx)(`div`,{className:`lbl`,children:`vs median`})]})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-spark`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#trending-down`})}),`12-week history · $/1%`,(0,z.jsxs)(`span`,{className:`mtr-legend`+(l?``:` legend-no-used`),"aria-hidden":`true`,children:[(0,z.jsx)(`span`,{className:`sw sw-dpp`}),(0,z.jsx)(`span`,{className:`sw-lbl`,children:`$/1%`}),(0,z.jsx)(`span`,{className:`sw sw-used`}),(0,z.jsx)(`span`,{className:`sw-lbl`,children:`used %`})]})]}),(0,z.jsxs)(`div`,{className:`mtr-sparkhero`,children:[(0,z.jsx)(`svg`,{id:`mtr-svg`,viewBox:`0 0 600 140`,preserveAspectRatio:`none`,"aria-hidden":`true`,children:c.map(e=>{let{el:t,attrs:n,text:r,key:i}=e,a={};for(let e in n)a[e===`class`?`className`:e]=n[e];return t===`line`?(0,z.jsx)(`line`,{...a},i):t===`polyline`?(0,z.jsx)(`polyline`,{...a},i):t===`circle`?(0,z.jsx)(`circle`,{...a},i):(0,z.jsx)(`text`,{...a,children:r},i)})}),(0,z.jsx)(`div`,{className:`mtr-sparkaxis`,id:`mtr-sparkaxis`,children:u>0?(0,z.jsxs)(g.Fragment,{children:[(0,z.jsxs)(`span`,{children:[`W−`,u-1]}),(0,z.jsxs)(`span`,{children:[`W−`,Math.floor((u-1)/2)]}),(0,z.jsx)(`span`,{children:`Now`})]}):null})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-tbl`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#hash`})}),`Weekly detail`]}),(0,z.jsxs)(`div`,{className:`mtr-tbl-head`,children:[(0,z.jsxs)(`span`,{className:`m-pill accent-purple`,id:`mtr-tbl-count`,children:[u,` weeks`]}),(0,z.jsx)(`span`,{className:`mtr-tbl-sub`,children:`current row highlighted · negative Δ = $/1% down vs prior week`})]}),(0,z.jsxs)(`table`,{className:`m-histable`,id:`mtr-table`,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{children:`Week`}),(0,z.jsx)(`th`,{className:`num`,children:`Used %`}),(0,z.jsx)(`th`,{className:`num`,children:`$ / 1%`}),(0,z.jsx)(`th`,{className:`num`,children:`Δ $/1%`})]})}),(0,z.jsx)(`tbody`,{id:`mtr-rows`,children:t.map((e,t)=>{let n=ts(e,u-1-t),r=e.used_pct==null?`—`:Math.round(e.used_pct)+`%`,i=e.dollar_per_pct==null?`—`:`$`+e.dollar_per_pct.toFixed(2),a=ns(e.delta);return(0,z.jsxs)(`tr`,{className:e.is_current?`cur`:void 0,children:[(0,z.jsx)(`td`,{children:(0,z.jsx)(`span`,{className:`wlab`,children:n})}),(0,z.jsx)(`td`,{className:`num usedpct`,children:r}),(0,z.jsx)(`td`,{className:`num dpp`,children:i}),(0,z.jsx)(`td`,{className:`num delta ${a.cls}`,children:a.text})]},e.label+`|`+t)})})]})]})})}var as=/(^|\/)(subagents\/|agent-)/;function os(){return(0,g.useSyncExternalStore)(L,()=>I().snapshot?.generated_at??``)}function ss(){let e=(0,g.useSyncExternalStore)(L,()=>I().openSessionId),t=os(),[n,r]=(0,g.useState)(null),[i,a]=(0,g.useState)(!0),[o,s]=(0,g.useState)(null),c=(0,g.useRef)(null),l=(0,g.useRef)(!1),u=(0,g.useRef)(null);return(0,g.useEffect)(()=>{u.current=e??I().snapshot?.sessions?.rows?.[0]?.session_id??null,l.current=!1},[e]),(0,g.useEffect)(()=>{let e=u.current;if(!e){a(!1),s(`No session available.`),r(null),c.current=null;return}let t=c.current!==e||n==null;c.current=e,t&&(a(!0),s(null),r(null));let i=new AbortController;return fetch(`/api/session/${encodeURIComponent(e)}`,{signal:i.signal}).then(async e=>{if(e.status===404){(t||l.current)&&(a(!1),s(`Session not found (the cache may have rolled forward).`),r(null)),l.current=!0;return}if(!e.ok)throw Error(`HTTP `+e.status);let n=await e.json();l.current=!1,r(n),s(null),a(!1)}).catch(e=>{e.name!==`AbortError`&&(l.current=!1,t&&(s(`Failed to load: `+e.message),a(!1)))}),()=>i.abort()},[e,t]),(0,z.jsx)(Io,{title:`Session detail`,accentClass:`accent-orange`,headerExtras:(0,z.jsx)(Gt,{panel:`sessions`,panelLabel:`Session`,triggerId:`session-modal`,onClick:()=>R(N(`sessions`,`session-modal`))}),children:(0,z.jsxs)(`section`,{className:`modal-sessions`,children:[i?(0,z.jsx)(`div`,{className:`modal-loading`,id:`msess-loading`,children:`Loading session detail…`}):null,o?(0,z.jsx)(`div`,{className:`modal-error`,id:`msess-error`,children:o}):null,!i&&!o&&n?(0,z.jsx)(cs,{detail:n}):null]})})}function cs({detail:e}){let t=Array.isArray(e.source_paths)?e.source_paths:[],n=[],r=[];t.forEach(e=>{as.test(e)?r.push(e):n.push(e)});let i=e.cost_total_usd??0,a=[[`Input`,e.input_tokens,null],[`Output`,e.output_tokens,null],[`Cache creation`,e.cache_creation_tokens,null],[`Cache read`,e.cache_read_tokens,null],[`Cache hit %`,e.cache_hit_pct,`cache-hit`]].filter(e=>e[1]!=null),o=!e.models||e.models.length===0,s=!e.cost_per_model||e.cost_per_model.length===0;return(0,z.jsxs)(`div`,{className:`modal-content`,id:`msess-content`,children:[(0,z.jsx)(`div`,{className:`m-chipstrip`,children:(0,z.jsx)(`span`,{className:`msess-badge`,id:`msess-id`,"aria-label":`Session ID`,children:e.session_id??`—`})}),(0,z.jsxs)(`div`,{className:`m-hero cols-3`,children:[(0,z.jsxs)(`div`,{className:`m-kv kv-cost`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#dollar`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`msess-cost`,children:e.cost_total_usd==null?`—`:`$`+e.cost_total_usd.toFixed(2)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Total cost`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-dur`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#clock`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`msess-dur`,children:e.duration_min==null?`—`:e.duration_min+` min`}),(0,z.jsx)(`div`,{className:`lbl`,children:`Duration`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-proj`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#folder`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,id:`msess-project`,title:e.project_path??``,"aria-label":`Project`,children:e.project_label??e.project_path??`—`}),(0,z.jsx)(`div`,{className:`lbl`,children:`Project`})]})]})]}),(0,z.jsxs)(`div`,{className:`msess-ts`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#calendar`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`span`,{className:`k`,children:`started`}),(0,z.jsx)(`span`,{className:`v`,id:`msess-started`,children:e.started_utc??`—`})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`span`,{className:`k`,children:`last activity`}),(0,z.jsx)(`span`,{className:`v`,id:`msess-last`,children:e.last_activity_utc??`—`})]})]}),(0,z.jsxs)(`h3`,{className:`m-sec sec-tok`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#hash`})}),`Tokens`]}),(0,z.jsx)(`div`,{className:`msess-tok-grid`,id:`msess-tokens`,children:a.map(([e,t,n])=>(0,z.jsxs)(`div`,{className:`msess-tok-tile`+(n?` `+n:``),children:[(0,z.jsx)(`div`,{className:`lbl`,children:e}),(0,z.jsx)(`div`,{className:`n`,children:n===`cache-hit`?t.toFixed(1)+`%`:t.toLocaleString(`en-US`)}),n===`cache-hit`?(0,z.jsx)(`div`,{className:`bar`,children:(0,z.jsx)(`div`,{className:`fill`,style:{width:Math.max(0,Math.min(t,100))+`%`}})}):null]},e))}),o?null:(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-mod`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#sparkles`})}),`Models`]}),(0,z.jsx)(`div`,{className:`m-chipstrip`,id:`msess-models`,children:(e.models||[]).map(e=>(0,z.jsx)(`span`,{className:`chip `+ln(e.name),children:e.name},e.name))})]}),s?null:(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-costm`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#pie-chart`})}),`Cost by model`]}),(0,z.jsxs)(`div`,{className:`msess-costm`,children:[(0,z.jsx)(`div`,{className:`bar`,id:`msess-cost-bar`,children:(e.cost_per_model||[]).map(e=>{let t=i>0&&e.cost_usd!=null?e.cost_usd/i*100:0;return(0,z.jsx)(`div`,{className:`seg `+ln(e.model),style:{width:t+`%`}},e.model)})}),(0,z.jsx)(`div`,{className:`legend`,id:`msess-cost-legend`,children:(e.cost_per_model||[]).map(e=>{let t=i>0&&e.cost_usd!=null?e.cost_usd/i*100:0;return(0,z.jsxs)(`div`,{className:`lg`,children:[(0,z.jsx)(`span`,{className:`sw `+ln(e.model)}),(0,z.jsx)(`span`,{className:`name`,children:e.model}),(0,z.jsx)(`span`,{className:`v`,children:e.cost_usd==null?`—`:`$`+e.cost_usd.toFixed(3)}),(0,z.jsxs)(`span`,{className:`pct`,children:[Math.round(t),`%`]})]},e.model)})})]})]}),t.length>0?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-src`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#file-text`})}),`Source files`]}),(0,z.jsxs)(`div`,{className:`msess-src`,id:`msess-src`,children:[(0,z.jsxs)(`div`,{className:`src-head`,children:[(0,z.jsxs)(`span`,{className:`count-pill`,children:[t.length,` file`,t.length===1?``:`s`]}),(0,z.jsxs)(`span`,{className:`sub`,children:[n.length,` primary`,r.length>0?(0,z.jsxs)(z.Fragment,{children:[` `,(0,z.jsx)(`span`,{className:`dot`,children:`·`}),` `,(0,z.jsxs)(`span`,{className:`subcount`,children:[r.length,` subagent`,r.length===1?``:`s`]})]}):null]})]}),n.length>0?n.map(e=>(0,z.jsx)(`div`,{className:`primary-path`,children:e},e)):r.length>0?(0,z.jsxs)(`div`,{className:`src-empty-primary`,children:[`No primary path resolved · `,r.length,` subagent path`,r.length===1?``:`s`,` below`]}):null,r.length>0?(0,z.jsxs)(`details`,{className:`subagents`,open:n.length===0,children:[(0,z.jsxs)(`summary`,{children:[`Show `,r.length,` subagent path`,r.length===1?``:`s`]}),(0,z.jsx)(`ul`,{className:`paths`,children:r.map(e=>(0,z.jsx)(`li`,{children:e},e))})]}):null]})]}):null]})}function ls({row:e,variant:t,accentClass:n}){let r=Ht(),i={tz:r.resolvedTz,offsetLabel:r.offsetLabel},a=(e,t)=>`${D.datetimeShort(e,i)} → ${D.datetimeShort(t,i)}`,o=e.delta_cost_pct==null?`flat`:e.delta_cost_pct>0?`up`:e.delta_cost_pct<0?`down`:`flat`,s=t===`weekly`?`week`:t===`monthly`?`month`:`day`,c=t===`daily`?`Today`:`Now`;return(0,z.jsxs)(`div`,{className:`detail-card ${n}`,children:[(0,z.jsxs)(`div`,{className:`head`,children:[(0,z.jsxs)(`div`,{className:`big`,children:[e.label,e.is_current&&(0,z.jsx)(`span`,{className:`pill-current`,children:c})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`span`,{className:`cost`,style:{color:`var(--text)`,fontWeight:700},children:D.usd2(e.cost_usd)}),` `,e.delta_cost_pct==null?(0,z.jsx)(`span`,{className:`delta flat`,children:`—`}):(0,z.jsxs)(`span`,{className:`delta ${o}`,children:[D.deltaPct(e.delta_cost_pct),` vs prior `,s]})]})]}),t===`weekly`&&e.week_start_at&&e.week_end_at&&(0,z.jsxs)(`div`,{className:`window`,children:[`Subscription window: `,a(e.week_start_at,e.week_end_at)]}),(0,z.jsx)(`div`,{className:`model-stack`,role:`presentation`,children:e.models.map(e=>(0,z.jsx)(`span`,{className:e.chip,style:{width:`${e.cost_pct}%`}},e.model))}),(0,z.jsx)(`div`,{className:`chips`,children:e.models.map(e=>(0,z.jsxs)(`span`,{className:`chip ${e.chip}`,children:[e.display,` `,Math.round(e.cost_pct),`% · `,D.usd2(e.cost_usd)]},e.model))}),(0,z.jsxs)(`div`,{className:`tokens-row`,children:[(0,z.jsxs)(`div`,{className:`t`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Input`}),(0,z.jsx)(`span`,{className:`v`,children:D.compact(e.input_tokens)})]}),(0,z.jsxs)(`div`,{className:`t`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Output`}),(0,z.jsx)(`span`,{className:`v`,children:D.compact(e.output_tokens)})]}),(0,z.jsxs)(`div`,{className:`t`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Cache+`}),(0,z.jsx)(`span`,{className:`v`,children:D.compact(e.cache_creation_tokens)})]}),(0,z.jsxs)(`div`,{className:`t`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Cache-read`}),(0,z.jsx)(`span`,{className:`v`,children:D.compact(e.cache_read_tokens)})]}),(0,z.jsxs)(`div`,{className:`t`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Total`}),(0,z.jsx)(`span`,{className:`v`,children:D.compact(e.total_tokens)})]}),e.cache_hit_pct!=null&&(0,z.jsxs)(`div`,{className:`t cache`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Cache hit`}),(0,z.jsxs)(`span`,{className:`v`,children:[e.cache_hit_pct.toFixed(1),`%`]}),(0,z.jsx)(`div`,{className:`bar`,children:(0,z.jsx)(`div`,{className:`fill`,style:{width:`${Math.min(100,Math.max(0,e.cache_hit_pct))}%`}})})]})]}),t===`weekly`&&(0,z.jsxs)(`div`,{className:`stats2`,children:[(0,z.jsxs)(`div`,{className:`s`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Used %`}),(0,z.jsx)(`span`,{className:`v`,children:D.pct0(e.used_pct)})]}),(0,z.jsxs)(`div`,{className:`s`,children:[(0,z.jsx)(`span`,{className:`k`,children:`$/1%`}),(0,z.jsx)(`span`,{className:`v`,children:D.usd2(e.dollar_per_pct)})]})]})]})}function us(e){return e==null||e===0?`num`:e>0?`num delta-up`:`num delta-down`}function ds(e){let t=new Set,n=[];for(let r of e.models)t.has(r.chip)||(t.add(r.chip),n.push(r.chip));return n}function fs({row:e}){let t=ds(e),n=t.slice(0,3),r=t.length>3?t.length-3:0;return(0,z.jsxs)(`span`,{className:`models-chips`,children:[n.map(e=>(0,z.jsx)(`span`,{className:`chip ${e}`,children:e},e)),r>0&&(0,z.jsxs)(`span`,{className:`models-chips-more`,children:[`…+`,r]})]})}function ps({rows:e,variant:t,accentClass:n,selectedIndex:r,onSelect:i}){return(0,z.jsxs)(`table`,{className:`history-table history-table--${t} ${n}`,role:`grid`,"aria-rowcount":e.length,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{children:t===`weekly`?`Week`:`Month`}),(0,z.jsx)(`th`,{children:`Models`}),(0,z.jsx)(`th`,{className:`num`,children:`Cost (USD)`}),t===`weekly`&&(0,z.jsx)(`th`,{className:`num`,children:`Used %`}),t===`weekly`&&(0,z.jsx)(`th`,{className:`num`,children:`$/1%`}),(0,z.jsx)(`th`,{className:`num`,children:`Δ`})]})}),(0,z.jsx)(`tbody`,{children:e.map((e,n)=>(0,z.jsxs)(`tr`,{className:n===r?`selected`:void 0,"aria-rowindex":n+1,"aria-selected":n===r,onClick:()=>i(n),children:[(0,z.jsxs)(`td`,{children:[e.label,n===r?` ▶`:``]}),(0,z.jsx)(`td`,{children:(0,z.jsx)(fs,{row:e})}),(0,z.jsx)(`td`,{className:`num`,children:D.usd2(e.cost_usd)}),t===`weekly`&&(0,z.jsx)(`td`,{className:`num`,children:D.pct0(e.used_pct)}),t===`weekly`&&(0,z.jsx)(`td`,{className:`num`,children:D.usd2(e.dollar_per_pct)}),(0,z.jsx)(`td`,{className:us(e.delta_cost_pct),children:D.deltaPct(e.delta_cost_pct)})]},e.label))})]})}function ms(){let e=Ke()?.weekly?.rows??[],[t,n]=(0,g.useState)(0),r=e.length;(0,g.useEffect)(()=>zt([{key:`ArrowDown`,scope:`modal`,when:()=>I().openModal===`weekly`,action:()=>n(e=>Math.min(e+1,Math.max(0,r-1)))},{key:`ArrowUp`,scope:`modal`,when:()=>I().openModal===`weekly`,action:()=>n(e=>Math.max(e-1,0))}]),[r]);let i=(0,z.jsx)(Gt,{panel:`weekly`,panelLabel:`Weekly`,triggerId:`weekly-modal`,onClick:()=>R(N(`weekly`,`weekly-modal`))});if(r===0)return(0,z.jsx)(Io,{title:`Weekly history · last 12`,accentClass:`accent-cyan`,headerExtras:i,children:(0,z.jsx)(`div`,{className:`panel-empty`,children:`No usage history yet.`})});let a=e[Math.min(t,r-1)];return(0,z.jsxs)(Io,{title:`Weekly history · last 12`,accentClass:`accent-cyan`,headerExtras:i,children:[(0,z.jsx)(ls,{row:a,variant:`weekly`,accentClass:`accent-cyan`}),(0,z.jsx)(ps,{rows:e,variant:`weekly`,accentClass:`accent-cyan`,selectedIndex:t,onSelect:n})]})}function hs(){let e=Ke()?.monthly?.rows??[],[t,n]=(0,g.useState)(0),r=e.length;(0,g.useEffect)(()=>zt([{key:`ArrowDown`,scope:`modal`,when:()=>I().openModal===`monthly`,action:()=>n(e=>Math.min(e+1,Math.max(0,r-1)))},{key:`ArrowUp`,scope:`modal`,when:()=>I().openModal===`monthly`,action:()=>n(e=>Math.max(e-1,0))}]),[r]);let i=(0,z.jsx)(Gt,{panel:`monthly`,panelLabel:`Monthly`,triggerId:`monthly-modal`,onClick:()=>R(N(`monthly`,`monthly-modal`))});if(r===0)return(0,z.jsx)(Io,{title:`Monthly history · last 12`,accentClass:`accent-pink`,headerExtras:i,children:(0,z.jsx)(`div`,{className:`panel-empty`,children:`No usage history yet.`})});let a=e[Math.min(t,r-1)];return(0,z.jsxs)(Io,{title:`Monthly history · last 12`,accentClass:`accent-pink`,headerExtras:i,children:[(0,z.jsx)(ls,{row:a,variant:`monthly`,accentClass:`accent-pink`}),(0,z.jsx)(ps,{rows:e,variant:`monthly`,accentClass:`accent-pink`,selectedIndex:t,onSelect:n})]})}var gs=720,_s=180,vs={left:46,right:20,top:18,bottom:20};function ys(e){return e===0?`$0`:e<10?`$`+e.toFixed(2):`$`+Math.round(e).toString()}function bs(){return(0,g.useSyncExternalStore)(L,()=>I().snapshot?.generated_at??``)}function xs({detail:e}){let t=bs(),n=Ht(),r={tz:n.resolvedTz,offsetLabel:n.offsetLabel},i=Date.parse(e.start_at),a=Date.parse(e.end_at)-i||1,o=e=>vs.left+(Date.parse(e)-i)/a*(gs-vs.left-vs.right),s=Math.max(e.cost_usd,e.projection?.total_cost_usd??0),c=e=>{let t=vs.top,n=_s-vs.bottom;return s<=0?n:n-e/s*(n-t)},l=[];for(let e=0;e<=5;e++)l.push(new Date(i+e*36e5).toISOString());let u=e.samples.length>0?e.samples[e.samples.length-1].cum:0,d=e.is_active?t||new Date().toISOString():null,f=[];if(e.samples.length>0){f.push([o(e.start_at),c(0)]);for(let t of e.samples)f.push([o(t.t),c(t.cum)]);d&&f.push([o(d),c(u)])}let p=f.map(([e,t])=>`${e.toFixed(1)},${t.toFixed(1)}`).join(` `),m=f.length>0?`M ${p.replace(/ /g,` L `)} L ${f[f.length-1][0].toFixed(1)},${c(0).toFixed(1)} Z`:``,h=s<=0?[0]:[0,s/2,s];return(0,z.jsx)(`div`,{className:`mblock-timeline`,children:(0,z.jsxs)(`svg`,{viewBox:`0 0 ${gs} ${_s}`,style:{width:`100%`,height:`auto`},role:`img`,"aria-label":`Cumulative cost over the 5-hour block window`,children:[h.map(e=>(0,z.jsx)(`text`,{x:8,y:c(e)+4,fill:`var(--text-dim)`,fontSize:10,children:ys(e)},e)),(0,z.jsx)(`line`,{x1:vs.left,y1:vs.top,x2:vs.left,y2:_s-vs.bottom,stroke:`var(--border-soft)`,strokeWidth:.8}),(0,z.jsx)(`line`,{x1:vs.left,y1:_s-vs.bottom,x2:gs-vs.right,y2:_s-vs.bottom,stroke:`var(--border-soft)`,strokeWidth:.8}),l.slice(1,-1).map(e=>(0,z.jsx)(`line`,{x1:o(e),y1:vs.top,x2:o(e),y2:_s-vs.bottom,stroke:`var(--border-soft)`,strokeDasharray:`2 3`,strokeWidth:.5},e)),l.map(e=>(0,z.jsx)(`text`,{x:o(e)-14,y:_s-5,fill:`var(--text-dim)`,fontSize:9,children:D.timeHHmm(e,r,{noSuffix:!0})},e)),f.length>0?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`path`,{d:m,fill:`var(--accent-green)`,opacity:.12}),(0,z.jsx)(`polyline`,{points:p,fill:`none`,stroke:`var(--accent-green)`,strokeWidth:2}),(0,z.jsx)(`circle`,{cx:f[f.length-1][0],cy:f[f.length-1][1],r:3,fill:`var(--accent-green)`})]}):(0,z.jsx)(`text`,{x:gs/2,y:_s/2,fill:`var(--text-faint)`,fontSize:11,textAnchor:`middle`,children:`No spend recorded yet in this block.`}),e.is_active&&e.projection&&d&&f.length>0?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`polyline`,{points:`${o(d).toFixed(1)},${c(u).toFixed(1)} ${o(e.end_at).toFixed(1)},${c(e.projection.total_cost_usd).toFixed(1)}`,fill:`none`,stroke:`var(--accent-amber)`,strokeWidth:1.5,strokeDasharray:`5 4`,opacity:.85}),(0,z.jsx)(`circle`,{cx:o(e.end_at),cy:c(e.projection.total_cost_usd),r:3,fill:`var(--accent-amber)`,opacity:.85}),(0,z.jsxs)(`text`,{x:o(e.end_at)-50,y:c(e.projection.total_cost_usd)-6,fill:`var(--accent-amber)`,fontSize:9,children:[`proj $`,e.projection.total_cost_usd.toFixed(2)]}),(0,z.jsx)(`line`,{x1:o(d),y1:vs.top,x2:o(d),y2:_s-vs.bottom,stroke:`var(--accent-amber)`,strokeWidth:1.2}),(0,z.jsx)(`text`,{x:o(d)+4,y:vs.top+10,fill:`var(--accent-amber)`,fontSize:9,children:`now`})]}):null]})})}function Ss(){return(0,g.useSyncExternalStore)(L,()=>I().snapshot?.generated_at??``)}function Cs(e,t){let n=Date.parse(e.start_at),r=e.is_active?Date.parse(t)||Date.now():e.actual_end_at?Date.parse(e.actual_end_at):Date.parse(e.end_at),i=Math.max(0,Math.floor((r-n)/6e4)),a=Math.floor(i/60),o=i%60;return`${a}h ${String(o).padStart(2,`0`)}m`}function ws(e,t,n){return`${D.timeHHmm(e,n)} → ${D.timeHHmm(t,n)}`}function Ts(){let e=(0,g.useSyncExternalStore)(L,()=>I().openBlockStartAt),t=Ss(),n=Ht(),r={tz:n.resolvedTz,offsetLabel:n.offsetLabel},[i,a]=(0,g.useState)(null),[o,s]=(0,g.useState)(!0),[c,l]=(0,g.useState)(null),u=(0,g.useRef)(null),d=(0,g.useRef)(!1),f=(0,g.useRef)(null);return(0,g.useEffect)(()=>{f.current=e??null,d.current=!1},[e]),(0,g.useEffect)(()=>{let e=f.current;if(!e){s(!1),l(`No block bound.`),a(null),u.current=null;return}let t=u.current!==e||i==null;u.current=e,t&&(s(!0),l(null),a(null));let n=new AbortController;return fetch(`/api/block/${encodeURIComponent(e)}`,{signal:n.signal}).then(async e=>{if(e.status===404){(t||d.current)&&(s(!1),l(`Block not found (the cache may have rolled forward).`),a(null)),d.current=!0;return}if(!e.ok)throw Error(`HTTP `+e.status);let n=await e.json();d.current=!1,a(n),l(null),s(!1)}).catch(e=>{e.name!==`AbortError`&&(d.current=!1,t&&(l(`Failed to load: `+e.message),s(!1)))}),()=>n.abort()},[e,t]),(0,z.jsx)(Io,{title:i?`${i.anchor===`heuristic`?`~ `:``}Block · ${i.label}`:`Block`,accentClass:`accent-blue`,headerExtras:(0,z.jsx)(Gt,{panel:`blocks`,panelLabel:`5-hour block`,triggerId:`block-modal`,onClick:()=>R(N(`blocks`,`block-modal`))}),children:(0,z.jsxs)(`section`,{className:`modal-block`,children:[o?(0,z.jsx)(`div`,{className:`modal-loading`,children:`Loading block detail…`}):null,c?(0,z.jsx)(`div`,{className:`modal-error`,children:c}):null,!o&&!c&&i?(0,z.jsx)(Es,{detail:i,generatedAt:t,ctx:r}):null]})})}function Es({detail:e,generatedAt:t,ctx:n}){let r=e.cost_usd??0;return(0,z.jsxs)(`div`,{className:`modal-content`,children:[(0,z.jsxs)(`div`,{className:`m-chipstrip`,children:[e.is_active?(0,z.jsx)(`span`,{className:`m-pill accent-green`,children:`● Active`}):null,e.anchor===`heuristic`?(0,z.jsx)(`span`,{className:`m-pill accent-amber`,children:`~ heuristic anchor`}):null,(0,z.jsx)(`span`,{className:`m-pill accent-blue`,children:ws(e.start_at,e.end_at,n)}),(0,z.jsxs)(`span`,{className:`m-pill`,children:[e.entries_count.toLocaleString(`en-US`),` `,e.entries_count===1?`entry`:`entries`]})]}),(0,z.jsxs)(`div`,{className:`m-hero `+(e.is_active?`cols-4`:`cols-3`),children:[(0,z.jsxs)(`div`,{className:`m-kv kv-cost`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#dollar`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,children:D.usd2(e.cost_usd)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Total cost`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv kv-dur`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#clock`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,children:Cs(e,t)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Elapsed`})]})]}),(0,z.jsxs)(`div`,{className:`m-kv`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#hash`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,children:e.total_tokens.toLocaleString(`en-US`)}),(0,z.jsx)(`div`,{className:`lbl`,children:`Total tokens`})]})]}),e.is_active?(0,z.jsxs)(`div`,{className:`m-kv kv-proj`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#crystal-ball`})}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`v`,children:e.projection?D.usd2(e.projection.total_cost_usd):`—`}),(0,z.jsxs)(`div`,{className:`lbl`,children:[`Projected`,e.projection?` · ${e.projection.remaining_minutes}m left`:``]})]})]}):null]}),(0,z.jsx)(xs,{detail:e}),(0,z.jsxs)(`h3`,{className:`m-sec sec-tok`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#hash`})}),`Tokens`]}),(0,z.jsxs)(`div`,{className:`msess-tok-grid mblock-tok-grid`,children:[(0,z.jsxs)(`div`,{className:`msess-tok-tile`,children:[(0,z.jsx)(`div`,{className:`lbl`,children:`Input`}),(0,z.jsx)(`div`,{className:`n`,children:e.input_tokens.toLocaleString(`en-US`)})]}),(0,z.jsxs)(`div`,{className:`msess-tok-tile`,children:[(0,z.jsx)(`div`,{className:`lbl`,children:`Output`}),(0,z.jsx)(`div`,{className:`n`,children:e.output_tokens.toLocaleString(`en-US`)})]}),(0,z.jsxs)(`div`,{className:`msess-tok-tile`,children:[(0,z.jsx)(`div`,{className:`lbl`,children:`Cache create`}),(0,z.jsx)(`div`,{className:`n`,children:e.cache_creation_tokens.toLocaleString(`en-US`)})]}),(0,z.jsxs)(`div`,{className:`msess-tok-tile`,children:[(0,z.jsx)(`div`,{className:`lbl`,children:`Cache read`}),(0,z.jsx)(`div`,{className:`n`,children:e.cache_read_tokens.toLocaleString(`en-US`)})]}),e.cache_hit_pct==null?null:(0,z.jsxs)(`div`,{className:`msess-tok-tile cache-hit`,children:[(0,z.jsx)(`div`,{className:`lbl`,children:`Cache hit %`}),(0,z.jsxs)(`div`,{className:`n`,children:[e.cache_hit_pct.toFixed(1),`%`]}),(0,z.jsx)(`div`,{className:`bar`,children:(0,z.jsx)(`div`,{className:`fill`,style:{width:Math.min(100,Math.max(0,e.cache_hit_pct))+`%`}})})]})]}),e.models.length>0?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-costm`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#pie-chart`})}),`Cost by model`]}),(0,z.jsxs)(`div`,{className:`msess-costm`,children:[(0,z.jsx)(`div`,{className:`bar`,children:e.models.map(e=>{let t=r>0?e.cost_usd/r*100:0;return(0,z.jsx)(`div`,{className:`seg `+ln(e.model),style:{width:t+`%`}},e.model)})}),(0,z.jsx)(`div`,{className:`legend`,children:e.models.map(e=>{let t=r>0?e.cost_usd/r*100:0;return(0,z.jsxs)(`div`,{className:`lg`,children:[(0,z.jsx)(`span`,{className:`sw `+ln(e.model)}),(0,z.jsx)(`span`,{className:`name`,children:e.display}),(0,z.jsxs)(`span`,{className:`v`,children:[`$`,e.cost_usd.toFixed(2)]}),(0,z.jsxs)(`span`,{className:`pct`,children:[Math.round(t),`%`]})]},e.model)})})]})]}):null,e.is_active&&e.burn_rate&&e.projection?(0,z.jsxs)(z.Fragment,{children:[(0,z.jsxs)(`h3`,{className:`m-sec sec-burn`,children:[(0,z.jsx)(`svg`,{className:`icon`,"aria-hidden":`true`,children:(0,z.jsx)(`use`,{href:`/static/icons.svg#crystal-ball`})}),`Burn rate & projection`]}),(0,z.jsxs)(`div`,{className:`mblock-burn`,children:[(0,z.jsxs)(`div`,{className:`row`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Burn rate`}),(0,z.jsx)(`span`,{className:`v amber`,children:D.usd2(e.burn_rate.cost_per_hour)}),(0,z.jsx)(`span`,{className:`dim`,children:`/ hr`}),(0,z.jsx)(`span`,{className:`sep`,children:`·`}),(0,z.jsx)(`span`,{className:`v cyan`,children:Math.round(e.burn_rate.tokens_per_minute).toLocaleString(`en-US`)}),(0,z.jsx)(`span`,{className:`dim`,children:`tok / min`})]}),(0,z.jsxs)(`div`,{className:`row`,children:[(0,z.jsx)(`span`,{className:`k`,children:`Projection`}),(0,z.jsx)(`span`,{className:`v amber`,children:D.usd2(e.projection.total_cost_usd)}),(0,z.jsx)(`span`,{className:`dim`,children:`total`}),(0,z.jsx)(`span`,{className:`sep`,children:`·`}),(0,z.jsx)(`span`,{className:`v cyan`,children:e.projection.total_tokens.toLocaleString(`en-US`)}),(0,z.jsx)(`span`,{className:`dim`,children:`tok`}),(0,z.jsx)(`span`,{className:`sep`,children:`·`}),(0,z.jsxs)(`span`,{className:`v`,children:[e.projection.remaining_minutes,` min`]}),(0,z.jsx)(`span`,{className:`dim`,children:`remaining`})]})]})]}):null]})}function Ds({rows:e,selectedDate:t,onSelect:n}){let r=[...e].reverse(),i=r.reduce((e,t)=>Math.max(e,t.cost_usd),0),a=r.length>0?Os(r[0].date):``,o=r.length>0?Os(r[r.length-1].date):``,s=r.find(e=>e.is_today),c=s?`${Os(s.date)} · today`:``;return(0,z.jsxs)(`section`,{className:`daily-modal-bars`,"aria-label":`30-day cost`,children:[(0,z.jsxs)(`div`,{className:`daily-modal-bars-head`,children:[(0,z.jsxs)(`span`,{children:[`30-day cost · selected: `,t?Os(t):`—`]}),(0,z.jsx)(`span`,{className:`hint`,children:`↑↓ navigate · click any bar`})]}),(0,z.jsx)(`div`,{className:`daily-modal-bars-grid`,role:`img`,"aria-label":`30-day cost histogram`,children:r.map(e=>{let r=e.cost_usd<=0,a=e.date===t,o=r?4:i>0?e.cost_usd/i*100:0,s=[`bar`,r?`zero`:``,a?`sel`:``,e.is_today?`today`:``].filter(Boolean).join(` `);return(0,z.jsx)(`button`,{"data-date":e.date,className:s,style:{height:`${o}%`},disabled:r,"aria-pressed":a,"aria-label":`${e.label} cost ${e.cost_usd>0?D.usd2(e.cost_usd):`no usage`}`,title:e.cost_usd>0?`${e.label} · ${D.usd2(e.cost_usd)}`:`${e.label} · —`,onClick:()=>{r||n(e.date)}},e.date)})}),r.length>0&&(0,z.jsxs)(`div`,{className:`daily-modal-bars-axis`,children:[(0,z.jsx)(`span`,{children:a}),c&&(0,z.jsx)(`span`,{children:c}),(0,z.jsx)(`span`,{children:o})]})]})}function Os(e){let t=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`],n=e.split(`-`).map(Number);return`${t[n[1]-1]} ${n[2]}`}function ks(){let e=Ke()?.daily?.rows??[],t=(0,g.useSyncExternalStore)(L,()=>I().openDailyDate),[n,r]=(0,g.useState)(null);(0,g.useEffect)(()=>{t&&r(t)},[]);let i=new Set(e.map(e=>e.date)),a=e[0]?.date??null,o=n&&i.has(n)?n:a;(0,g.useEffect)(()=>zt([{key:`ArrowDown`,scope:`modal`,when:()=>I().openModal===`daily`,action:()=>{let t=o;if(!t)return;let n=e.findIndex(e=>e.date===t);n<0||n>=e.length-1||r(e[n+1].date)}},{key:`ArrowUp`,scope:`modal`,when:()=>I().openModal===`daily`,action:()=>{let t=o;if(!t)return;let n=e.findIndex(e=>e.date===t);n<=0||r(e[n-1].date)}}]),[e,o]);let s=(0,z.jsx)(Gt,{panel:`daily`,panelLabel:`Daily`,triggerId:`daily-modal`,onClick:()=>R(N(`daily`,`daily-modal`))});if(e.length===0)return(0,z.jsx)(Io,{title:`Daily history · last 30`,accentClass:`accent-indigo`,headerExtras:s,children:(0,z.jsx)(`div`,{className:`panel-empty`,children:`No usage history yet.`})});let c=e.findIndex(e=>e.date===o),l=c>=0?c:0,u=e[l],d=e[l+1],f=As(u,d);return(0,z.jsxs)(Io,{title:`Daily history · last 30`,accentClass:`accent-indigo`,headerExtras:s,children:[(0,z.jsx)(Ds,{rows:e,selectedDate:o,onSelect:r}),(0,z.jsx)(ls,{row:f,variant:`daily`,accentClass:`accent-indigo`})]})}function As(e,t){let n=t&&t.cost_usd>0?(e.cost_usd-t.cost_usd)/t.cost_usd:null;return{label:e.label,cost_usd:e.cost_usd,total_tokens:e.total_tokens,input_tokens:e.input_tokens,output_tokens:e.output_tokens,cache_creation_tokens:e.cache_creation_tokens,cache_read_tokens:e.cache_read_tokens,used_pct:null,dollar_per_pct:null,delta_cost_pct:n,is_current:e.is_today,models:e.models,cache_hit_pct:e.cache_hit_pct}}var js=[`#d946ef`,`#c084fc`,`#60a5fa`,`#fbbf24`,`#22d3ee`],Ms=`#64748b`,Ns=5,Ps=400,Fs=150;function Is({trend:e,yMode:t,windowWeeks:n,onProjectSelect:r}){let i=(0,g.useMemo)(()=>{let t=Math.max(0,Math.min(n,e.window_weeks)),r=e.weeks.slice(-t),i=e.projects.map(e=>{let n=e.weekly_cost.slice(-t),r=n.reduce((e,t)=>e+t,0);return{key:e.key,weekly:n,cost:r,color:``}}).sort((e,t)=>t.cost-e.cost),a=i.slice(0,Ns).map((e,t)=>({...e,color:js[t]??Ms})),o=i.slice(Ns),s=r.map((e,t)=>o.reduce((e,n)=>e+(n.weekly[t]??0),0)),c=s.reduce((e,t)=>e+t,0),l=[...a];return o.length>0&&c>0&&l.push({key:`(other)`,weekly:s,cost:c,color:Ms}),{weeks:r,series:l}},[e,n]),a=on();if(i.weeks.length===0||i.series.length===0)return(0,z.jsxs)(`div`,{className:`panel-empty`,children:[`No project activity in the last `,n,` week`,n===1?``:`s`,`.`]});let o=i.weeks.length,s=i.weeks.map((e,t)=>i.series.reduce((e,n)=>e+(n.weekly[t]??0),0)),c=t===`share`?100:Math.max(...s,.01),l=(e,t=`left`)=>o<=1?t===`left`?Ps*.1:Ps*.9:e/(o-1)*Ps,u=Array(o).fill(0),d=i.series.map(e=>{let n=[];for(let e=0;e<o;e++){let t=Fs-u[e]/c*Fs;n.push(`${l(e,`left`).toFixed(2)},${t.toFixed(2)}`),o===1&&n.push(`${l(e,`right`).toFixed(2)},${t.toFixed(2)}`)}for(let r=o-1;r>=0;r--){let i=s[r]??0,a=t===`share`?i>0?(e.weekly[r]??0)/i*100:0:e.weekly[r]??0;u[r]+=a;let d=Fs-u[r]/c*Fs;o===1&&n.push(`${l(r,`right`).toFixed(2)},${d.toFixed(2)}`),n.push(`${l(r,`left`).toFixed(2)},${d.toFixed(2)}`)}return{color:e.color,key:e.key,points:n.join(` `)}}),f=i.weeks.map(e=>(0,z.jsx)(`span`,{children:e.week_label},e.week_start_date));return(0,z.jsxs)(`div`,{className:`projects-trend`,children:[(0,z.jsx)(`svg`,{viewBox:`0 0 ${Ps} ${Fs}`,preserveAspectRatio:`none`,role:`img`,"aria-label":`Stacked area: project ${t===`share`?`share %`:`cost`} over ${o} weeks`,children:d.map(e=>{let t=e.key===`(other)`;return(0,z.jsx)(`polygon`,{fill:e.color,opacity:t?.5:.65,points:e.points,"data-series-key":e.key,onClick:()=>{t||r?.(e.key)},style:{cursor:t?`default`:`pointer`}},e.key)})}),(0,z.jsx)(`div`,{className:`projects-trend-xaxis`,children:f}),(0,z.jsx)(`div`,{className:`projects-trend-legend`,children:i.series.map(e=>{let t=e.key===`(other)`,n=(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(`span`,{className:`sw`,style:{background:e.color}}),e.key]});return a&&!t?(0,z.jsx)(`button`,{type:`button`,className:`projects-trend-legend-item`,"data-series-key":e.key,onClick:()=>r?.(e.key),children:n},e.key):(0,z.jsx)(`span`,{className:`projects-trend-legend-item`,"data-series-key":e.key,children:n},e.key)})})]})}function Ls(e,t){let[n,r]=(0,g.useState)(null),[i,a]=(0,g.useState)(!1),[o,s]=(0,g.useState)(null),c=Ke()?.generated_at??``,l=(0,g.useRef)(0),u=(0,g.useRef)(null),d=(0,g.useRef)(null),f=(0,g.useRef)(!1);return(0,g.useEffect)(()=>{if(!e){r(null),a(!1),s(null),l.current=0,u.current=null,d.current=null,f.current=!1;return}let i=u.current!==e||d.current!==t,o=i||n==null;if(o&&f.current&&!i)return;o&&(a(!0),s(null)),i&&(l.current=0),u.current=e,d.current=t,f.current=!0;let c=new AbortController,p=`/api/project/${encodeURIComponent(e)}?weeks=${t}`;return fetch(p,{signal:c.signal}).then(async e=>{if(e.status===404){l.current+=1,l.current>=2?(r(null),s(`Project no longer in cache — close this drill.`),a(!1)):o&&(s(`Couldn't load project detail — will retry on next tick.`),a(!1));return}if(!e.ok){o&&(s(`Couldn't load project detail — will retry on next tick.`),a(!1));return}l.current=0,r(await e.json()),s(null),a(!1)}).catch(e=>{e?.name!==`AbortError`&&o&&(s(`Couldn't load project detail — will retry on next tick.`),a(!1))}).finally(()=>{f.current=!1}),()=>c.abort()},[e,t,c]),{data:n,loading:i,error:o}}function Rs({projectKey:e,windowWeeks:t}){let{data:n,loading:r,error:i}=Ls(e,t),a=Ht(),o={tz:a.resolvedTz,offsetLabel:a.offsetLabel},s=n!=null&&(n.key!==e||n.window_weeks!==t);if(r&&!n||s)return(0,z.jsx)(`div`,{className:`panel-empty`,children:`Loading…`});if(i&&!n)return(0,z.jsx)(`div`,{className:`panel-empty`,children:i});if(!n)return null;let c=n.models[0]?.cost_usd??0,l=c>0?c:1,u=Math.max(0,n.sessions_total-n.sessions.length);return(0,z.jsxs)(`div`,{className:`projects-drill`,"data-testid":`projects-drill`,"aria-live":`polite`,children:[(0,z.jsx)(`div`,{className:`projects-drill-head`,children:(0,z.jsxs)(`span`,{className:`title`,children:[`▾ `,n.key,` · `,n.sessions_total,` session`,n.sessions_total===1?``:`s`,` · `,D.usd2(n.window_cost_usd),` (`,t,`w)`]})}),(0,z.jsxs)(`div`,{className:`projects-drill-grid`,children:[(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`section-label`,children:`Models (this project)`}),n.models.length===0?(0,z.jsx)(`div`,{className:`muted`,children:`No model data for this window.`}):n.models.map(e=>{let t={"--w":`${e.cost_usd/l*100}%`};return(0,z.jsxs)(`div`,{className:`drill-bar-row`,children:[(0,z.jsx)(`span`,{className:`chip ${ln(e.model)}`,children:e.model}),(0,z.jsx)(`div`,{className:`drill-bar`,style:t}),(0,z.jsx)(`span`,{className:`cost ${un(e.cost_usd)}`,children:D.usd2(e.cost_usd)})]},e.model)})]}),(0,z.jsxs)(`div`,{children:[(0,z.jsx)(`div`,{className:`section-label`,children:`Recent sessions →`}),n.sessions.length===0?(0,z.jsx)(`div`,{className:`muted`,children:`No sessions for this window.`}):n.sessions.map((e,t)=>(0,z.jsxs)(`button`,{"data-testid":`drill-session-${t}`,className:`drill-session-row`,onClick:()=>R({type:`OPEN_MODAL`,kind:`session`,sessionId:e.session_id}),children:[(0,z.jsx)(`span`,{className:`started`,children:D.datetimeShort(e.last_activity_at,o)}),(0,z.jsx)(`span`,{className:`chip ${ln(e.primary_model)}`,children:e.primary_model}),(0,z.jsx)(`span`,{className:`cost ${un(e.cost_usd)}`,children:D.usd2(e.cost_usd)})]},e.session_id)),(0,z.jsxs)(`div`,{className:`drill-session-footer`,children:[u>0&&(0,z.jsxs)(`span`,{className:`muted`,children:[`+`,u,` more`]}),(0,z.jsx)(`button`,{type:`button`,"data-testid":`drill-show-in-sessions`,className:`drill-show-in-sessions`,onClick:()=>{R({type:`SET_FILTER`,text:n.key}),R({type:`CLOSE_MODAL`})},children:`Show in Sessions →`})]})]})]})]})}var zs=(e,t)=>e<t?-1:+(e>t),Bs=[{id:`project`,label:`Project`,defaultDirection:`asc`,compare:(e,t)=>zs(e.key,t.key),className:`project`},{id:`sessions`,label:`Sessions`,defaultDirection:`desc`,numeric:!0,compare:(e,t)=>e.sessionsCount-t.sessionsCount},{id:`first_seen`,label:`First seen`,defaultDirection:`asc`,nullKey:e=>e.firstSeenAt,compare:(e,t)=>zs(e.firstSeenAt,t.firstSeenAt),className:`started`},{id:`last_seen`,label:`Last seen`,defaultDirection:`desc`,nullKey:e=>e.lastSeenAt,compare:(e,t)=>zs(e.lastSeenAt,t.lastSeenAt),className:`started`},{id:`cost`,label:`Cost`,defaultDirection:`desc`,numeric:!0,compare:(e,t)=>e.windowCost-t.windowCost},{id:`used_pct`,label:`Used %`,defaultDirection:`desc`,numeric:!0,nullKey:e=>e.windowPct,compare:(e,t)=>e.windowPct-t.windowPct},{id:`share_of_window`,label:`% of week`,defaultDirection:`desc`,numeric:!0,nullKey:e=>e.shareOfWindow,compare:(e,t)=>e.shareOfWindow-t.shareOfWindow}],Vs=[{column:`cost`,direction:`desc`,label:`cost`,arrow:`↓`},{column:`sessions`,direction:`desc`,label:`sessions`,arrow:`↓`},{column:`used_pct`,direction:`desc`,label:`used`,arrow:`↓`},{column:`share_of_window`,direction:`desc`,label:`share`,arrow:`↓`},{column:`first_seen`,direction:`asc`,label:`first`,arrow:`↑`},{column:`last_seen`,direction:`desc`,label:`last`,arrow:`↓`},{column:`project`,direction:`asc`,label:`project`,arrow:`↑`}],Hs=[1,4,8,12];function Us(){let e=Ke(),t=Ht(),n={tz:t.resolvedTz,offsetLabel:t.offsetLabel},r=(0,g.useSyncExternalStore)(L,()=>I().openProjectKey),i=(0,g.useSyncExternalStore)(L,()=>I().prefs.projectsWindowWeeks),a=(0,g.useSyncExternalStore)(L,()=>I().prefs.projectsTrendYMode),o=(0,g.useSyncExternalStore)(L,()=>I().prefs.projectsSortOverride),[s,c]=(0,g.useState)(r??null),[l,u]=(0,g.useState)(!1);(0,g.useEffect)(()=>{if(r){c(r);return}s||c(e?.projects?.current_week?.rows?.[0]?.key??null)},[r,e?.projects?.current_week?.rows]),(0,g.useEffect)(()=>{r||s&&((e?.projects?.trend?.projects??[]).some(e=>e.key===s)||c(e?.projects?.current_week?.rows?.[0]?.key??null))},[r,s,e?.projects?.trend?.projects,e?.projects?.current_week?.rows]);let d=e?.projects?.trend??null,f=i,p=d?.window_weeks??0,m=(e,t)=>{R({type:`SAVE_PREFS`,patch:{[e]:t}})},h=e=>{c(t=>t===e?null:e)},_=(d?.projects??[]).map(e=>{let t=e.weekly_cost.slice(-i),n=e.weekly_pct.slice(-i),r=e.sessions_per_week.slice(-i),a=e.first_seen_per_week.slice(-i),o=e.last_seen_per_week.slice(-i),s=t.reduce((e,t)=>e+t,0),c=n.reduce((e,t)=>t==null?e:(e??0)+t,null),l=r.reduce((e,t)=>e+t,0),u=a.reduce((e,t)=>t==null?e:e==null||t<e?t:e,null),d=o.reduce((e,t)=>t==null?e:e==null||t>e?t:e,null);return{key:e.key,sessionsCount:l,firstSeenAt:u,lastSeenAt:d,windowCost:s,windowPct:c,shareOfWindow:null}}),v=_.reduce((e,t)=>e+t.windowCost,0);for(let e of _)e.shareOfWindow=v>0?e.windowCost/v*100:null;let y=o?de(_,Bs,o):de(_,Bs,{column:`cost`,direction:`desc`}),b=y.filter(e=>e.windowCost>0).slice(0,10),x=y.length-b.length,S=l?y:b,C=x>0,w=on(),T=(()=>{if(!o)return 0;let e=Vs.findIndex(e=>e.column===o.column&&e.direction===o.direction);return e===-1?0:e})(),ee=()=>{let e=Vs[(T+1)%Vs.length];R({type:`SET_TABLE_SORT`,table:`projects`,override:{column:e.column,direction:e.direction}})},te=Vs[T],E=()=>I().shareModal===null&&I().composerModal===null;return V([{key:`1`,scope:`modal`,when:E,action:()=>m(`projectsWindowWeeks`,1)},{key:`4`,scope:`modal`,when:E,action:()=>m(`projectsWindowWeeks`,4)},{key:`8`,scope:`modal`,when:E,action:()=>m(`projectsWindowWeeks`,8)},{key:`0`,scope:`modal`,when:E,action:()=>m(`projectsWindowWeeks`,12)},{key:`s`,scope:`modal`,when:E,action:()=>m(`projectsTrendYMode`,a===`share`?`absolute`:`share`)},{key:`ArrowUp`,scope:`modal`,when:E,action:()=>{if(S.length===0)return;let e=S.findIndex(e=>e.key===s);c(S[e<=0?S.length-1:e-1].key)}},{key:`ArrowDown`,scope:`modal`,when:E,action:()=>{if(S.length===0)return;let e=S.findIndex(e=>e.key===s);c(S[e===-1||e===S.length-1?0:e+1].key)}},{key:`Enter`,scope:`modal`,when:E,action:()=>{s?c(null):S.length>0&&c(S[0].key)}}]),(0,z.jsx)(Io,{title:`Projects · last ${i}w`,accentClass:`accent-magenta`,headerExtras:(0,z.jsx)(Gt,{panel:`projects`,panelLabel:`Projects`,triggerId:`projects-modal`,dataTestId:`share-icon-projects-modal`,onClick:()=>R(N(`projects`,`projects-modal`,{windowWeeks:i}))}),children:(0,z.jsxs)(`div`,{className:`projects-modal-body`,children:[(0,z.jsxs)(`div`,{className:`projects-controls`,role:`radiogroup`,"aria-label":`Window`,children:[Hs.map(e=>(0,z.jsxs)(`button`,{type:`button`,role:`radio`,"aria-checked":i===e,className:`pill ${i===e?`on`:``}`,onClick:()=>m(`projectsWindowWeeks`,e),children:[e,`w`]},`window-${e}`)),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`|`}),(0,z.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":a===`share`,className:`pill ${a===`share`?`on`:``}`,onClick:()=>m(`projectsTrendYMode`,`share`),children:`share %`}),(0,z.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":a===`absolute`,className:`pill ${a===`absolute`?`on`:``}`,onClick:()=>m(`projectsTrendYMode`,`absolute`),children:`$ absolute`})]}),p>0&&p<f&&(0,z.jsxs)(`div`,{className:`projects-notice`,children:[`Showing `,p,` week`,p===1?``:`s`,` (need more history for the full window).`]}),d?(0,z.jsx)(Is,{trend:d,yMode:a,windowWeeks:i,onProjectSelect:e=>c(e)}):(0,z.jsx)(`div`,{className:`panel-empty`,children:`Projects trend unavailable.`}),w&&(0,z.jsxs)(`button`,{type:`button`,className:`projects-mobile-sort`,"data-testid":`projects-mobile-sort`,onClick:ee,"aria-label":`Cycle sort column`,children:[`Sort: `,te.label,` `,te.arrow]}),(0,z.jsxs)(`table`,{className:`projects-table`,children:[(0,z.jsx)(tn,{columns:Bs,override:o,onChange:e=>R({type:`SET_TABLE_SORT`,table:`projects`,override:e}),accentVar:`--accent-magenta`}),(0,z.jsx)(`tbody`,{children:S.map(e=>(0,z.jsxs)(g.Fragment,{children:[(0,z.jsxs)(`tr`,{"data-testid":`projects-table-row`,"data-cost":e.windowCost,"data-sessions":e.sessionsCount,"aria-expanded":s===e.key,className:s===e.key?`selected`:``,onClick:()=>h(e.key),children:[(0,z.jsx)(`td`,{className:`project`,children:e.key}),(0,z.jsx)(`td`,{children:e.sessionsCount}),(0,z.jsx)(`td`,{className:`started first-seen`,children:D.dateShort(e.firstSeenAt,n)??`—`}),(0,z.jsx)(`td`,{className:`started last-seen`,children:D.dateShort(e.lastSeenAt,n)??`—`}),(0,z.jsx)(`td`,{className:un(e.windowCost),children:D.usd2(e.windowCost)}),(0,z.jsx)(`td`,{children:e.windowPct==null?`—`:D.pct0(e.windowPct)}),(0,z.jsx)(`td`,{children:e.shareOfWindow==null?`—`:D.pct0(e.shareOfWindow)})]}),w&&s===e.key&&(0,z.jsx)(`tr`,{className:`projects-drill-row`,"aria-hidden":`false`,children:(0,z.jsx)(`td`,{colSpan:7,children:(0,z.jsx)(Rs,{projectKey:e.key,windowWeeks:i})})})]},e.key))})]}),C&&(0,z.jsx)(`button`,{type:`button`,className:`projects-table-toggle`,"data-testid":`projects-table-toggle`,"aria-expanded":l,onClick:()=>u(e=>!e),children:l?`Show top 10 active`:`Show all ${y.length} projects (+${x})`}),!w&&s&&(0,z.jsx)(Rs,{projectKey:s,windowWeeks:i}),(0,z.jsxs)(`div`,{className:`projects-modal-footer-hint`,"data-testid":`projects-modal-footer-hint`,"aria-live":`off`,children:[(0,z.jsxs)(`span`,{children:[(0,z.jsx)(`kbd`,{children:`1`}),`/`,(0,z.jsx)(`kbd`,{children:`4`}),`/`,(0,z.jsx)(`kbd`,{children:`8`}),`/`,(0,z.jsx)(`kbd`,{children:`0`}),` window`]}),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`·`}),(0,z.jsxs)(`span`,{children:[(0,z.jsx)(`kbd`,{children:`↑↓`}),` row`]}),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`·`}),(0,z.jsxs)(`span`,{children:[(0,z.jsx)(`kbd`,{children:`Enter`}),` drill`]}),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`·`}),(0,z.jsxs)(`span`,{children:[(0,z.jsx)(`kbd`,{children:`s`}),` share/$`]}),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`·`}),(0,z.jsxs)(`span`,{children:[(0,z.jsx)(`kbd`,{children:`Esc`}),` close`]}),(0,z.jsx)(`span`,{className:`sep`,"aria-hidden":`true`,children:`·`}),(0,z.jsx)(yt,{})]})]})})}var Ws=100;function Gs({alert:e,ctx:t}){if(e.axis===`weekly`){let n=e.context.week_start_date?D.weekStart(e.context.week_start_date,t):null,r=e.context.dollars_per_percent;return(0,z.jsxs)(`span`,{className:`alert-context alert-context--weekly`,children:[n?`Week of ${n}`:`Week —`,r!=null&&(0,z.jsxs)(z.Fragment,{children:[` · `,(0,z.jsxs)(`span`,{className:`num`,children:[`$`,r.toFixed(2),`/1%`]})]})]})}return(0,z.jsxs)(`span`,{className:`alert-context alert-context--five-hour`,children:[`Block `,e.context.block_start_at?D.timeOnly(e.context.block_start_at,t):`—`]})}function Ks({alert:e}){let t=e.axis===`weekly`?e.context.cumulative_cost_usd:e.context.block_cost_usd;return(0,z.jsx)(`span`,{className:`num`,children:D.usd2(t??null)})}function qs(){let e=(0,g.useSyncExternalStore)(L,()=>I().alerts),t=Ht(),n={tz:t.resolvedTz,offsetLabel:t.offsetLabel},r=e.slice(0,Ws);return r.length===0?(0,z.jsx)(Io,{title:`Recent alerts`,accentClass:`accent-amber`,children:(0,z.jsx)(`div`,{className:`panel-empty`,children:`No alerts yet. Alerts appear when usage crosses 90% or 95%.`})}):(0,z.jsx)(Io,{title:`Recent alerts`,accentClass:`accent-amber`,children:(0,z.jsxs)(`div`,{className:`alerts-modal-body`,children:[(0,z.jsxs)(`table`,{className:`alerts-table`,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{scope:`col`,children:`%`}),(0,z.jsx)(`th`,{scope:`col`,children:`Axis`}),(0,z.jsx)(`th`,{scope:`col`,children:`Cost`}),(0,z.jsx)(`th`,{scope:`col`,children:`Context`}),(0,z.jsx)(`th`,{scope:`col`,children:`Alerted`})]})}),(0,z.jsx)(`tbody`,{children:r.map(e=>{let t=e.threshold>=95?`red`:`amber`;return(0,z.jsxs)(`tr`,{className:`alert-modal-row`,children:[(0,z.jsxs)(`td`,{className:`alert-threshold severity-${t} ${t} num`,children:[e.threshold,`%`]}),(0,z.jsx)(`td`,{children:(0,z.jsx)(`span`,{className:`chip chip--${e.axis}`,children:e.axis===`weekly`?`WEEKLY`:`5H-BLOCK`})}),(0,z.jsx)(`td`,{className:`num`,children:(0,z.jsx)(Ks,{alert:e})}),(0,z.jsx)(`td`,{children:(0,z.jsx)(Gs,{alert:e,ctx:n})}),(0,z.jsx)(`td`,{className:`alert-when`,children:D.relativeOrAbsolute(e.alerted_at,n)})]},e.id)})})]}),e.length>Ws&&(0,z.jsxs)(`div`,{className:`alerts-modal-foot`,children:[`Showing `,Ws,` of `,e.length,` most recent`]})]})})}function Js(){let e=(0,g.useSyncExternalStore)(L,()=>I().openModal);if(!e)return null;switch(e){case`current-week`:return(0,z.jsx)(Uo,{});case`forecast`:return(0,z.jsx)(Yo,{});case`trend`:return(0,z.jsx)(is,{});case`session`:return(0,z.jsx)(ss,{});case`weekly`:return(0,z.jsx)(ms,{});case`monthly`:return(0,z.jsx)(hs,{});case`block`:return(0,z.jsx)(Ts,{});case`daily`:return(0,z.jsx)(ks,{});case`projects`:return(0,z.jsx)(Us,{});case`alerts`:return(0,z.jsx)(qs,{})}}var X=class extends Error{code;constructor(e,t,n,r){super(n),this.status=e,this.field=t,this.code=r}};async function Ys(e){if(!e.ok){let t={};try{t=await e.json()}catch{}throw new X(e.status,t.field,t.error??`HTTP ${e.status}`,t.code)}return e.json()}async function Xs(e,t){return Ys(await fetch(`/api/share/templates?panel=${encodeURIComponent(e)}`,{signal:t?.signal}))}async function Zs(e,t){return Ys(await fetch(`/api/share/render`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),signal:t?.signal}))}var Qs=[{id:`recap`,label:`Recap`,placeholderDescription:`Text + tiny chart`},{id:`visual`,label:`Visual`,placeholderDescription:`Coming in M2`},{id:`detail`,label:`Detail`,placeholderDescription:`Coming in M2`}];function $s(e){return e.endsWith(`-recap`)?`recap`:e.endsWith(`-visual`)?`visual`:e.endsWith(`-detail`)?`detail`:null}function ec({panel:e,templates:t,error:n,selectedTemplateId:r,onSelect:i}){if(n)return(0,z.jsx)(`div`,{className:`share-gallery-error`,role:`alert`,children:n});let a={};for(let e of t??[]){let t=$s(e.id);t&&(a[t]=e)}return(0,z.jsx)(`div`,{className:`share-gallery`,role:`radiogroup`,"aria-label":`Report template`,children:Qs.map(e=>{let n=a[e.id];if(t==null)return(0,z.jsxs)(`div`,{className:`share-tile share-tile-skeleton`,"aria-hidden":`true`,children:[(0,z.jsx)(`div`,{className:`share-tile-skeleton-bar`}),(0,z.jsx)(`div`,{className:`share-tile-skeleton-bar short`})]},e.id);if(!n)return(0,z.jsxs)(`button`,{type:`button`,className:`share-tile share-tile-disabled`,disabled:!0,"aria-disabled":`true`,role:`radio`,"aria-checked":`false`,title:`${e.label} — ${e.placeholderDescription}`,children:[(0,z.jsx)(`div`,{className:`share-tile-label`,children:e.label}),(0,z.jsx)(`div`,{className:`share-tile-desc`,children:e.placeholderDescription})]},e.id);let o=n.id===r;return(0,z.jsxs)(`button`,{type:`button`,className:`share-tile`+(o?` share-tile-selected`:``),role:`radio`,"aria-checked":o,"data-template-id":n.id,onClick:()=>i(n.id),children:[(0,z.jsx)(`div`,{className:`share-tile-label`,children:n.label}),(0,z.jsx)(`div`,{className:`share-tile-desc`,children:n.description})]},e.id)})})}function tc({options:e,onChange:t}){let n=n=>t({...e,...n}),r=n=>t({...e,period:{...e.period,...n}}),i=e=>{if(e===``){n({top_n:null});return}let t=Number.parseInt(e,10);Number.isNaN(t)||n({top_n:Math.max(1,t)})};return(0,z.jsxs)(`div`,{className:`share-knobs`,children:[(0,z.jsxs)(`div`,{className:`share-knob`,children:[(0,z.jsx)(`label`,{htmlFor:`share-knob-period`,children:`Period`}),(0,z.jsxs)(`select`,{id:`share-knob-period`,value:e.period.kind,onChange:e=>r({kind:e.target.value}),children:[(0,z.jsx)(`option`,{value:`current`,children:`This week`}),(0,z.jsx)(`option`,{value:`previous`,children:`Previous week`}),(0,z.jsx)(`option`,{value:`custom`,children:`Custom`})]}),e.period.kind===`custom`?(0,z.jsxs)(`div`,{className:`share-knob-period-custom`,children:[(0,z.jsxs)(`label`,{className:`share-knob-sublabel`,children:[(0,z.jsx)(`span`,{children:`Start`}),(0,z.jsx)(`input`,{type:`date`,value:e.period.start?.slice(0,10)??``,onChange:e=>r({start:e.target.value}),"aria-label":`Custom period start date`})]}),(0,z.jsxs)(`label`,{className:`share-knob-sublabel`,children:[(0,z.jsx)(`span`,{children:`End`}),(0,z.jsx)(`input`,{type:`date`,value:e.period.end?.slice(0,10)??``,onChange:e=>r({end:e.target.value}),"aria-label":`Custom period end date`})]})]}):null]}),(0,z.jsxs)(`div`,{className:`share-knob`,children:[(0,z.jsx)(`span`,{className:`share-knob-label`,children:`Theme`}),(0,z.jsxs)(`div`,{className:`share-knob-radiogroup`,role:`radiogroup`,"aria-label":`Theme`,children:[(0,z.jsxs)(`label`,{className:`share-knob-radio`,children:[(0,z.jsx)(`input`,{type:`radio`,name:`share-theme`,value:`light`,checked:e.theme===`light`,onChange:()=>n({theme:`light`})}),(0,z.jsx)(`span`,{children:`Light`})]}),(0,z.jsxs)(`label`,{className:`share-knob-radio`,children:[(0,z.jsx)(`input`,{type:`radio`,name:`share-theme`,value:`dark`,checked:e.theme===`dark`,onChange:()=>n({theme:`dark`})}),(0,z.jsx)(`span`,{children:`Dark`})]})]})]}),(0,z.jsxs)(`div`,{className:`share-knob`,children:[(0,z.jsx)(`label`,{htmlFor:`share-knob-topn`,children:`Top-N`}),(0,z.jsx)(`input`,{id:`share-knob-topn`,type:`number`,min:1,step:1,inputMode:`numeric`,value:e.top_n??``,onChange:e=>i(e.target.value),"aria-label":`Top-N`})]}),(0,z.jsxs)(`div`,{className:`share-knob`,children:[(0,z.jsx)(`span`,{className:`share-knob-label`,children:`Projects`}),(0,z.jsx)(`button`,{type:`button`,className:`share-knob-allowlist-stub`,disabled:!0,"aria-disabled":`true`,title:`Project allowlist — coming in M3+`,children:`All projects`})]}),(0,z.jsx)(`div`,{className:`share-knob`,children:(0,z.jsxs)(`label`,{className:`share-knob-checkbox`,children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:e.show_chart,onChange:e=>n({show_chart:e.target.checked}),"aria-label":`Include chart in export`}),(0,z.jsx)(`span`,{children:`Show chart`})]})}),(0,z.jsx)(`div`,{className:`share-knob`,children:(0,z.jsxs)(`label`,{className:`share-knob-checkbox`,children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:e.show_table,onChange:e=>n({show_table:e.target.checked}),"aria-label":`Include table in export`}),(0,z.jsx)(`span`,{children:`Show table`})]})}),(0,z.jsx)(`div`,{className:`share-knob`,children:(0,z.jsxs)(`label`,{className:`share-knob-checkbox`,children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:!e.reveal_projects,onChange:e=>n({reveal_projects:!e.target.checked}),"aria-label":`Anonymize project names on export`}),(0,z.jsx)(`span`,{children:`Anon on export`})]})})]})}var nc=200,rc={status:`idle`,body:``,contentType:``,errorMessage:null,errorField:null};function ic({panel:e,templateId:t,options:n}){let[r,i]=(0,g.useState)(rc),a=(0,g.useRef)(null),o=(0,g.useRef)(0);return(0,g.useEffect)(()=>{if(!t){i(rc);return}i(e=>({...e,status:`loading`}));let r=++o.current,s=setTimeout(()=>{a.current?.abort();let s=new AbortController;a.current=s,Zs({panel:e,template_id:t,options:{...n,reveal_projects:!0}},{signal:s.signal}).then(e=>{r===o.current&&i({status:`ready`,body:e.body,contentType:e.content_type,errorMessage:null,errorField:null})}).catch(e=>{if(r===o.current&&!(e&&typeof e==`object`&&e.name===`AbortError`)){if(e instanceof X){i({status:`error`,body:``,contentType:``,errorMessage:e.message??`HTTP ${e.status}`,errorField:e.field??null});return}i({status:`error`,body:``,contentType:``,errorMessage:e.message??`Unknown error`,errorField:null})}})},nc);return()=>{clearTimeout(s)}},[e,t,n]),(0,g.useEffect)(()=>()=>{a.current?.abort()},[]),t?r.status===`error`?(0,z.jsxs)(`div`,{className:`share-preview share-preview-error`,role:`alert`,children:[(0,z.jsx)(`div`,{className:`share-preview-error-title`,children:`Preview failed`}),(0,z.jsxs)(`div`,{className:`share-preview-error-message`,children:[r.errorMessage,r.errorField?(0,z.jsxs)(`span`,{className:`share-preview-error-field`,children:[` `,`(field: `,r.errorField,`)`]}):null]})]}):r.status===`loading`||r.status===`idle`?(0,z.jsx)(`div`,{className:`share-preview share-preview-loading`,"aria-busy":`true`,children:`Rendering preview…`}):n.format===`md`?(0,z.jsx)(`pre`,{className:`share-preview share-preview-md`,"aria-label":`Markdown preview`,children:r.body}):(0,z.jsx)(`iframe`,{className:`share-preview share-preview-iframe`,title:`Report preview (decorative)`,tabIndex:-1,sandbox:`allow-same-origin`,srcDoc:r.body}):(0,z.jsx)(`div`,{className:`share-preview share-preview-empty`,children:`Select a template to preview.`})}var ac={"current-week":`Current week`,trend:`Trend`,weekly:`Weekly`,daily:`Daily`,monthly:`Monthly`,blocks:`5-hour blocks`,forecast:`Forecast`,sessions:`Sessions`,projects:`Projects`};function oc(e){return ac[e]}function sc(e){switch(e){case`md`:return`md`;case`html`:return`html`;case`svg`:return`svg`}}async function cc(e){if(!e.ok){let t={};try{t=await e.json()}catch{}throw new X(e.status,t.field,t.error??`HTTP ${e.status}`)}return e.json()}async function lc(e){return cc(await fetch(`/api/share/presets`,{signal:e?.signal}))}async function uc(e,t){return cc(await fetch(`/api/share/presets`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),signal:t?.signal}))}async function dc(e,t,n){let r=await fetch(`/api/share/presets/${encodeURIComponent(e)}/${encodeURIComponent(t)}`,{method:`DELETE`,signal:n?.signal});if(!r.ok){let e={};try{e=await r.json()}catch{}throw new X(r.status,void 0,e.error??`HTTP ${r.status}`)}}async function fc(e){return cc(await fetch(`/api/share/history`,{signal:e?.signal}))}async function Z(e,t){return cc(await fetch(`/api/share/history`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),signal:t?.signal}))}function pc({panel:e,templateId:t,options:n,onSaved:r,onCancel:i}){let[a,o]=(0,g.useState)(``),[s,c]=(0,g.useState)(!1),[l,u]=(0,g.useState)(null);async function d(){let i=a.trim();if(!i){u(`Name is required`);return}if(i.length>64){u(`Name must be 64 characters or fewer`);return}if(i.includes(`/`)){u(`Name cannot contain '/'`);return}c(!0),u(null);try{await uc({panel:e,name:i,template_id:t,options:n}),R({type:`SHOW_STATUS_TOAST`,text:`Saved preset "${i}"`}),r()}catch(e){u((e instanceof X?e.message??`HTTP ${e.status}`:e.message)??`Save failed`)}finally{c(!1)}}return(0,z.jsxs)(`div`,{className:`share-save-popover`,role:`dialog`,"aria-label":`Save preset`,children:[(0,z.jsxs)(`label`,{className:`share-save-label`,children:[`Preset name`,(0,z.jsx)(`input`,{type:`text`,className:`share-save-input`,autoFocus:!0,value:a,maxLength:64,disabled:s,onChange:e=>o(e.target.value),onKeyDown:e=>{e.key===`Enter`?(e.preventDefault(),e.stopPropagation(),d()):e.key===`Escape`&&(e.preventDefault(),e.stopPropagation(),i())}})]}),l?(0,z.jsx)(`div`,{className:`share-save-error`,role:`alert`,children:l}):null,(0,z.jsxs)(`div`,{className:`share-save-actions`,children:[(0,z.jsx)(`button`,{type:`button`,onClick:i,disabled:s,children:`Cancel`}),(0,z.jsx)(`button`,{type:`button`,onClick:()=>void d(),disabled:s,children:s?`Saving…`:`Save`})]})]})}async function mc(e,t,n){let r=new Blob([e],{type:`image/svg+xml`}),i=URL.createObjectURL(r);try{let e=new Image;e.src=i,await e.decode();let r=document.createElement(`canvas`);r.width=e.naturalWidth*t,r.height=e.naturalHeight*t;let a=r.getContext(`2d`);if(!a)throw Error(`Could not acquire 2D canvas context`);a.fillStyle=n,a.fillRect(0,0,r.width,r.height),a.scale(t,t),a.drawImage(e,0,0);let o=await new Promise(e=>{r.toBlob(t=>e(t),`image/png`)});if(o)return o;let s=r.toDataURL(`image/png`);return(await fetch(s)).blob()}finally{URL.revokeObjectURL(i)}}function hc(e){let t=document.createElement(`iframe`);t.setAttribute(`aria-hidden`,`true`),t.style.cssText=`position:fixed;right:0;bottom:0;width:0;height:0;border:0`,document.body.appendChild(t);let n=t.contentDocument;if(!n)throw Error(`iframe contentDocument unavailable`);n.open(),n.write(e),n.close();try{t.contentWindow?.focus(),t.contentWindow?.print()}catch{let t=window.open(``,`_blank`,`noopener,noreferrer`);t&&(t.document.open(),t.document.write(e),t.document.close())}setTimeout(()=>t.remove(),1e3)}function gc(e){Z({panel:e.panel,template_id:e.template_id,options:e.options,format:e.options.format,destination:e.destination}).catch(()=>{})}function _c(e){return e===`light`?`#ffffff`:`#0f172a`}function vc(e,t){return`cctally-${e}-${new Date().toISOString().slice(0,10).replaceAll(`-`,``)}.${sc(t)}`}function yc(e){switch(e){case`md`:return`text/markdown;charset=utf-8`;case`html`:return`text/html;charset=utf-8`;case`svg`:return`image/svg+xml;charset=utf-8`}}function bc(e,t){let n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=e,r.style.display=`none`,document.body.appendChild(r),r.click(),document.body.removeChild(r),setTimeout(()=>URL.revokeObjectURL(n),0)}function xc({panel:e,templateId:t,options:n,onOptionsChange:r}){let[i,a]=(0,g.useState)(null),[o,s]=(0,g.useState)(null),[c,l]=(0,g.useState)(!1),u=(0,g.useRef)(null);(0,g.useEffect)(()=>()=>{u.current!=null&&clearTimeout(u.current)},[]);let[d,f]=(0,g.useState)(!1),p=(0,g.useRef)(null);(0,g.useEffect)(()=>{if(!d)return;function e(e){let t=p.current;t&&(t.contains(e.target)||f(!1))}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[d]),(0,g.useEffect)(()=>{s(null)},[n.format,t]);let m=t==null||i!=null,h=e=>R({type:`SHOW_STATUS_TOAST`,text:e}),_=async()=>{if(!t)throw Error(`no template selected`);return{body:(await Zs({panel:e,template_id:t,options:n})).body,format:n.format}},v=async()=>{if(!(m||!t)){a(`copy`),s(null);try{let{body:r}=await _();if(!navigator.clipboard||typeof navigator.clipboard.writeText!=`function`)throw Error(`Clipboard API unavailable in this browser`);await navigator.clipboard.writeText(r),h(`Copied`),gc({panel:e,template_id:t,options:n,destination:`copy`})}catch(e){s(`Copy failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},y=async()=>{if(!(m||!t)){a(`download`),s(null);try{let{body:r,format:i}=await _(),a=new Blob([r],{type:yc(i)});bc(vc(e,i),a),h(`Downloaded`),gc({panel:e,template_id:t,options:n,destination:`download`})}catch(e){s(`Download failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},b=async()=>{if(!(m||!t)){a(`basket`),s(null);try{let r=await Zs({panel:e,template_id:t,options:n}),i=xe({panel:e,template_id:t,options:n,added_at:new Date().toISOString(),data_digest_at_add:r.snapshot.data_digest,kernel_version:r.snapshot.kernel_version,label_hint:oc(e)});R({type:`BASKET_ADD`,item:i});let a=I().basket;if(a.rejectedReason===`capacity`)return;l(!0),u.current!=null&&clearTimeout(u.current),u.current=setTimeout(()=>l(!1),800),R({type:`SHOW_STATUS_TOAST`,text:`Added ${i.label_hint} to basket (${a.items.length})`})}catch(e){s(`Add to basket failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},x=async()=>{if(!(m||!t)){a(`open`),s(null);try{let{body:r,format:i}=await _(),a=new Blob([r],{type:yc(i)}),o=URL.createObjectURL(a);window.open(o,`_blank`,`noopener,noreferrer`),gc({panel:e,template_id:t,options:n,destination:`open`})}catch(e){s(`Open failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},S=async()=>{if(!(!t||n.format!==`svg`||m)){a(`png`),s(null);try{let{body:r}=await _(),i=await mc(r,2,_c(n.theme));bc(vc(e,`svg`).replace(/\.svg$/,`.png`),i),h(`PNG downloaded`),gc({panel:e,template_id:t,options:n,destination:`png`})}catch(e){s(`PNG export failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},C=async()=>{if(!(!t||n.format!==`html`||m)){a(`print`),s(null);try{let{body:r}=await _();hc(r),gc({panel:e,template_id:t,options:n,destination:`print`})}catch(e){s(`Print failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{a(null)}}},w=n.format===`md`&&!m,T=(n.format===`html`||n.format===`svg`)&&!m,ee=n.format===`svg`&&!m,te=n.format===`html`&&!m;return(0,z.jsxs)(`div`,{className:`share-actions`,children:[(0,z.jsxs)(`div`,{className:`share-format-row`,role:`radiogroup`,"aria-label":`Export format`,children:[(0,z.jsx)(`span`,{className:`share-format-label`,children:`Format:`}),[`md`,`html`,`svg`].map(e=>(0,z.jsxs)(`label`,{className:`share-format-radio`,children:[(0,z.jsx)(`input`,{type:`radio`,name:`share-format`,value:e,checked:n.format===e,onChange:()=>r({...n,format:e})}),(0,z.jsx)(`span`,{children:e})]},e))]}),(0,z.jsxs)(`div`,{className:`share-action-row`,children:[(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-copy`,onClick:v,disabled:!w,title:n.format===`md`?i===`copy`?`Copying…`:`Copy to clipboard`:`Copy is available for Markdown only`,children:i===`copy`?`Copying…`:`Copy`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-download`,onClick:y,disabled:m,title:i===`download`?`Downloading…`:`Download file`,children:i===`download`?`Downloading…`:`Download`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-open`,onClick:x,disabled:!T,title:n.format===`html`||n.format===`svg`?i===`open`?`Opening…`:`Open in new tab`:`Open is available for HTML/SVG`,children:i===`open`?`Opening…`:`Open`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-png`,onClick:S,disabled:!ee,title:n.format===`svg`?i===`png`?`Rasterizing…`:`Download PNG (rasterized from SVG)`:`PNG export — available for SVG format only`,children:i===`png`?`Rasterizing…`:`PNG`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-print`,onClick:C,disabled:!te,title:n.format===`html`?i===`print`?`Opening print dialog…`:`Open the browser print dialog (save as PDF)`:`Print → PDF — available for HTML format only`,children:i===`print`?`Printing…`:`Print → PDF`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-basket${c?` share-action-basket-added`:``}`,onClick:b,disabled:m,title:m&&t==null?`Pick a template first`:i===`basket`?`Adding to basket…`:`Add this section to the report basket`,children:c?`✓ Added`:i===`basket`?`Adding…`:`+ Basket`})]}),(0,z.jsxs)(`div`,{className:`share-save-preset-row`,ref:p,children:[(0,z.jsx)(`button`,{type:`button`,className:`share-save-preset`,disabled:t==null||i!=null,onClick:()=>f(e=>!e),"aria-haspopup":`dialog`,"aria-expanded":d,title:t==null?`Pick a template first`:`Save the current recipe as a named preset`,children:`Save preset…`}),d&&t?(0,z.jsx)(pc,{panel:e,templateId:t,options:n,onSaved:()=>f(!1),onCancel:()=>f(!1)}):null]}),o?(0,z.jsx)(`div`,{className:`share-action-error`,role:`alert`,children:o}):null]})}function Sc(e){let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString()}function Cc({panel:e,onPick:t,onManage:n}){let[r,i]=(0,g.useState)(!1),[a,o]=(0,g.useState)({}),[s,c]=(0,g.useState)([]),[l,u]=(0,g.useState)(null),d=(0,g.useRef)(null);(0,g.useEffect)(()=>{if(!r)return;let t=new AbortController;return u(null),Promise.all([lc({signal:t.signal}),fc({signal:t.signal})]).then(([t,n])=>{o(t.presets[e]??{}),c(n.history.filter(t=>t.panel===e).slice().reverse())}).catch(e=>{e?.name!==`AbortError`&&u((e instanceof X?e.message??`HTTP ${e.status}`:e.message)??`Failed to load presets`)}),()=>t.abort()},[r,e]),(0,g.useEffect)(()=>{if(!r)return;function e(e){let t=d.current;t&&(t.contains(e.target)||i(!1))}return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[r]);let f=Object.keys(a).sort();return(0,z.jsxs)(`div`,{className:`share-presets-dropdown`,ref:d,children:[(0,z.jsx)(`button`,{type:`button`,className:`share-presets-trigger`,"aria-haspopup":`menu`,"aria-expanded":r,onClick:()=>i(e=>!e),children:`presets ▾`}),r?(0,z.jsxs)(`div`,{className:`share-presets-menu`,role:`menu`,children:[l?(0,z.jsx)(`div`,{className:`share-presets-error`,role:`alert`,children:l}):null,f.length===0&&!l?(0,z.jsx)(`div`,{className:`share-presets-empty`,children:`No saved presets yet.`}):null,f.length>0?(0,z.jsx)(`ul`,{className:`share-presets-list`,children:f.map(e=>(0,z.jsx)(`li`,{children:(0,z.jsx)(`button`,{type:`button`,role:`menuitem`,className:`share-presets-item`,onClick:()=>{t(a[e].template_id,a[e].options),i(!1)},children:e})},e))}):null,s.length>0?(0,z.jsxs)(`div`,{className:`share-presets-history`,children:[(0,z.jsx)(`div`,{className:`share-presets-history-heading`,role:`presentation`,children:`Recent shares`}),(0,z.jsx)(`ul`,{className:`share-presets-history-list`,children:s.map(e=>(0,z.jsx)(`li`,{children:(0,z.jsxs)(`button`,{type:`button`,role:`menuitem`,className:`share-presets-history-item`,onClick:()=>{t(e.template_id,e.options),i(!1)},title:`${e.template_id} · ${e.format??`unknown`} · ${e.exported_at}`,children:[(0,z.jsx)(`span`,{className:`share-presets-history-template`,children:e.template_id}),(0,z.jsxs)(`span`,{className:`share-presets-history-meta`,children:[` · `,e.format??`unknown`,` · `,Sc(e.exported_at)]})]})},e.recipe_id))})]}):null,(0,z.jsx)(`div`,{className:`share-presets-footer`,children:(0,z.jsx)(`button`,{type:`button`,role:`menuitem`,className:`share-presets-manage`,onClick:()=>{n(),i(!1)},children:`Manage presets…`})})]}):null]})}var wc=`share-manage-presets-title`;function Tc({open:e,onClose:t}){let[n,r]=(0,g.useState)([]),[i,a]=(0,g.useState)(!1),[o,s]=(0,g.useState)(null);V((0,g.useMemo)(()=>e?[{key:`Escape`,scope:`modal`,action:t}]:[],[e,t]));let c=(0,g.useRef)(null),l=(0,g.useRef)(!1);(0,g.useEffect)(()=>{if(e)l.current||(l.current=!0,c.current=document.activeElement);else if(l.current){l.current=!1;let e=c.current;if(c.current=null,e&&typeof e.focus==`function`&&document.contains(e))e.focus();else{let e=document.activeElement;e&&typeof e.blur==`function`&&e.blur(),document.body.focus()}}},[e]),(0,g.useEffect)(()=>{if(!e)return;let t=!1;return s(null),(async()=>{try{let e=await lc();if(t)return;let n=[];for(let[t,r]of Object.entries(e.presets))for(let[e,i]of Object.entries(r))n.push({panel:t,name:e,record:i});n.sort((e,t)=>e.panel===t.panel?e.name.localeCompare(t.name):e.panel.localeCompare(t.panel)),r(n)}catch(e){if(t)return;s((e instanceof X?e.message??`HTTP ${e.status}`:e.message)??`Failed to load presets`)}})(),()=>{t=!0}},[e]);async function u(e){a(!0),s(null);try{await dc(e.panel,e.name),r(t=>t.filter(t=>!(t.panel===e.panel&&t.name===e.name))),R({type:`SHOW_STATUS_TOAST`,text:`Deleted preset "${e.name}"`})}catch(e){s((e instanceof X?e.message??`HTTP ${e.status}`:e.message)??`Delete failed`)}finally{a(!1)}}async function d(e,t){a(!0),s(null);try{await uc({panel:e.panel,name:t,template_id:e.record.template_id,options:e.record.options}),await dc(e.panel,e.name),r(n=>n.map(n=>n.panel===e.panel&&n.name===e.name?{...n,name:t}:n)),R({type:`SHOW_STATUS_TOAST`,text:`Renamed to "${t}"`})}catch(e){s((e instanceof X?e.message??`HTTP ${e.status}`:e.message)??`Rename failed`)}finally{a(!1)}}return e?(0,z.jsxs)(`div`,{className:`share-manage-modal`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":wc,onClick:e=>e.stopPropagation(),children:[(0,z.jsxs)(`div`,{className:`share-manage-header`,children:[(0,z.jsx)(`h2`,{id:wc,children:`Manage presets`}),(0,z.jsx)(`button`,{type:`button`,onClick:t,"aria-label":`Close`,className:`share-manage-close`,children:`⤬`})]}),o?(0,z.jsx)(`div`,{className:`share-manage-error`,role:`alert`,children:o}):null,n.length===0&&!o?(0,z.jsx)(`p`,{className:`share-manage-empty`,children:`No saved presets yet.`}):null,n.length>0?(0,z.jsxs)(`table`,{className:`share-manage-table`,children:[(0,z.jsx)(`thead`,{children:(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`th`,{children:`Panel`}),(0,z.jsx)(`th`,{children:`Name`}),(0,z.jsx)(`th`,{children:`Saved at`}),(0,z.jsx)(`th`,{})]})}),(0,z.jsx)(`tbody`,{children:n.map(e=>(0,z.jsx)(Ec,{row:e,busy:i,onDelete:()=>void u(e),onRename:t=>void d(e,t)},`${e.panel}/${e.name}`))})]}):null]}):null}function Ec({row:e,busy:t,onDelete:n,onRename:r}){let[i,a]=(0,g.useState)(!1),[o,s]=(0,g.useState)(e.name),c=()=>{let t=o.trim();if(!t||t===e.name){s(e.name),a(!1);return}r(t),a(!1)};return(0,z.jsxs)(`tr`,{children:[(0,z.jsx)(`td`,{children:oc(e.panel)}),(0,z.jsx)(`td`,{children:i?(0,z.jsx)(`input`,{className:`share-manage-name-input`,autoFocus:!0,value:o,disabled:t,maxLength:64,onChange:e=>s(e.target.value),onKeyDown:t=>{t.key===`Enter`?(t.preventDefault(),c()):t.key===`Escape`&&(t.preventDefault(),t.stopPropagation(),s(e.name),a(!1))}}):(0,z.jsx)(`span`,{children:e.name})}),(0,z.jsx)(`td`,{children:e.record.saved_at}),(0,z.jsxs)(`td`,{className:`share-manage-actions`,children:[(0,z.jsx)(`button`,{type:`button`,disabled:t,onClick:()=>{i?(s(e.name),a(!1)):a(!0)},children:i?`Cancel`:`Rename`}),(0,z.jsx)(`button`,{type:`button`,disabled:t,onClick:n,children:`Delete`})]})]})}function Dc(){return{format:`md`,theme:`light`,reveal_projects:!1,no_branding:!1,top_n:5,period:{kind:`current`},project_allowlist:null,show_chart:!0,show_table:!0}}function Oc(e,t){if(!t)return e;let n={...e,...t};return t.period&&(n.period={...e.period,...t.period}),n}function kc({panel:e,onClose:t,initialParams:n}){let r=oc(e),[i,a]=(0,g.useState)(null),[o,s]=(0,g.useState)(null),[c,l]=(0,g.useState)(null),[u,d]=(0,g.useState)(()=>{let e=Dc();return n?.windowWeeks==null?e:{...e,windowWeeks:n.windowWeeks}}),f=(0,g.useRef)(!1),[p,m]=(0,g.useState)(!1),h=`share-modal-title`;V((0,g.useMemo)(()=>[{key:`Escape`,scope:`overlay`,when:()=>!p&&I().composerModal===null,action:t}],[t,p])),(0,g.useEffect)(()=>{let t=!1;return a(null),s(null),Xs(e).then(e=>{if(t)return;a(e.templates);let n=e.templates[0];n&&(l(n.id),f.current||d(e=>Oc(e,n.default_options)))}).catch(e=>{t||s(e instanceof X?`Couldn't load templates: ${e.message??`HTTP ${e.status}`}`:`Couldn't load templates: ${e.message}`)}),()=>{t=!0}},[e]),(0,g.useEffect)(()=>{if(!i||!c||f.current)return;let e=i.find(e=>e.id===c);e&&d(t=>Oc(t,e.default_options))},[c,i]);let _=e=>{f.current=!0,d(e)};return(0,z.jsxs)(`div`,{className:`share-modal`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":h,onClick:e=>e.stopPropagation(),children:[(0,z.jsx)(`header`,{className:`share-modal-header`,children:(0,z.jsxs)(`h2`,{id:h,children:[`Share `,r,` report`]})}),(0,z.jsxs)(`div`,{className:`share-modal-body`,children:[(0,z.jsxs)(`section`,{className:`share-section share-gallery-section`,"aria-label":`Template gallery`,children:[(0,z.jsx)(`div`,{className:`share-gallery-header`,children:(0,z.jsx)(Cc,{panel:e,onPick:(e,t)=>{l(e),f.current=!0,d(e=>({...e,...t}))},onManage:()=>m(!0)})}),(0,z.jsx)(ec,{panel:e,templates:i,error:o,selectedTemplateId:c,onSelect:e=>l(e)})]}),(0,z.jsxs)(`section`,{className:`share-section share-main-section`,children:[(0,z.jsx)(`div`,{className:`share-knobs-col`,"aria-label":`Render options`,children:(0,z.jsx)(tc,{options:u,onChange:_})}),(0,z.jsx)(`div`,{className:`share-preview-col`,"aria-label":`Live preview`,children:(0,z.jsx)(ic,{panel:e,templateId:c,options:u})})]})]}),(0,z.jsx)(`footer`,{className:`share-modal-footer`,children:(0,z.jsx)(xc,{panel:e,templateId:c,options:u,onOptionsChange:_})}),(0,z.jsx)(`button`,{type:`button`,className:`share-modal-close`,"aria-label":`Close share modal`,onClick:t,children:`⤬`}),(0,z.jsx)(Tc,{open:p,onClose:()=>m(!1)})]})}function Ac(e,t){return{title:t.title,theme:t.theme,format:t.format,no_branding:t.no_branding,reveal_projects:t.reveal_projects,sections:e.map(e=>({snapshot:{panel:e.panel,template_id:e.template_id,options:e.options,data_digest_at_add:e.data_digest_at_add,kernel_version:e.kernel_version}}))}}async function jc(e,t){let n=await fetch(`/api/share/compose`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e),signal:t?.signal});if(!n.ok){let e={};try{e=await n.json()}catch{}throw new X(n.status,e.field,e.error??`HTTP ${n.status}`,e.code)}return n.json()}function Mc({items:e,results:t,kernelVersion:n,onRefresh:r,onRemove:i,onPreviewOnly:a}){let o=jr(Ar(ji,{activationConstraint:{distance:4}}),Ar(Ei,{coordinateGetter:eo}));function s(t){if(!t.over||t.active.id===t.over.id)return;let n=e.findIndex(e=>e.id===t.active.id),r=e.findIndex(e=>e.id===t.over.id);n<0||r<0||R({type:`BASKET_REORDER`,fromIdx:n,toIdx:r})}return(0,z.jsx)(Ta,{sensors:o,collisionDetection:zr,onDragEnd:s,children:(0,z.jsx)(Ha,{items:e.map(e=>e.id),strategy:za,children:(0,z.jsx)(`ul`,{className:`composer-section-list`,children:e.map((e,o)=>(0,z.jsx)(Nc,{item:e,result:t[o],kernelVersion:n,onRefresh:r,onRemove:i,onPreviewOnly:a},e.id))})})})}function Nc({item:e,result:t,kernelVersion:n,onRefresh:r,onRemove:i,onPreviewOnly:a}){let{attributes:o,listeners:s,setNodeRef:c,transform:l,transition:u,isDragging:d}=Xa({id:e.id}),f=so(),p={transform:gr.Transform.toString(l),transition:f?void 0:u,opacity:d?.4:1},[m,h]=(0,g.useState)(!1),_=t?.drift_detected,v=e.kernel_version!==n,y=!!(_||v);return(0,z.jsxs)(`li`,{ref:c,style:p,className:`composer-section-row`,children:[(0,z.jsx)(`button`,{className:`composer-drag-handle`,"aria-label":`Reorder ${e.label_hint}`,type:`button`,...o,...s,children:`≡`}),(0,z.jsx)(`span`,{className:`composer-section-label`,children:e.label_hint}),y?(0,z.jsx)(`span`,{className:`composer-outdated-badge`,title:_&&v?`Data and kernel both shifted since add-time. Refresh to update.`:_?`Data has changed since this section was added. Refresh to update.`:`Kernel updated since this section was added. Refresh to re-render at the new version.`,children:`Outdated`}):null,(0,z.jsxs)(`div`,{className:`composer-section-actions`,children:[(0,z.jsx)(`button`,{type:`button`,"aria-haspopup":`menu`,"aria-expanded":m,onClick:()=>h(e=>!e),"aria-label":`Actions for ${e.label_hint}`,children:`⋯`}),m?(0,z.jsxs)(`ul`,{role:`menu`,className:`composer-section-menu`,children:[(0,z.jsx)(`li`,{children:(0,z.jsx)(`button`,{type:`button`,onClick:()=>{a(e.id),h(!1)},children:`Preview only this`})}),(0,z.jsx)(`li`,{children:(0,z.jsx)(`button`,{type:`button`,onClick:()=>{r(e.id),h(!1)},children:`Refresh from current data`})}),(0,z.jsx)(`li`,{children:(0,z.jsx)(`button`,{type:`button`,onClick:()=>{i(e.id),h(!1)},"aria-label":`Remove ${e.label_hint}`,children:`Remove`})})]}):null]})]})}function Pc(e,t){return t&&e>0}function Fc(e){return`cctally-report-${new Date().toISOString().slice(0,10).replaceAll(`-`,``)}.${e===`md`?`md`:e}`}function Ic(e){switch(e){case`md`:return`text/markdown;charset=utf-8`;case`html`:return`text/html;charset=utf-8`;case`svg`:return`image/svg+xml;charset=utf-8`}}function Lc(e){return e===`light`?`#ffffff`:`#0f172a`}function Rc(e,t){let n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=e,r.style.display=`none`,document.body.appendChild(r),r.click(),document.body.removeChild(r),setTimeout(()=>URL.revokeObjectURL(n),0)}var zc=200;function Bc(){return I().composerModal}function Vc(){return I().basket}var Q=`composer-modal-title`;function Hc(){let e=(0,g.useSyncExternalStore)(L,Bc),t=(0,g.useSyncExternalStore)(L,Vc),n=on(),r=(0,g.useRef)(null),i=(0,g.useRef)(!1),[a,o]=(0,g.useState)(``),[s,c]=(0,g.useState)(`light`),[l,u]=(0,g.useState)(`html`),[d,f]=(0,g.useState)(!0),[p,m]=(0,g.useState)(!1),[h,_]=(0,g.useState)(null),[v,y]=(0,g.useState)(null),[b,x]=(0,g.useState)(!1),S=(0,g.useRef)(null),[C,w]=(0,g.useState)(null),[T,ee]=(0,g.useState)(null);(0,g.useEffect)(()=>{ee(null)},[l,s,d,p]),V((0,g.useMemo)(()=>[{key:`Escape`,scope:`overlay`,when:()=>I().composerModal!==null,action:()=>R(ve())}],[])),(0,g.useEffect)(()=>{e?.open&&a===``&&o(`cctally report — ${new Date().toISOString().slice(0,10)}`)},[e?.open,a]),(0,g.useEffect)(()=>{if(e?.open)i.current||(i.current=!0,r.current=document.activeElement);else if(i.current){i.current=!1;let e=r.current;if(r.current=null,e&&typeof e.focus==`function`&&document.contains(e))e.focus();else{let e=document.activeElement;e&&typeof e.blur==`function`&&e.blur(),document.body.focus()}}},[e?.open]),(0,g.useEffect)(()=>{if(!e?.open||t.items.length===0||a===``)return;let n=setTimeout(()=>{S.current?.abort();let e=new AbortController;S.current=e,x(!0),y(null),jc(Ac(t.items,{title:a,theme:s,format:l,no_branding:p,reveal_projects:!d}),{signal:e.signal}).then(t=>{e.signal.aborted||_(t)}).catch(t=>{t?.name!==`AbortError`&&(e.signal.aborted||y(t instanceof X?t.message??`HTTP ${t.status}`:t.message))}).finally(()=>{e.signal.aborted||x(!1)})},zc);return()=>clearTimeout(n)},[e?.open,t.items,a,s,l,d,p]);async function te(e){let n=t.items.findIndex(t=>t.id===e);if(n<0)return;let r=t.items[n];try{let t=await Zs({panel:r.panel,template_id:r.template_id,options:{...r.options,reveal_projects:!d}}),i=xe({panel:r.panel,template_id:r.template_id,options:r.options,added_at:new Date().toISOString(),data_digest_at_add:t.snapshot.data_digest,kernel_version:t.snapshot.kernel_version,label_hint:r.label_hint,id:r.id});R({type:`BASKET_REMOVE`,id:e}),R({type:`BASKET_ADD`,item:i});let a=I().basket.items.length-1;a!==n&&R({type:`BASKET_REORDER`,fromIdx:a,toIdx:n})}catch(e){y(`Refresh failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}}let E=async e=>{let n=await jc(Ac(t.items,{title:a,theme:s,format:e,no_branding:p,reveal_projects:!d}));return{body:n.body,content_type:n.content_type}},D=e=>R({type:`SHOW_STATUS_TOAST`,text:e}),O=async(e,t,n)=>{if(C==null){w(e),ee(null);try{await t()}catch(e){ee(`${n} failed: ${e instanceof X?e.message??`HTTP ${e.status}`:e.message}`)}finally{w(null)}}},ne=()=>O(`copy`,async()=>{let{body:e}=await E(`md`);if(!navigator.clipboard||typeof navigator.clipboard.writeText!=`function`)throw Error(`Clipboard API unavailable in this browser`);await navigator.clipboard.writeText(e),D(`Copied`)},`Copy`),k=()=>O(`download`,async()=>{let{body:e}=await E(l),t=new Blob([e],{type:Ic(l)});Rc(Fc(l),t),D(`Downloaded`)},`Download`),re=()=>O(`open`,async()=>{let{body:e}=await E(l),t=new Blob([e],{type:Ic(l)}),n=URL.createObjectURL(t);window.open(n,`_blank`,`noopener,noreferrer`)},`Open`),A=()=>O(`png`,async()=>{let{body:e}=await E(`svg`),t=await mc(e,2,Lc(s));Rc(Fc(`svg`).replace(/\.svg$/,`.png`),t),D(`PNG downloaded`)},`PNG export`),ie=()=>O(`print`,async()=>{let{body:e}=await E(`html`);hc(e)},`Print`),ae=C==null&&l===`md`&&t.items.length>0,oe=C==null&&t.items.length>0,se=C==null&&(l===`html`||l===`svg`)&&t.items.length>0,j=C==null&&l===`svg`&&t.items.length>0,ce=C==null&&l===`html`&&t.items.length>0,le=!d,ue=Pc(t.items.length,le),de=le?t.items.length:0;return e?.open?t.items.length===0?(0,z.jsxs)(`div`,{className:`composer-modal composer-modal-empty${n?` composer-modal-mobile`:``}`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":Q,children:[(0,z.jsxs)(`header`,{className:`composer-modal-header`,children:[(0,z.jsx)(`h2`,{id:Q,children:`Compose report`}),(0,z.jsx)(`button`,{type:`button`,className:`composer-modal-close`,onClick:()=>R(ve()),"aria-label":`Close`,children:`⤬`})]}),(0,z.jsx)(`p`,{className:`composer-empty-message`,children:`Basket is empty. Open any panel's share menu and pick + Basket to add a section.`})]}):(0,z.jsxs)(`div`,{className:`composer-modal${n?` composer-modal-mobile`:``}`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":Q,children:[(0,z.jsxs)(`header`,{className:`composer-modal-header`,children:[(0,z.jsx)(`h2`,{id:Q,children:`Compose report`}),(0,z.jsx)(`button`,{type:`button`,className:`composer-modal-close`,onClick:()=>R(ve()),"aria-label":`Close`,children:`⤬`})]}),(0,z.jsxs)(`div`,{className:`composer-knobs`,children:[(0,z.jsxs)(`label`,{children:[`Title`,(0,z.jsx)(`input`,{type:`text`,value:a,onChange:e=>o(e.target.value)})]}),(0,z.jsxs)(`label`,{children:[`Theme`,(0,z.jsxs)(`select`,{value:s,onChange:e=>c(e.target.value),children:[(0,z.jsx)(`option`,{value:`light`,children:`light`}),(0,z.jsx)(`option`,{value:`dark`,children:`dark`})]})]}),(0,z.jsxs)(`label`,{children:[`Format`,(0,z.jsxs)(`select`,{value:l,onChange:e=>u(e.target.value),children:[(0,z.jsx)(`option`,{value:`html`,children:`html`}),(0,z.jsx)(`option`,{value:`md`,children:`md`}),(0,z.jsx)(`option`,{value:`svg`,children:`svg`})]})]}),(0,z.jsxs)(`label`,{children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:d,onChange:e=>f(e.target.checked)}),`Anon on export`]}),(0,z.jsxs)(`label`,{children:[(0,z.jsx)(`input`,{type:`checkbox`,checked:p,onChange:e=>m(e.target.checked)}),`No branding`]})]}),ue?(0,z.jsxs)(`div`,{className:`composer-anon-banner`,role:`status`,"aria-live":`polite`,children:[(0,z.jsxs)(`span`,{children:[de,` section`,de===1?``:`s`,` contain real project names. They will appear in the export.`]}),(0,z.jsx)(`button`,{type:`button`,onClick:()=>f(!0),children:`Anonymize all`})]}):null,(0,z.jsxs)(`div`,{className:`composer-body`,children:[(0,z.jsx)(Mc,{items:t.items,results:h?.snapshot.section_results??[],kernelVersion:h?.snapshot.kernel_version??1,onRefresh:e=>{te(e)},onRemove:e=>R({type:`BASKET_REMOVE`,id:e}),onPreviewOnly:e=>{}}),(0,z.jsx)(`iframe`,{className:`composer-preview`,title:`Combined preview`,tabIndex:-1,sandbox:`allow-same-origin`,srcDoc:h?.body??`<p>Composing&hellip;</p>`})]}),b?(0,z.jsx)(`div`,{className:`composer-busy`,children:`Composing…`}):null,v?(0,z.jsx)(`div`,{className:`composer-error`,role:`alert`,children:v}):null,T?(0,z.jsx)(`div`,{className:`composer-error`,role:`alert`,children:T}):null,(0,z.jsxs)(`footer`,{className:`composer-actions`,children:[(0,z.jsxs)(`div`,{className:`composer-export-row`,children:[(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-copy`,onClick:ne,disabled:!ae,title:l===`md`?C===`copy`?`Copying…`:`Copy composed report to clipboard`:`Copy is available for Markdown only`,children:C===`copy`?`Copying…`:`Copy`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-download`,onClick:k,disabled:!oe,title:C===`download`?`Downloading…`:`Download composed report`,children:C===`download`?`Downloading…`:`Download`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-open`,onClick:re,disabled:!se,title:l===`html`||l===`svg`?C===`open`?`Opening…`:`Open composed report in new tab`:`Open is available for HTML/SVG`,children:C===`open`?`Opening…`:`Open`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-png`,onClick:A,disabled:!j,title:l===`svg`?C===`png`?`Rasterizing…`:`Download composed report as PNG`:`PNG export — available for SVG format only`,children:C===`png`?`Rasterizing…`:`PNG`}),(0,z.jsx)(`button`,{type:`button`,className:`share-action share-action-print`,onClick:ie,disabled:!ce,title:l===`html`?C===`print`?`Opening print dialog…`:`Open the browser print dialog (save as PDF)`:`Print → PDF — available for HTML format only`,children:C===`print`?`Printing…`:`Print → PDF`})]}),(0,z.jsx)(`button`,{type:`button`,className:`composer-clear-all`,onClick:()=>R({type:`BASKET_CLEAR`}),children:`Clear all`})]})]}):null}function Uc(){let e=(0,g.useSyncExternalStore)(L,()=>I().shareModal),t=(0,g.useRef)(null),n=(0,g.useRef)(!1);(0,g.useEffect)(()=>{if(e)n.current||(n.current=!0,t.current=(e.triggerId?document.getElementById(e.triggerId):null)??document.activeElement);else if(n.current){n.current=!1;let e=t.current;if(t.current=null,e&&typeof e.focus==`function`&&document.contains(e))e.focus();else{let e=document.activeElement;e&&typeof e.blur==`function`&&e.blur(),document.body.focus()}}},[e]);let r=()=>R(ge());return(0,z.jsxs)(z.Fragment,{children:[e?(0,z.jsx)(`div`,{id:`share-modal-root`,className:`share-overlay`,onClick:e=>{e.stopPropagation(),e.target===e.currentTarget&&r()},children:(0,z.jsx)(kc,{panel:e.panel,initialParams:e.params,onClose:r})}):null,(0,z.jsx)(Hc,{})]})}function Wc(){let e=(0,g.useSyncExternalStore)(L,()=>I().prefs.panelOrder);return(0,z.jsxs)(z.Fragment,{children:[(0,z.jsx)(Ot,{}),(0,z.jsx)(ho,{items:e,children:(0,z.jsx)(`div`,{className:`grid`,children:e.map((e,t)=>(0,z.jsx)(co,{id:e,index:t},e))})}),(0,z.jsx)(Pt,{}),(0,z.jsx)(Mn,{}),(0,z.jsx)(In,{}),(0,z.jsx)(Js,{}),(0,z.jsx)(Uc,{}),(0,z.jsx)(Fo,{}),(0,z.jsx)(_o,{}),(0,z.jsx)(Un,{})]})}function Gc(e){let t=I().prefs.panelOrder,n=e-1;if(n<0||n>=t.length)return;let r=kn[t[n]];r&&r.openAction()}var Kc=`Click a panel first, then press S to share it.`;function qc(){return typeof window>`u`||!window.matchMedia?!1:window.matchMedia(an).matches}function Jc(){if(typeof document>`u`)return null;let e=document.activeElement;if(!e||!(e instanceof Element))return null;let t=e.closest(`[data-panel-kind]`);return t?t.getAttribute(`data-panel-kind`):null}function Yc(){return{key:`S`,scope:`global`,when:()=>{let e=I();return!(qc()||e.shareModal!==null||e.composerModal!==null||e.openModal!==null||e.update.modalOpen||e.inputMode!==null)},action:()=>{let e=Jc();if(e===null){R({type:`SHOW_STATUS_TOAST`,text:Kc});return}if(!j.has(e))return;let t=e;R(N(t,`${t}-panel`))}}}function Xc(){return typeof window>`u`||!window.matchMedia?!1:window.matchMedia(an).matches}function Zc(){return{key:`B`,scope:`global`,when:()=>{let e=I();return!(Xc()||e.shareModal!==null||e.composerModal!==null||e.openModal!==null||e.update.modalOpen||e.inputMode!==null)},action:()=>R(_e())}}function Qc(){return[Zc()]}mt(),nt(),Bt();var $=()=>{let e=I();return!e.update.modalOpen&&!e.doctorModalOpen};zt([{key:`1`,scope:`global`,when:$,action:()=>Gc(1)},{key:`2`,scope:`global`,when:$,action:()=>Gc(2)},{key:`3`,scope:`global`,when:$,action:()=>Gc(3)},{key:`4`,scope:`global`,when:$,action:()=>Gc(4)},{key:`5`,scope:`global`,when:$,action:()=>Gc(5)},{key:`6`,scope:`global`,when:$,action:()=>Gc(6)},{key:`7`,scope:`global`,when:$,action:()=>Gc(7)},{key:`8`,scope:`global`,when:$,action:()=>Gc(8)},{key:`9`,scope:`global`,when:$,action:()=>Gc(9)},{key:`0`,scope:`global`,when:$,action:()=>Gc(10)},{key:`r`,scope:`global`,when:$,action:()=>Et()},{key:`q`,scope:`global`,when:$,action:Nt},{key:`n`,scope:`global`,when:$,action:()=>jt(1)},{key:`N`,scope:`global`,when:$,action:()=>jt(-1)},{key:`d`,scope:`global`,when:()=>{let e=I();return!(e.openModal!==null||e.update.modalOpen||e.inputMode!==null)},action:()=>R({type:`OPEN_DOCTOR_MODAL`})},Yc(),...Qc(),{key:`c`,scope:`sessions`,when:()=>!I().openModal,action:()=>{let e=I().prefs.sessionsCollapsed;R({type:`SAVE_PREFS`,patch:{sessionsCollapsed:!e}})}}]);var $c=document.getElementById(`root`);if(!$c)throw Error(`missing #root`);(0,_.createRoot)($c).render((0,z.jsx)(g.StrictMode,{children:(0,z.jsx)(Wc,{})}));
@@ -4,7 +4,7 @@
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
6
6
  <title>cctally dashboard</title>
7
- <script type="module" crossorigin src="/static/assets/index-DUKjFlG8.js"></script>
7
+ <script type="module" crossorigin src="/static/assets/index-Cy59E7Ru.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/static/assets/index-Dp14ELVt.css">
9
9
  </head>
10
10
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cctally",
3
- "version": "1.10.0",
3
+ "version": "1.10.2",
4
4
  "description": "Claude Code usage tracker and local dashboard for Pro/Max subscription limits - weekly cost-per-percent trend, quota forecasts, threshold alerts. ccusage-compatible.",
5
5
  "homepage": "https://github.com/omrikais/cctally",
6
6
  "repository": {