epiq 1.8.3 → 1.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/gui/main.js CHANGED
@@ -24820,7 +24820,7 @@ function useViewTransitionState(to, { relative } = {}) {
24820
24820
  }
24821
24821
 
24822
24822
  // source/gui/client/App.tsx
24823
- var import_react62 = __toESM(require_react(), 1);
24823
+ var import_react60 = __toESM(require_react(), 1);
24824
24824
 
24825
24825
  // source/gui/client/components/Aside.tsx
24826
24826
  var import_react = __toESM(require_react(), 1);
@@ -52785,7 +52785,7 @@ var User = ({
52785
52785
  );
52786
52786
 
52787
52787
  // source/version.ts
52788
- var EPIQ_VERSION = "1.8.3";
52788
+ var EPIQ_VERSION = "1.8.5";
52789
52789
 
52790
52790
  // source/gui/client/components/Header.tsx
52791
52791
  var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1);
@@ -54711,11 +54711,11 @@ function addChildren(props, children) {
54711
54711
  }
54712
54712
  }
54713
54713
  }
54714
- function productionCreate(_3, jsx95, jsxs73) {
54714
+ function productionCreate(_3, jsx94, jsxs72) {
54715
54715
  return create2;
54716
54716
  function create2(_4, type, props, key2) {
54717
54717
  const isStaticChildren = Array.isArray(props.children);
54718
- const fn = isStaticChildren ? jsxs73 : jsx95;
54718
+ const fn = isStaticChildren ? jsxs72 : jsx94;
54719
54719
  return key2 ? fn(type, props, key2) : fn(type, props);
54720
54720
  }
54721
54721
  }
@@ -68765,7 +68765,7 @@ var BulkDetails = ({
68765
68765
  };
68766
68766
 
68767
68767
  // source/gui/client/components/SwimlaneColumn.tsx
68768
- var import_react41 = __toESM(require_react(), 1);
68768
+ var import_react40 = __toESM(require_react(), 1);
68769
68769
 
68770
68770
  // source/lib/utils/number.ts
68771
68771
  var medianOfSorted = (sorted) => {
@@ -68820,188 +68820,11 @@ var IconLaneStats = ({ size = 13 }) => /* @__PURE__ */ (0, import_jsx_runtime67.
68820
68820
  }
68821
68821
  );
68822
68822
 
68823
- // source/gui/client/components/LaneSparkline.tsx
68824
- var import_react37 = __toESM(require_react(), 1);
68825
- var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
68826
- var WIDTH = 112;
68827
- var HEIGHT = 14;
68828
- var DAY2 = 864e5;
68829
- var REACH = 200;
68830
- var BRIGHTEST = 1;
68831
- var GLOW_VAR = "--spark-glow";
68832
- var GROUND = 0.05;
68833
- var GRID_REST = 0.05;
68834
- var GRID_GAIN = 0.12;
68835
- var AXIS = GUI_THEME.dim2;
68836
- var CURVE = GUI_THEME.dim2;
68837
- var CURVE_OPACITY = 0.4;
68838
- var latestRun = (points) => {
68839
- const run = [];
68840
- for (let index2 = points.length - 1; index2 >= 0; index2--) {
68841
- const point4 = points[index2];
68842
- if (point4.median === null) break;
68843
- run.unshift(point4);
68844
- }
68845
- return run;
68846
- };
68847
- var smoothed = (values) => values.map((value, index2) => {
68848
- const window2 = [values[index2 - 1], value, values[index2 + 1]].filter(
68849
- (entry) => entry !== void 0
68850
- );
68851
- return window2.reduce((total, entry) => total + entry, 0) / window2.length;
68852
- });
68853
- var smoothPath = (points) => {
68854
- if (points.length < 2) return "";
68855
- const at = (index2) => points[Math.min(points.length - 1, Math.max(0, index2))];
68856
- return points.slice(1).reduce((path2, point4, index2) => {
68857
- const previous3 = at(index2);
68858
- const before = at(index2 - 1);
68859
- const after = at(index2 + 2);
68860
- const c1x = previous3.x + (point4.x - before.x) / 6;
68861
- const c1y = previous3.y + (point4.y - before.y) / 6;
68862
- const c2x = point4.x - (after.x - previous3.x) / 6;
68863
- const c2y = point4.y - (after.y - previous3.y) / 6;
68864
- return `${path2} C${c1x.toFixed(1)} ${c1y.toFixed(1)}, ${c2x.toFixed(
68865
- 1
68866
- )} ${c2y.toFixed(1)}, ${point4.x.toFixed(1)} ${point4.y.toFixed(1)}`;
68867
- }, `M${at(0).x.toFixed(1)} ${at(0).y.toFixed(1)}`);
68868
- };
68869
- var LaneSparkline = ({ points }) => {
68870
- const ref = (0, import_react37.useRef)(null);
68871
- const gradientId = (0, import_react37.useId)().replace(/:/g, "");
68872
- (0, import_react37.useEffect)(() => {
68873
- let sampled = 0;
68874
- const onMove = (event) => {
68875
- const now = Date.now();
68876
- if (now - sampled < 16) return;
68877
- sampled = now;
68878
- const node2 = ref.current;
68879
- if (!node2) return;
68880
- const rect = node2.getBoundingClientRect();
68881
- const dx = Math.max(
68882
- rect.left - event.clientX,
68883
- 0,
68884
- event.clientX - rect.right
68885
- );
68886
- const dy = Math.max(
68887
- rect.top - event.clientY,
68888
- 0,
68889
- event.clientY - rect.bottom
68890
- );
68891
- const distance = Math.hypot(dx, dy);
68892
- node2.style.setProperty(
68893
- GLOW_VAR,
68894
- String(distance >= REACH ? 0 : 1 - distance / REACH)
68895
- );
68896
- };
68897
- window.addEventListener("mousemove", onMove);
68898
- return () => window.removeEventListener("mousemove", onMove);
68899
- }, []);
68900
- const run = latestRun(points);
68901
- if (run.length < 2) return null;
68902
- const first = run[0].t;
68903
- const span = Math.max(1, run.at(-1).t - first);
68904
- const peak = Math.max(...run.map((point4) => point4.median));
68905
- const medians = smoothed(run.map((point4) => point4.median));
68906
- const path2 = smoothPath(
68907
- run.map((point4, index2) => ({
68908
- x: (point4.t - first) / span * WIDTH,
68909
- y: HEIGHT - 1 - medians[index2] / Math.max(1, peak) * (HEIGHT - 2)
68910
- }))
68911
- );
68912
- const grid = Array.from(
68913
- { length: Math.floor(span / (7 * DAY2)) },
68914
- (_3, index2) => (1 - (index2 + 1) * 7 * DAY2 / span) * WIDTH
68915
- ).filter((x3) => x3 > 1).map((x3) => `M${x3.toFixed(1)} 1 L${x3.toFixed(1)} ${HEIGHT - 1}`).join(" ");
68916
- const stroke = {
68917
- d: path2,
68918
- fill: "none",
68919
- strokeWidth: 1,
68920
- strokeLinecap: "round",
68921
- strokeLinejoin: "round"
68922
- };
68923
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
68924
- "svg",
68925
- {
68926
- ref,
68927
- "data-testid": "lane-sparkline",
68928
- width: WIDTH,
68929
- height: HEIGHT,
68930
- viewBox: `0 0 ${WIDTH} ${HEIGHT}`,
68931
- "aria-hidden": true,
68932
- style: { flexShrink: 0, pointerEvents: "none" },
68933
- children: [
68934
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
68935
- "rect",
68936
- {
68937
- x: 0,
68938
- y: 0,
68939
- width: WIDTH,
68940
- height: HEIGHT,
68941
- rx: 2,
68942
- fill: GUI_THEME.primary,
68943
- style: {
68944
- opacity: `calc(var(${GLOW_VAR}, 0) * ${GROUND})`,
68945
- transition: "opacity 140ms ease"
68946
- }
68947
- }
68948
- ),
68949
- grid && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
68950
- "path",
68951
- {
68952
- d: grid,
68953
- fill: "none",
68954
- strokeWidth: 1,
68955
- stroke: AXIS,
68956
- style: {
68957
- opacity: `calc(${GRID_REST} + var(${GLOW_VAR}, 0) * ${GRID_GAIN})`,
68958
- transition: "opacity 140ms ease"
68959
- }
68960
- }
68961
- ),
68962
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("defs", { children: [
68963
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("linearGradient", { id: gradientId, x1: "0", x2: "1", y1: "0", y2: "0", children: [
68964
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "0%", stopColor: CURVE, stopOpacity: 0 }),
68965
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "22%", stopColor: CURVE }),
68966
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "78%", stopColor: CURVE }),
68967
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "100%", stopColor: CURVE, stopOpacity: 0 })
68968
- ] }),
68969
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("linearGradient", { id: `${gradientId}-lit`, x1: "0", x2: "1", y1: "0", y2: "0", children: [
68970
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "0%", stopColor: GUI_THEME.secondary, stopOpacity: 0 }),
68971
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "22%", stopColor: GUI_THEME.secondary }),
68972
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "78%", stopColor: GUI_THEME.secondary }),
68973
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("stop", { offset: "100%", stopColor: GUI_THEME.secondary, stopOpacity: 0 })
68974
- ] })
68975
- ] }),
68976
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
68977
- "path",
68978
- {
68979
- ...stroke,
68980
- stroke: `url(#${gradientId})`,
68981
- opacity: CURVE_OPACITY
68982
- }
68983
- ),
68984
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
68985
- "path",
68986
- {
68987
- ...stroke,
68988
- stroke: `url(#${gradientId}-lit)`,
68989
- style: {
68990
- opacity: `calc(var(${GLOW_VAR}, 0) * ${BRIGHTEST})`,
68991
- transition: "opacity 140ms ease"
68992
- }
68993
- }
68994
- )
68995
- ]
68996
- }
68997
- );
68998
- };
68999
-
69000
68823
  // source/gui/client/components/TicketCard.tsx
69001
- var import_react40 = __toESM(require_react(), 1);
68824
+ var import_react39 = __toESM(require_react(), 1);
69002
68825
 
69003
68826
  // source/gui/client/lib/theatre.ts
69004
- var import_react39 = __toESM(require_react(), 1);
68827
+ var import_react38 = __toESM(require_react(), 1);
69005
68828
 
69006
68829
  // source/lib/utils/playback-pacing.ts
69007
68830
  var buildPlaybackFractions = (times) => {
@@ -69044,7 +68867,7 @@ var formatTimeOfDay = (date) => `${pad(date.getHours())}:${pad(date.getMinutes()
69044
68867
  var isSameDay = (a2, b3) => a2.getFullYear() === b3.getFullYear() && a2.getMonth() === b3.getMonth() && a2.getDate() === b3.getDate();
69045
68868
 
69046
68869
  // source/gui/client/lib/scrubber/layout.ts
69047
- var import_react38 = __toESM(require_react(), 1);
68870
+ var import_react37 = __toESM(require_react(), 1);
69048
68871
  var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
69049
68872
  var isLayoutMode = (value) => value === "even" || value === "real";
69050
68873
  var TRACK_HEIGHT = 24;
@@ -69128,10 +68951,10 @@ var SCRUBBER_KEYFRAMES = `
69128
68951
  `;
69129
68952
  var NARROW_BAR_QUERY = "(max-width: 1180px)";
69130
68953
  var useNarrowBar = () => {
69131
- const [narrow, setNarrow] = (0, import_react38.useState)(
68954
+ const [narrow, setNarrow] = (0, import_react37.useState)(
69132
68955
  () => window.matchMedia(NARROW_BAR_QUERY).matches
69133
68956
  );
69134
- (0, import_react38.useEffect)(() => {
68957
+ (0, import_react37.useEffect)(() => {
69135
68958
  const query = window.matchMedia(NARROW_BAR_QUERY);
69136
68959
  const onChange = () => setNarrow(query.matches);
69137
68960
  query.addEventListener("change", onChange);
@@ -69141,10 +68964,10 @@ var useNarrowBar = () => {
69141
68964
  };
69142
68965
  var REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
69143
68966
  var usePrefersReducedMotion = () => {
69144
- const [reduced, setReduced] = (0, import_react38.useState)(
68967
+ const [reduced, setReduced] = (0, import_react37.useState)(
69145
68968
  () => window.matchMedia(REDUCED_MOTION_QUERY).matches
69146
68969
  );
69147
- (0, import_react38.useEffect)(() => {
68970
+ (0, import_react37.useEffect)(() => {
69148
68971
  const query = window.matchMedia(REDUCED_MOTION_QUERY);
69149
68972
  const onChange = () => setReduced(query.matches);
69150
68973
  query.addEventListener("change", onChange);
@@ -69153,12 +68976,12 @@ var usePrefersReducedMotion = () => {
69153
68976
  return reduced;
69154
68977
  };
69155
68978
  var useExitTransition = (visible, durationMs) => {
69156
- const [mounted, setMounted] = (0, import_react38.useState)(visible);
69157
- const [leaving, setLeaving] = (0, import_react38.useState)(false);
69158
- const wasVisible = (0, import_react38.useRef)(visible);
69159
- const duration = (0, import_react38.useRef)(durationMs);
68979
+ const [mounted, setMounted] = (0, import_react37.useState)(visible);
68980
+ const [leaving, setLeaving] = (0, import_react37.useState)(false);
68981
+ const wasVisible = (0, import_react37.useRef)(visible);
68982
+ const duration = (0, import_react37.useRef)(durationMs);
69160
68983
  duration.current = durationMs;
69161
- (0, import_react38.useEffect)(() => {
68984
+ (0, import_react37.useEffect)(() => {
69162
68985
  if (visible === wasVisible.current) return;
69163
68986
  wasVisible.current = visible;
69164
68987
  if (visible) {
@@ -69177,7 +69000,7 @@ var useExitTransition = (visible, durationMs) => {
69177
69000
  }, duration.current);
69178
69001
  return () => clearTimeout(timeout);
69179
69002
  }, [visible]);
69180
- return (0, import_react38.useMemo)(() => ({ mounted, leaving }), [mounted, leaving]);
69003
+ return (0, import_react37.useMemo)(() => ({ mounted, leaving }), [mounted, leaving]);
69181
69004
  };
69182
69005
 
69183
69006
  // source/lib/utils/minmax.ts
@@ -69513,7 +69336,6 @@ var SCOPES = [
69513
69336
  "day",
69514
69337
  "week",
69515
69338
  "month",
69516
- "halfyear",
69517
69339
  "year",
69518
69340
  "all"
69519
69341
  ];
@@ -69522,7 +69344,6 @@ var SCOPE_DURATION_MS = {
69522
69344
  day: 24 * 60 * 60 * 1e3,
69523
69345
  week: 7 * 24 * 60 * 60 * 1e3,
69524
69346
  month: 30 * 24 * 60 * 60 * 1e3,
69525
- halfyear: 180 * 24 * 60 * 60 * 1e3,
69526
69347
  year: 365 * 24 * 60 * 60 * 1e3
69527
69348
  };
69528
69349
  var SCOPE_RECENT_LABELS = {
@@ -69530,7 +69351,6 @@ var SCOPE_RECENT_LABELS = {
69530
69351
  day: "Last 24 hours",
69531
69352
  week: "Last 7 days",
69532
69353
  month: "Last 30 days",
69533
- halfyear: "Last 180 days",
69534
69354
  year: "Last 365 days"
69535
69355
  };
69536
69356
  var isScope = (value) => SCOPES.includes(value ?? "");
@@ -69553,7 +69373,7 @@ var formatPeriodLabel = (scope, offset, range2, zoomed = false) => {
69553
69373
  if (offset === 0) return SCOPE_RECENT_LABELS[scope];
69554
69374
  return compactRangeLabel(range2);
69555
69375
  };
69556
- var scopeButtonLabel = (scope) => scope === "all" ? "All" : scope === "halfyear" ? "6 months" : scope[0].toUpperCase() + scope.slice(1);
69376
+ var scopeButtonLabel = (scope) => scope === "all" ? "All" : scope[0].toUpperCase() + scope.slice(1);
69557
69377
 
69558
69378
  // source/gui/client/lib/log-destination.ts
69559
69379
  var SHA_ATTRIBUTE = "data-log-sha";
@@ -69784,30 +69604,30 @@ var useTheatrePlayback = ({
69784
69604
  ack,
69785
69605
  onSeek
69786
69606
  }) => {
69787
- const [speed, setSpeed] = (0, import_react39.useState)(1);
69788
- const [playing, setPlaying] = (0, import_react39.useState)(false);
69789
- const [progress, setProgress] = (0, import_react39.useState)(0);
69790
- const [seeking, setSeeking] = (0, import_react39.useState)(false);
69791
- const progressRef = (0, import_react39.useRef)(0);
69792
- const frameRef = (0, import_react39.useRef)(null);
69793
- const sentCursorRef = (0, import_react39.useRef)(null);
69794
- const inflightRef = (0, import_react39.useRef)(false);
69795
- const onSeekRef = (0, import_react39.useRef)(onSeek);
69607
+ const [speed, setSpeed] = (0, import_react38.useState)(1);
69608
+ const [playing, setPlaying] = (0, import_react38.useState)(false);
69609
+ const [progress, setProgress] = (0, import_react38.useState)(0);
69610
+ const [seeking, setSeeking] = (0, import_react38.useState)(false);
69611
+ const progressRef = (0, import_react38.useRef)(0);
69612
+ const frameRef = (0, import_react38.useRef)(null);
69613
+ const sentCursorRef = (0, import_react38.useRef)(null);
69614
+ const inflightRef = (0, import_react38.useRef)(false);
69615
+ const onSeekRef = (0, import_react38.useRef)(onSeek);
69796
69616
  onSeekRef.current = onSeek;
69797
69617
  const durationMs = theatreDurationMs(plan?.events.length ?? 0);
69798
69618
  const cursor = plan ? cursorAt(plan.fractions, playbackPosition(progress)) : -1;
69799
69619
  const done = plan !== null && progress >= 1;
69800
- (0, import_react39.useEffect)(() => {
69620
+ (0, import_react38.useEffect)(() => {
69801
69621
  setProgress(0);
69802
69622
  progressRef.current = 0;
69803
69623
  sentCursorRef.current = null;
69804
69624
  inflightRef.current = false;
69805
69625
  setPlaying(plan !== null);
69806
69626
  }, [plan]);
69807
- (0, import_react39.useEffect)(() => {
69627
+ (0, import_react38.useEffect)(() => {
69808
69628
  inflightRef.current = false;
69809
69629
  }, [ack]);
69810
- (0, import_react39.useEffect)(() => {
69630
+ (0, import_react38.useEffect)(() => {
69811
69631
  if (!plan) return;
69812
69632
  if (inflightRef.current) return;
69813
69633
  if (sentCursorRef.current === cursor) return;
@@ -69815,7 +69635,7 @@ var useTheatrePlayback = ({
69815
69635
  inflightRef.current = true;
69816
69636
  onSeekRef.current(seekTimeFor(plan, cursor));
69817
69637
  }, [plan, cursor, ack]);
69818
- (0, import_react39.useEffect)(() => {
69638
+ (0, import_react38.useEffect)(() => {
69819
69639
  if (!plan || !playing || seeking) return;
69820
69640
  let last = performance.now();
69821
69641
  const step = (now) => {
@@ -69839,20 +69659,20 @@ var useTheatrePlayback = ({
69839
69659
  frameRef.current = null;
69840
69660
  };
69841
69661
  }, [plan, playing, seeking, speed, durationMs]);
69842
- const restart = (0, import_react39.useCallback)(() => {
69662
+ const restart = (0, import_react38.useCallback)(() => {
69843
69663
  setProgress(0);
69844
69664
  progressRef.current = 0;
69845
69665
  setPlaying(true);
69846
69666
  }, []);
69847
- const toggle = (0, import_react39.useCallback)(() => {
69667
+ const toggle = (0, import_react38.useCallback)(() => {
69848
69668
  if (progressRef.current >= 1) {
69849
69669
  restart();
69850
69670
  return;
69851
69671
  }
69852
69672
  setPlaying((current) => !current);
69853
69673
  }, [restart]);
69854
- const cycleSpeed = (0, import_react39.useCallback)(() => setSpeed(nextSpeed), []);
69855
- const seekTo = (0, import_react39.useCallback)((fraction) => {
69674
+ const cycleSpeed = (0, import_react38.useCallback)(() => setSpeed(nextSpeed), []);
69675
+ const seekTo = (0, import_react38.useCallback)((fraction) => {
69856
69676
  const next = clamp(fraction, 0, 1);
69857
69677
  progressRef.current = next;
69858
69678
  setProgress(next);
@@ -69871,8 +69691,8 @@ var useTheatrePlayback = ({
69871
69691
  restart,
69872
69692
  cycleSpeed,
69873
69693
  seekTo,
69874
- beginSeek: (0, import_react39.useCallback)(() => setSeeking(true), []),
69875
- endSeek: (0, import_react39.useCallback)(() => setSeeking(false), [])
69694
+ beginSeek: (0, import_react38.useCallback)(() => setSeeking(true), []),
69695
+ endSeek: (0, import_react38.useCallback)(() => setSeeking(false), [])
69876
69696
  };
69877
69697
  };
69878
69698
  var THEATRE_KEYFRAMES = `
@@ -69964,7 +69784,7 @@ var moveSwimlane = (state, setState, send) => (swimlaneId, boardId, targetIndex)
69964
69784
  };
69965
69785
 
69966
69786
  // source/gui/client/components/TicketCard.tsx
69967
- var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
69787
+ var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
69968
69788
  var DWELL_COLOR = {
69969
69789
  none: GUI_THEME.dim,
69970
69790
  warn: GUI_THEME.amber,
@@ -69986,8 +69806,8 @@ var TicketCard = ({
69986
69806
  flashKey,
69987
69807
  dwell
69988
69808
  }) => {
69989
- const cardRef = (0, import_react40.useRef)(null);
69990
- (0, import_react40.useEffect)(() => {
69809
+ const cardRef = (0, import_react39.useRef)(null);
69810
+ (0, import_react39.useEffect)(() => {
69991
69811
  if (!isSelected) return;
69992
69812
  cardRef.current?.scrollIntoView({
69993
69813
  behavior: "smooth",
@@ -69995,14 +69815,14 @@ var TicketCard = ({
69995
69815
  inline: "nearest"
69996
69816
  });
69997
69817
  }, [isSelected]);
69998
- (0, import_react40.useEffect)(() => {
69818
+ (0, import_react39.useEffect)(() => {
69999
69819
  const card = cardRef.current;
70000
69820
  if (!card || flashKey === null) return;
70001
69821
  if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
70002
69822
  card.animate(THEATRE_FLASH_FRAMES, THEATRE_FLASH_TIMING);
70003
69823
  }, [flashKey]);
70004
69824
  const getVisualTargetIndex = (isAfterMiddle) => index2 + (isAfterMiddle ? 1 : 0);
70005
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
69825
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
70006
69826
  "div",
70007
69827
  {
70008
69828
  ref: cardRef,
@@ -70052,7 +69872,7 @@ var TicketCard = ({
70052
69872
  animation: theatre ? THEATRE_CARD_IN_ANIMATION : void 0
70053
69873
  },
70054
69874
  children: [
70055
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
69875
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
70056
69876
  "div",
70057
69877
  {
70058
69878
  style: {
@@ -70066,7 +69886,7 @@ var TicketCard = ({
70066
69886
  children: isSelected ? "\u276F" : index2 + 1
70067
69887
  }
70068
69888
  ),
70069
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
69889
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
70070
69890
  "div",
70071
69891
  {
70072
69892
  style: {
@@ -70078,7 +69898,7 @@ var TicketCard = ({
70078
69898
  paddingLeft: 8
70079
69899
  },
70080
69900
  children: [
70081
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
69901
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
70082
69902
  "div",
70083
69903
  {
70084
69904
  style: {
@@ -70089,7 +69909,7 @@ var TicketCard = ({
70089
69909
  flex: 1
70090
69910
  },
70091
69911
  children: [
70092
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
69912
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
70093
69913
  "div",
70094
69914
  {
70095
69915
  style: {
@@ -70105,17 +69925,17 @@ var TicketCard = ({
70105
69925
  children: ticket.title
70106
69926
  }
70107
69927
  ),
70108
- ticket.ref && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
69928
+ ticket.ref && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
70109
69929
  "div",
70110
69930
  {
70111
69931
  style: {
70112
69932
  color: GUI_THEME.dim2,
70113
69933
  fontSize: 10
70114
69934
  },
70115
- children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(CopyRef, { refValue: ticket.ref })
69935
+ children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(CopyRef, { refValue: ticket.ref })
70116
69936
  }
70117
69937
  ),
70118
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
69938
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
70119
69939
  "div",
70120
69940
  {
70121
69941
  style: {
@@ -70126,7 +69946,7 @@ var TicketCard = ({
70126
69946
  },
70127
69947
  children: ticket.tags.map((tag) => {
70128
69948
  const isolated = tag.id === isolatedTagId;
70129
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
69949
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
70130
69950
  "button",
70131
69951
  {
70132
69952
  type: "button",
@@ -70158,7 +69978,7 @@ var TicketCard = ({
70158
69978
  ]
70159
69979
  }
70160
69980
  ),
70161
- /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
69981
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
70162
69982
  "div",
70163
69983
  {
70164
69984
  style: {
@@ -70169,7 +69989,7 @@ var TicketCard = ({
70169
69989
  paddingTop: 2
70170
69990
  },
70171
69991
  children: [
70172
- dwell && dwell.level !== "none" && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
69992
+ dwell && dwell.level !== "none" && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
70173
69993
  "span",
70174
69994
  {
70175
69995
  "data-testid": "ticket-dwell",
@@ -70192,12 +70012,12 @@ var TicketCard = ({
70192
70012
  whiteSpace: "nowrap"
70193
70013
  },
70194
70014
  children: [
70195
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(IconClock, { size: 12 }),
70196
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { children: formatDuration(dwell.ms) })
70015
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(IconClock, { size: 12 }),
70016
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: formatDuration(dwell.ms) })
70197
70017
  ]
70198
70018
  }
70199
70019
  ),
70200
- commentCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
70020
+ commentCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
70201
70021
  "button",
70202
70022
  {
70203
70023
  type: "button",
@@ -70235,15 +70055,15 @@ var TicketCard = ({
70235
70055
  event.currentTarget.style.transform = "translateY(0)";
70236
70056
  },
70237
70057
  children: [
70238
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(IconComment, {}),
70239
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { children: commentCount })
70058
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(IconComment, {}),
70059
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: commentCount })
70240
70060
  ]
70241
70061
  }
70242
70062
  )
70243
70063
  ]
70244
70064
  }
70245
70065
  ),
70246
- ticket.assignees.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
70066
+ ticket.assignees.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
70247
70067
  "div",
70248
70068
  {
70249
70069
  style: {
@@ -70253,7 +70073,7 @@ var TicketCard = ({
70253
70073
  paddingTop: 2,
70254
70074
  marginTop: "-4px"
70255
70075
  },
70256
- children: ticket.assignees.map((assignee, idx) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
70076
+ children: ticket.assignees.map((assignee, idx) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
70257
70077
  User,
70258
70078
  {
70259
70079
  user: assignee,
@@ -70273,7 +70093,7 @@ var TicketCard = ({
70273
70093
  };
70274
70094
 
70275
70095
  // source/gui/client/components/SwimlaneColumn.tsx
70276
- var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
70096
+ var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
70277
70097
  var COLUMN_GLOW_COLOR = "rgb(140, 176, 232)";
70278
70098
  var COLUMN_PADDING = 14;
70279
70099
  var SCROLLBAR_GUTTER_INSET = COLUMN_PADDING / 2;
@@ -70303,18 +70123,18 @@ var SwimlaneColumn = ({
70303
70123
  theatre,
70304
70124
  live,
70305
70125
  statsOpen,
70306
- onOpenStats,
70307
- trend
70126
+ onOpenStats
70308
70127
  }) => {
70309
- const [statsHovered, setStatsHovered] = (0, import_react41.useState)(false);
70310
70128
  const now = Date.now();
70311
70129
  const dwell = live ? laneDwell(swimlane.issues, now) : null;
70130
+ const medianWait = dwell ? formatDuration(dwell.median) : "";
70131
+ const statsTitle = medianWait ? `Swimlane Stats \u2014 ${medianWait} median wait time` : "Swimlane Stats";
70312
70132
  const cardDwell = (ticket) => {
70313
70133
  if (!dwell) return null;
70314
70134
  const ms = dwellOf(ticket, now);
70315
70135
  return { ms, level: dwellLevel(ms, dwell, swimlane.issues.length) };
70316
70136
  };
70317
- return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(
70137
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
70318
70138
  Panel,
70319
70139
  {
70320
70140
  as: "section",
@@ -70370,7 +70190,7 @@ var SwimlaneColumn = ({
70370
70190
  onDragLeave();
70371
70191
  },
70372
70192
  children: [
70373
- dropSide && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70193
+ dropSide && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
70374
70194
  "div",
70375
70195
  {
70376
70196
  "data-testid": "swimlane-drop-indicator",
@@ -70387,7 +70207,7 @@ var SwimlaneColumn = ({
70387
70207
  }
70388
70208
  }
70389
70209
  ),
70390
- /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(
70210
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
70391
70211
  "header",
70392
70212
  {
70393
70213
  draggable: !swimlane.readonly,
@@ -70409,7 +70229,7 @@ var SwimlaneColumn = ({
70409
70229
  cursor: swimlane.readonly ? "default" : "grab"
70410
70230
  },
70411
70231
  children: [
70412
- /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(
70232
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
70413
70233
  "div",
70414
70234
  {
70415
70235
  style: {
@@ -70419,7 +70239,7 @@ var SwimlaneColumn = ({
70419
70239
  minWidth: 0
70420
70240
  },
70421
70241
  children: [
70422
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70242
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
70423
70243
  "span",
70424
70244
  {
70425
70245
  style: {
@@ -70428,7 +70248,7 @@ var SwimlaneColumn = ({
70428
70248
  children: selected ? "\u276F" : " "
70429
70249
  }
70430
70250
  ),
70431
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70251
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
70432
70252
  "strong",
70433
70253
  {
70434
70254
  style: {
@@ -70442,69 +70262,43 @@ var SwimlaneColumn = ({
70442
70262
  children: swimlane.title
70443
70263
  }
70444
70264
  ),
70445
- /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("span", { style: { color: GUI_THEME.dim }, children: [
70265
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("span", { style: { color: GUI_THEME.dim }, children: [
70446
70266
  "(",
70447
70267
  swimlane.issues.length,
70448
70268
  ")"
70449
70269
  ] }),
70450
- swimlane.readonly && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70270
+ live && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
70271
+ Button,
70272
+ {
70273
+ variant: "ghost",
70274
+ "data-testid": "swimlane-stats-open",
70275
+ title: statsTitle,
70276
+ onClick: (event) => {
70277
+ event.stopPropagation();
70278
+ onOpenStats(swimlane.id);
70279
+ },
70280
+ style: {
70281
+ display: "flex",
70282
+ alignItems: "center",
70283
+ color: statsOpen ? GUI_THEME.accent : GUI_THEME.dim,
70284
+ flexShrink: 0
70285
+ },
70286
+ children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(IconLaneStats, {})
70287
+ }
70288
+ ),
70289
+ swimlane.readonly && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
70451
70290
  "span",
70452
70291
  {
70453
70292
  title: "Read-only",
70454
70293
  style: { display: "flex", color: GUI_THEME.dim },
70455
- children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(IconLock, {})
70294
+ children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(IconLock, {})
70456
70295
  }
70457
70296
  )
70458
70297
  ]
70459
70298
  }
70460
70299
  ),
70461
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70462
- "div",
70463
- {
70464
- style: {
70465
- flex: 1,
70466
- display: "flex",
70467
- justifyContent: "center",
70468
- alignItems: "center",
70469
- minWidth: 0
70470
- },
70471
- children: dwell && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70472
- Button,
70473
- {
70474
- variant: "ghost",
70475
- "data-testid": "swimlane-stats-open",
70476
- title: `Lane stats \u2014 tickets here have waited ${formatDuration(
70477
- dwell.median
70478
- )} on average, the longest ${formatDuration(dwell.max)}`,
70479
- onClick: (event) => {
70480
- event.stopPropagation();
70481
- onOpenStats(swimlane.id);
70482
- },
70483
- onMouseEnter: () => setStatsHovered(true),
70484
- onMouseLeave: () => setStatsHovered(false),
70485
- style: {
70486
- display: "flex",
70487
- alignItems: "center",
70488
- color: statsOpen ? GUI_THEME.accent : GUI_THEME.dim,
70489
- flexShrink: 0,
70490
- // A frame only under the pointer. The panel's own outer
70491
- // edge rather than its inner `line`: a 1px box round a
70492
- // small control needs the weight that holds a panel apart
70493
- // from the board, not the one that divides sections
70494
- // inside it.
70495
- border: `1px solid ${statsHovered ? GUI_THEME.edge : "transparent"}`,
70496
- borderRadius: 4,
70497
- background: "transparent",
70498
- padding: "2px 4px",
70499
- transition: "border-color 140ms ease"
70500
- },
70501
- children: live && trend.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(LaneSparkline, { points: trend }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(IconLaneStats, {})
70502
- }
70503
- )
70504
- }
70505
- ),
70506
- /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 2 }, children: [
70507
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70300
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 2 }, children: [
70301
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
70508
70302
  Button,
70509
70303
  {
70510
70304
  variant: "ghost",
@@ -70514,7 +70308,7 @@ var SwimlaneColumn = ({
70514
70308
  children: "+"
70515
70309
  }
70516
70310
  ),
70517
- !swimlane.readonly && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70311
+ !swimlane.readonly && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
70518
70312
  KebabMenu,
70519
70313
  {
70520
70314
  testId: "swimlane-menu",
@@ -70538,7 +70332,7 @@ var SwimlaneColumn = ({
70538
70332
  ]
70539
70333
  }
70540
70334
  ),
70541
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70335
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
70542
70336
  "div",
70543
70337
  {
70544
70338
  style: {
@@ -70549,10 +70343,10 @@ var SwimlaneColumn = ({
70549
70343
  flex: 1,
70550
70344
  minHeight: 0
70551
70345
  },
70552
- children: swimlane.issues.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_jsx_runtime70.Fragment, {}) : /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
70553
- swimlane.issues.map((ticket, index2) => /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_react41.default.Fragment, { children: [
70554
- dropIndex === index2 && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(DropIndicator, {}),
70555
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70346
+ children: swimlane.issues.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_jsx_runtime69.Fragment, {}) : /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_jsx_runtime69.Fragment, { children: [
70347
+ swimlane.issues.map((ticket, index2) => /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(import_react40.default.Fragment, { children: [
70348
+ dropIndex === index2 && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(DropIndicator, {}),
70349
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
70556
70350
  TicketCard,
70557
70351
  {
70558
70352
  ticket,
@@ -70575,7 +70369,7 @@ var SwimlaneColumn = ({
70575
70369
  }
70576
70370
  )
70577
70371
  ] }, ticket.id)),
70578
- dropIndex === swimlane.issues.length && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(DropIndicator, {})
70372
+ dropIndex === swimlane.issues.length && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(DropIndicator, {})
70579
70373
  ] })
70580
70374
  }
70581
70375
  )
@@ -70585,30 +70379,30 @@ var SwimlaneColumn = ({
70585
70379
  };
70586
70380
 
70587
70381
  // source/gui/client/components/StayTrend.tsx
70588
- var import_react42 = __toESM(require_react(), 1);
70589
- var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1);
70590
- var HEIGHT2 = 68;
70382
+ var import_react41 = __toESM(require_react(), 1);
70383
+ var import_jsx_runtime70 = __toESM(require_jsx_runtime(), 1);
70384
+ var HEIGHT = 68;
70591
70385
  var PAD_TOP = 14;
70592
70386
  var PAD_BOTTOM = 16;
70593
70387
  var PAD_RIGHT = 40;
70594
- var DAY3 = 24 * 60 * 60 * 1e3;
70388
+ var DAY2 = 24 * 60 * 60 * 1e3;
70595
70389
  var dayLabel = (t, now) => {
70596
- const days = Math.round((now - t) / DAY3);
70390
+ const days = Math.round((now - t) / DAY2);
70597
70391
  if (days <= 0) return "today";
70598
- return `${formatDuration(days * DAY3)} ago`;
70392
+ return `${formatDuration(days * DAY2)} ago`;
70599
70393
  };
70600
70394
  var StayTrend = ({ points }) => {
70601
- const [hovered, setHovered] = (0, import_react42.useState)(null);
70602
- const [width, setWidth] = (0, import_react42.useState)(0);
70395
+ const [hovered, setHovered] = (0, import_react41.useState)(null);
70396
+ const [width, setWidth] = (0, import_react41.useState)(0);
70603
70397
  const measured = points.filter(
70604
70398
  (point4) => point4.median !== null
70605
70399
  );
70606
70400
  if (measured.length < 2 || width === 0) {
70607
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70401
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70608
70402
  "div",
70609
70403
  {
70610
70404
  ref: (element4) => setWidth(element4?.clientWidth ?? 0),
70611
- style: { height: HEIGHT2, marginTop: 12 }
70405
+ style: { height: HEIGHT, marginTop: 12 }
70612
70406
  }
70613
70407
  );
70614
70408
  }
@@ -70617,7 +70411,7 @@ var StayTrend = ({ points }) => {
70617
70411
  const span = Math.max(1, now - first);
70618
70412
  const peak = Math.max(...measured.map((point4) => point4.median));
70619
70413
  const plotWidth = Math.max(1, width - PAD_RIGHT);
70620
- const plotHeight = HEIGHT2 - PAD_TOP - PAD_BOTTOM;
70414
+ const plotHeight = HEIGHT - PAD_TOP - PAD_BOTTOM;
70621
70415
  const plot = (point4) => ({
70622
70416
  x: (point4.t - first) / span * plotWidth,
70623
70417
  // Off a floor of zero rather than the range's own low: a line that fills
@@ -70629,7 +70423,7 @@ var StayTrend = ({ points }) => {
70629
70423
  const last = plotted.at(-1);
70630
70424
  const runs = plotted.reduce((groups, entry, index2) => {
70631
70425
  const previous3 = measured[index2 - 1];
70632
- const broken = previous3 !== void 0 && Math.round((entry.point.t - previous3.t) / DAY3) > 1;
70426
+ const broken = previous3 !== void 0 && Math.round((entry.point.t - previous3.t) / DAY2) > 1;
70633
70427
  if (index2 === 0 || broken) groups.push([]);
70634
70428
  groups.at(-1).push(entry);
70635
70429
  return groups;
@@ -70642,21 +70436,21 @@ var StayTrend = ({ points }) => {
70642
70436
  )} ${base} Z`;
70643
70437
  const weekMarks = Array.from(
70644
70438
  { length: Math.floor((points.length - 1) / 7) },
70645
- (_3, index2) => (span - (index2 + 1) * 7 * DAY3) / span * plotWidth
70439
+ (_3, index2) => (span - (index2 + 1) * 7 * DAY2) / span * plotWidth
70646
70440
  ).filter((x3) => x3 > 0);
70647
70441
  const nearest = (offsetX) => plotted.reduce(
70648
70442
  (best, entry) => Math.abs(entry.x - offsetX) < Math.abs(best.x - offsetX) ? entry : best
70649
70443
  );
70650
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70444
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70651
70445
  "div",
70652
70446
  {
70653
70447
  ref: (element4) => setWidth(element4?.clientWidth ?? 0),
70654
70448
  style: { position: "relative", marginTop: 12 },
70655
- children: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
70449
+ children: /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(
70656
70450
  "svg",
70657
70451
  {
70658
70452
  width: "100%",
70659
- height: HEIGHT2,
70453
+ height: HEIGHT,
70660
70454
  role: "img",
70661
70455
  "aria-label": `Median stay over the last ${points.length} days, now ${formatDuration(last.point.median)}`,
70662
70456
  style: { display: "block", overflow: "visible" },
@@ -70667,7 +70461,7 @@ var StayTrend = ({ points }) => {
70667
70461
  )
70668
70462
  ),
70669
70463
  children: [
70670
- weekMarks.map((x3) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70464
+ weekMarks.map((x3) => /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70671
70465
  "line",
70672
70466
  {
70673
70467
  x1: x3,
@@ -70679,7 +70473,7 @@ var StayTrend = ({ points }) => {
70679
70473
  },
70680
70474
  x3
70681
70475
  )),
70682
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70476
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70683
70477
  "line",
70684
70478
  {
70685
70479
  x1: 0,
@@ -70690,7 +70484,7 @@ var StayTrend = ({ points }) => {
70690
70484
  strokeWidth: 1
70691
70485
  }
70692
70486
  ),
70693
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70487
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70694
70488
  "text",
70695
70489
  {
70696
70490
  x: 0,
@@ -70701,7 +70495,7 @@ var StayTrend = ({ points }) => {
70701
70495
  children: "median stay"
70702
70496
  }
70703
70497
  ),
70704
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70498
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70705
70499
  "text",
70706
70500
  {
70707
70501
  x: plotWidth,
@@ -70713,7 +70507,7 @@ var StayTrend = ({ points }) => {
70713
70507
  children: formatDuration(peak) || "0s"
70714
70508
  }
70715
70509
  ),
70716
- runs.map((run) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70510
+ runs.map((run) => /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70717
70511
  "path",
70718
70512
  {
70719
70513
  d: areaOf(run),
@@ -70723,7 +70517,7 @@ var StayTrend = ({ points }) => {
70723
70517
  },
70724
70518
  `area-${run[0].point.t}`
70725
70519
  )),
70726
- runs.map((run) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70520
+ runs.map((run) => /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70727
70521
  "path",
70728
70522
  {
70729
70523
  d: lineOf(run),
@@ -70735,7 +70529,7 @@ var StayTrend = ({ points }) => {
70735
70529
  },
70736
70530
  `line-${run[0].point.t}`
70737
70531
  )),
70738
- hovered && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70532
+ hovered && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70739
70533
  "line",
70740
70534
  {
70741
70535
  x1: hovered.x,
@@ -70746,7 +70540,7 @@ var StayTrend = ({ points }) => {
70746
70540
  strokeWidth: 1
70747
70541
  }
70748
70542
  ),
70749
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70543
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70750
70544
  "circle",
70751
70545
  {
70752
70546
  cx: hovered?.x ?? last.x,
@@ -70757,7 +70551,7 @@ var StayTrend = ({ points }) => {
70757
70551
  strokeWidth: 2
70758
70552
  }
70759
70553
  ),
70760
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70554
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70761
70555
  "text",
70762
70556
  {
70763
70557
  x: (hovered ?? last).x + 8,
@@ -70768,22 +70562,22 @@ var StayTrend = ({ points }) => {
70768
70562
  children: formatDuration((hovered ?? last).point.median) || "0s"
70769
70563
  }
70770
70564
  ),
70771
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70565
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70772
70566
  "text",
70773
70567
  {
70774
70568
  x: 0,
70775
- y: HEIGHT2 - 2,
70569
+ y: HEIGHT - 2,
70776
70570
  fill: GUI_THEME.dim,
70777
70571
  fontSize: TEXT.label,
70778
70572
  fontFamily: "inherit",
70779
70573
  children: dayLabel(first, now)
70780
70574
  }
70781
70575
  ),
70782
- /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70576
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
70783
70577
  "text",
70784
70578
  {
70785
70579
  x: plotWidth,
70786
- y: HEIGHT2 - 2,
70580
+ y: HEIGHT - 2,
70787
70581
  textAnchor: "end",
70788
70582
  fill: GUI_THEME.dim,
70789
70583
  fontSize: TEXT.label,
@@ -70799,13 +70593,13 @@ var StayTrend = ({ points }) => {
70799
70593
  };
70800
70594
 
70801
70595
  // source/gui/client/components/SwimlaneStats.tsx
70802
- var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
70596
+ var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1);
70803
70597
  var CODE_TONE2 = GUI_THEME.green;
70804
70598
  var BOARD_TONE2 = GUI_THEME.accent;
70805
70599
  var FlowList = ({ flows, empty: empty3 }) => {
70806
- if (flows.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Empty, { children: empty3 });
70807
- return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
70808
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
70600
+ if (flows.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Empty, { children: empty3 });
70601
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(import_jsx_runtime71.Fragment, { children: [
70602
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70809
70603
  StackedBar,
70810
70604
  {
70811
70605
  segments: flows.map((flow3, index2) => ({
@@ -70815,15 +70609,15 @@ var FlowList = ({ flows, empty: empty3 }) => {
70815
70609
  }))
70816
70610
  }
70817
70611
  ),
70818
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { style: { marginTop: 12 }, children: flows.map((flow3, index2) => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
70612
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { style: { marginTop: 12 }, children: flows.map((flow3, index2) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70819
70613
  StatRow,
70820
70614
  {
70821
70615
  dot: seriesColor(index2),
70822
70616
  left: flow3.title,
70823
70617
  last: index2 === flows.length - 1,
70824
- right: /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(import_jsx_runtime72.Fragment, { children: [
70618
+ right: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(import_jsx_runtime71.Fragment, { children: [
70825
70619
  percent(flow3.share),
70826
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("span", { style: { color: GUI_THEME.dim }, children: [
70620
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("span", { style: { color: GUI_THEME.dim }, children: [
70827
70621
  " \xB7 ",
70828
70622
  flow3.count
70829
70623
  ] })
@@ -70841,8 +70635,8 @@ var SwimlaneStats = ({
70841
70635
  }) => {
70842
70636
  const dwell = laneDwell(swimlane.issues, Date.now());
70843
70637
  const stats = state?.stats ?? null;
70844
- return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(Aside, { dock, children: [
70845
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
70638
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(Aside, { dock, children: [
70639
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
70846
70640
  "div",
70847
70641
  {
70848
70642
  "data-testid": "swimlane-stats",
@@ -70854,7 +70648,7 @@ var SwimlaneStats = ({
70854
70648
  marginBottom: 12
70855
70649
  },
70856
70650
  children: [
70857
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
70651
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70858
70652
  "div",
70859
70653
  {
70860
70654
  style: {
@@ -70869,34 +70663,34 @@ var SwimlaneStats = ({
70869
70663
  children: swimlane.title
70870
70664
  }
70871
70665
  ),
70872
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Button, { variant: "ghost", onClick: onClose, title: "Close", children: "\xD7" })
70666
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Button, { variant: "ghost", onClick: onClose, title: "Close", children: "\xD7" })
70873
70667
  ]
70874
70668
  }
70875
70669
  ),
70876
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(Section, { title: "Time in this lane", tone: BOARD_TONE2, first: true, children: [
70877
- dwell ? /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { style: statGrid(true), children: [
70878
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
70670
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(Section, { title: "Time in this lane", tone: BOARD_TONE2, first: true, children: [
70671
+ dwell ? /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { style: statGrid(true), children: [
70672
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70879
70673
  Stat,
70880
70674
  {
70881
70675
  value: formatDuration(dwell.median) || "0s",
70882
70676
  label: "median stay"
70883
70677
  }
70884
70678
  ),
70885
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
70679
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70886
70680
  Stat,
70887
70681
  {
70888
70682
  value: formatDuration(dwell.max) || "0s",
70889
70683
  label: "longest stay"
70890
70684
  }
70891
70685
  ),
70892
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
70686
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70893
70687
  Stat,
70894
70688
  {
70895
70689
  value: formatDuration(dwell.mean) || "0s",
70896
70690
  label: "average stay"
70897
70691
  }
70898
70692
  ),
70899
- stats && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
70693
+ stats && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70900
70694
  Stat,
70901
70695
  {
70902
70696
  value: formatDuration(Date.now() - stats.createdAt) || "0s",
@@ -70904,14 +70698,14 @@ var SwimlaneStats = ({
70904
70698
  title: `Opened ${formatAbsolute(stats.createdAt)}`
70905
70699
  }
70906
70700
  )
70907
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Empty, { children: "Nothing is waiting here" }),
70908
- stats && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(StayTrend, { points: stats.stayTrend })
70701
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Empty, { children: "Nothing is waiting here" }),
70702
+ stats && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(StayTrend, { points: stats.stayTrend })
70909
70703
  ] }),
70910
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Section, { title: "Code standing here", tone: CODE_TONE2, children: stats && stats.code.commits === 0 ? /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Empty, { children: "No commits on the tickets in this lane" }) : stats && // The diff wears the same pill it wears on a commit row and a
70704
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Section, { title: "Code standing here", tone: CODE_TONE2, children: stats && stats.code.commits === 0 ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Empty, { children: "No commits on the tickets in this lane" }) : stats && // The diff wears the same pill it wears on a commit row and a
70911
70705
  // ticket's Code tab — a figure the reader already knows how to
70912
70706
  // read, rather than two large numbers that have to say "added"
70913
70707
  // and "removed" to mean anything.
70914
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
70708
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
70915
70709
  "div",
70916
70710
  {
70917
70711
  style: {
@@ -70921,7 +70715,7 @@ var SwimlaneStats = ({
70921
70715
  alignItems: "center"
70922
70716
  },
70923
70717
  children: [
70924
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(
70718
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
70925
70719
  "span",
70926
70720
  {
70927
70721
  style: {
@@ -70939,7 +70733,7 @@ var SwimlaneStats = ({
70939
70733
  ]
70940
70734
  }
70941
70735
  ),
70942
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
70736
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70943
70737
  DiffStat,
70944
70738
  {
70945
70739
  insertions: stats.code.insertions,
@@ -70949,10 +70743,10 @@ var SwimlaneStats = ({
70949
70743
  ]
70950
70744
  }
70951
70745
  ) }),
70952
- /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(Section, { title: "Usually arrives from", tone: BOARD_TONE2, children: [
70953
- state?.loading && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Empty, { children: "Reading the board\u2026" }),
70954
- state?.error && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Empty, { children: state.error }),
70955
- stats && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
70746
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(Section, { title: "Usually arrives from", tone: BOARD_TONE2, children: [
70747
+ state?.loading && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Empty, { children: "Reading the board\u2026" }),
70748
+ state?.error && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Empty, { children: state.error }),
70749
+ stats && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70956
70750
  FlowList,
70957
70751
  {
70958
70752
  flows: stats.arrivesFrom,
@@ -70960,7 +70754,7 @@ var SwimlaneStats = ({
70960
70754
  }
70961
70755
  )
70962
70756
  ] }),
70963
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(Section, { title: "Usually moves on to", tone: BOARD_TONE2, children: stats && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
70757
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Section, { title: "Usually moves on to", tone: BOARD_TONE2, children: stats && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
70964
70758
  FlowList,
70965
70759
  {
70966
70760
  flows: stats.movesOnTo,
@@ -70971,9 +70765,9 @@ var SwimlaneStats = ({
70971
70765
  };
70972
70766
 
70973
70767
  // source/gui/client/components/GlobalScrollbarStyles.tsx
70974
- var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
70768
+ var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
70975
70769
  var SCROLLBAR_SIZE = 3;
70976
- var GlobalScrollbarStyles = () => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("style", { children: `
70770
+ var GlobalScrollbarStyles = () => /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("style", { children: `
70977
70771
  /* Placeholders are a pseudo-element too. Unstyled they take the
70978
70772
  browser's warm grey, which sits oddly against the palette. */
70979
70773
  input::placeholder,
@@ -71022,9 +70816,9 @@ var GlobalScrollbarStyles = () => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
71022
70816
  ` });
71023
70817
 
71024
70818
  // source/gui/client/components/TooltipLayer.tsx
71025
- var import_react43 = __toESM(require_react(), 1);
70819
+ var import_react42 = __toESM(require_react(), 1);
71026
70820
  var import_react_dom = __toESM(require_react_dom(), 1);
71027
- var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1);
70821
+ var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
71028
70822
  var DELAY_MS = 500;
71029
70823
  var GAP = 8;
71030
70824
  var MARGIN = 6;
@@ -71050,12 +70844,12 @@ var triggerFor = (target) => {
71050
70844
  return owner instanceof HTMLElement ? owner : null;
71051
70845
  };
71052
70846
  var TooltipLayer = () => {
71053
- const tip = (0, import_react43.useRef)(null);
71054
- const timer = (0, import_react43.useRef)(null);
71055
- const stashed = (0, import_react43.useRef)(null);
71056
- const [shown, setShown] = (0, import_react43.useState)(null);
71057
- const [placement, setPlacement] = (0, import_react43.useState)(null);
71058
- (0, import_react43.useEffect)(() => {
70847
+ const tip = (0, import_react42.useRef)(null);
70848
+ const timer = (0, import_react42.useRef)(null);
70849
+ const stashed = (0, import_react42.useRef)(null);
70850
+ const [shown, setShown] = (0, import_react42.useState)(null);
70851
+ const [placement, setPlacement] = (0, import_react42.useState)(null);
70852
+ (0, import_react42.useEffect)(() => {
71059
70853
  const cancel = () => {
71060
70854
  if (timer.current !== null) clearTimeout(timer.current);
71061
70855
  timer.current = null;
@@ -71121,7 +70915,7 @@ var TooltipLayer = () => {
71121
70915
  window.removeEventListener("blur", hide);
71122
70916
  };
71123
70917
  }, []);
71124
- (0, import_react43.useEffect)(() => {
70918
+ (0, import_react42.useEffect)(() => {
71125
70919
  if (!shown) return setPlacement(null);
71126
70920
  const node2 = tip.current;
71127
70921
  if (!node2) return;
@@ -71132,7 +70926,7 @@ var TooltipLayer = () => {
71132
70926
  )
71133
70927
  );
71134
70928
  }, [shown]);
71135
- (0, import_react43.useEffect)(() => {
70929
+ (0, import_react42.useEffect)(() => {
71136
70930
  if (!shown) return;
71137
70931
  const check = setInterval(() => {
71138
70932
  if (!shown.trigger.isConnected) setShown(null);
@@ -71141,7 +70935,7 @@ var TooltipLayer = () => {
71141
70935
  }, [shown]);
71142
70936
  if (!shown) return null;
71143
70937
  return (0, import_react_dom.createPortal)(
71144
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
70938
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
71145
70939
  "div",
71146
70940
  {
71147
70941
  ref: tip,
@@ -71178,8 +70972,8 @@ var TooltipLayer = () => {
71178
70972
  };
71179
70973
 
71180
70974
  // source/gui/client/components/ErrorToast.tsx
71181
- var import_jsx_runtime75 = __toESM(require_jsx_runtime(), 1);
71182
- var ErrorToast = ({ message, onDismiss }) => /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(
70975
+ var import_jsx_runtime74 = __toESM(require_jsx_runtime(), 1);
70976
+ var ErrorToast = ({ message, onDismiss }) => /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
71183
70977
  "div",
71184
70978
  {
71185
70979
  style: {
@@ -71200,8 +70994,8 @@ var ErrorToast = ({ message, onDismiss }) => /* @__PURE__ */ (0, import_jsx_runt
71200
70994
  boxShadow: "0 4px 16px rgba(0, 0, 0, 0.4)"
71201
70995
  },
71202
70996
  children: [
71203
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { style: { flex: 1, minWidth: 0, overflowWrap: "anywhere" }, children: message }),
71204
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
70997
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { style: { flex: 1, minWidth: 0, overflowWrap: "anywhere" }, children: message }),
70998
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
71205
70999
  "button",
71206
71000
  {
71207
71001
  onClick: onDismiss,
@@ -71222,7 +71016,7 @@ var ErrorToast = ({ message, onDismiss }) => /* @__PURE__ */ (0, import_jsx_runt
71222
71016
  );
71223
71017
 
71224
71018
  // source/gui/client/components/TimeScrubber.tsx
71225
- var import_react47 = __toESM(require_react(), 1);
71019
+ var import_react46 = __toESM(require_react(), 1);
71226
71020
 
71227
71021
  // source/gui/client/lib/board-selection.ts
71228
71022
  var DEFAULT_SELECTION = {
@@ -71459,8 +71253,8 @@ var withSelectedIdentities = (listed, only, known) => {
71459
71253
  };
71460
71254
 
71461
71255
  // source/gui/client/components/ScatterCanvas.tsx
71462
- var import_react44 = __toESM(require_react(), 1);
71463
- var import_jsx_runtime76 = __toESM(require_jsx_runtime(), 1);
71256
+ var import_react43 = __toESM(require_react(), 1);
71257
+ var import_jsx_runtime75 = __toESM(require_jsx_runtime(), 1);
71464
71258
  var HIT_RADIUS = 7;
71465
71259
  var pointAt = (layers, x3, y3, width) => {
71466
71260
  let best = null;
@@ -71489,21 +71283,21 @@ var ScatterCanvas = ({
71489
71283
  onPointLeave,
71490
71284
  onPressCommit
71491
71285
  }) => {
71492
- const canvasRef = (0, import_react44.useRef)(null);
71493
- const sizeRef = (0, import_react44.useRef)({ width: 0, height: 0 });
71494
- const layersRef = (0, import_react44.useRef)(layers);
71286
+ const canvasRef = (0, import_react43.useRef)(null);
71287
+ const sizeRef = (0, import_react43.useRef)({ width: 0, height: 0 });
71288
+ const layersRef = (0, import_react43.useRef)(layers);
71495
71289
  layersRef.current = layers;
71496
- const activeHighlight = (0, import_react44.useMemo)(
71290
+ const activeHighlight = (0, import_react43.useMemo)(
71497
71291
  () => highlightId !== null && layers.some((layer) => layer.points.some((point4) => point4.id === highlightId)) ? highlightId : null,
71498
71292
  [layers, highlightId]
71499
71293
  );
71500
- const highlightRef = (0, import_react44.useRef)(activeHighlight);
71294
+ const highlightRef = (0, import_react43.useRef)(activeHighlight);
71501
71295
  highlightRef.current = activeHighlight;
71502
- const phasesRef = (0, import_react44.useRef)(/* @__PURE__ */ new Map());
71503
- const frameRef = (0, import_react44.useRef)(null);
71504
- const hoveredRef = (0, import_react44.useRef)(null);
71505
- const [entrancePlaying, setEntrancePlaying] = (0, import_react44.useState)(false);
71506
- const paint = (0, import_react44.useCallback)((now) => {
71296
+ const phasesRef = (0, import_react43.useRef)(/* @__PURE__ */ new Map());
71297
+ const frameRef = (0, import_react43.useRef)(null);
71298
+ const hoveredRef = (0, import_react43.useRef)(null);
71299
+ const [entrancePlaying, setEntrancePlaying] = (0, import_react43.useState)(false);
71300
+ const paint = (0, import_react43.useCallback)((now) => {
71507
71301
  const canvas = canvasRef.current;
71508
71302
  const context = canvas?.getContext("2d");
71509
71303
  if (!canvas || !context) return false;
@@ -71540,7 +71334,7 @@ var ScatterCanvas = ({
71540
71334
  context.globalAlpha = 1;
71541
71335
  return running;
71542
71336
  }, []);
71543
- const run = (0, import_react44.useCallback)(() => {
71337
+ const run = (0, import_react43.useCallback)(() => {
71544
71338
  if (frameRef.current !== null) return;
71545
71339
  const step = () => {
71546
71340
  frameRef.current = null;
@@ -71550,7 +71344,7 @@ var ScatterCanvas = ({
71550
71344
  };
71551
71345
  frameRef.current = requestAnimationFrame(step);
71552
71346
  }, [paint]);
71553
- (0, import_react44.useEffect)(() => {
71347
+ (0, import_react43.useEffect)(() => {
71554
71348
  const canvas = canvasRef.current;
71555
71349
  const parent = canvas?.parentElement;
71556
71350
  if (!canvas || !parent) return;
@@ -71571,7 +71365,7 @@ var ScatterCanvas = ({
71571
71365
  return () => observer.disconnect();
71572
71366
  }, [paint]);
71573
71367
  const signature = layers.map((layer) => `${layer.id}:${layer.generation}:${layer.leaving}`).join("|");
71574
- (0, import_react44.useEffect)(() => {
71368
+ (0, import_react43.useEffect)(() => {
71575
71369
  const seen = /* @__PURE__ */ new Set();
71576
71370
  for (const layer of layers) {
71577
71371
  seen.add(layer.id);
@@ -71596,10 +71390,10 @@ var ScatterCanvas = ({
71596
71390
  if (animate) run();
71597
71391
  else paint(performance.now());
71598
71392
  }, [signature, animate, run, paint]);
71599
- (0, import_react44.useEffect)(() => {
71393
+ (0, import_react43.useEffect)(() => {
71600
71394
  if (frameRef.current === null) paint(performance.now());
71601
71395
  }, [layers, activeHighlight, paint]);
71602
- (0, import_react44.useEffect)(
71396
+ (0, import_react43.useEffect)(
71603
71397
  () => () => {
71604
71398
  if (frameRef.current !== null) cancelAnimationFrame(frameRef.current);
71605
71399
  },
@@ -71614,7 +71408,7 @@ var ScatterCanvas = ({
71614
71408
  rect.width
71615
71409
  );
71616
71410
  };
71617
- return /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
71411
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
71618
71412
  "canvas",
71619
71413
  {
71620
71414
  ref: canvasRef,
@@ -71639,8 +71433,8 @@ var ScatterCanvas = ({
71639
71433
  };
71640
71434
 
71641
71435
  // source/gui/client/components/IconBars.tsx
71642
- var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1);
71643
- var IconBars = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
71436
+ var import_jsx_runtime76 = __toESM(require_jsx_runtime(), 1);
71437
+ var IconBars = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
71644
71438
  "svg",
71645
71439
  {
71646
71440
  width: size,
@@ -71652,18 +71446,18 @@ var IconBars = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)
71652
71446
  strokeLinecap: "round",
71653
71447
  "aria-hidden": "true",
71654
71448
  children: [
71655
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("line", { x1: "3", y1: "8.5", x2: "3", y2: "15.5" }),
71656
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("line", { x1: "7.5", y1: "4.5", x2: "7.5", y2: "19.5" }),
71657
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("line", { x1: "12", y1: "7", x2: "12", y2: "17" }),
71658
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("line", { x1: "16.5", y1: "3", x2: "16.5", y2: "21" }),
71659
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("line", { x1: "21", y1: "9.5", x2: "21", y2: "14.5" })
71449
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("line", { x1: "3", y1: "8.5", x2: "3", y2: "15.5" }),
71450
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("line", { x1: "7.5", y1: "4.5", x2: "7.5", y2: "19.5" }),
71451
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("line", { x1: "12", y1: "7", x2: "12", y2: "17" }),
71452
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("line", { x1: "16.5", y1: "3", x2: "16.5", y2: "21" }),
71453
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("line", { x1: "21", y1: "9.5", x2: "21", y2: "14.5" })
71660
71454
  ]
71661
71455
  }
71662
71456
  );
71663
71457
 
71664
71458
  // source/gui/client/components/IconChevronLeft.tsx
71665
- var import_jsx_runtime78 = __toESM(require_jsx_runtime(), 1);
71666
- var IconChevronLeft = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
71459
+ var import_jsx_runtime77 = __toESM(require_jsx_runtime(), 1);
71460
+ var IconChevronLeft = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
71667
71461
  "svg",
71668
71462
  {
71669
71463
  width: size,
@@ -71675,13 +71469,13 @@ var IconChevronLeft = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime7
71675
71469
  strokeLinecap: "round",
71676
71470
  strokeLinejoin: "round",
71677
71471
  "aria-hidden": "true",
71678
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("polyline", { points: "15 18 9 12 15 6" })
71472
+ children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("polyline", { points: "15 18 9 12 15 6" })
71679
71473
  }
71680
71474
  );
71681
71475
 
71682
71476
  // source/gui/client/components/IconLog.tsx
71683
- var import_jsx_runtime79 = __toESM(require_jsx_runtime(), 1);
71684
- var IconLog = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(
71477
+ var import_jsx_runtime78 = __toESM(require_jsx_runtime(), 1);
71478
+ var IconLog = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
71685
71479
  "svg",
71686
71480
  {
71687
71481
  width: size,
@@ -71693,19 +71487,19 @@ var IconLog = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(
71693
71487
  strokeLinecap: "round",
71694
71488
  "aria-hidden": "true",
71695
71489
  children: [
71696
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("line", { x1: "4", y1: "6", x2: "4.01", y2: "6" }),
71697
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("line", { x1: "9", y1: "6", x2: "20", y2: "6" }),
71698
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("line", { x1: "4", y1: "12", x2: "4.01", y2: "12" }),
71699
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("line", { x1: "9", y1: "12", x2: "16", y2: "12" }),
71700
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("line", { x1: "4", y1: "18", x2: "4.01", y2: "18" }),
71701
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("line", { x1: "9", y1: "18", x2: "19", y2: "18" })
71490
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("line", { x1: "4", y1: "6", x2: "4.01", y2: "6" }),
71491
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("line", { x1: "9", y1: "6", x2: "20", y2: "6" }),
71492
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("line", { x1: "4", y1: "12", x2: "4.01", y2: "12" }),
71493
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("line", { x1: "9", y1: "12", x2: "16", y2: "12" }),
71494
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("line", { x1: "4", y1: "18", x2: "4.01", y2: "18" }),
71495
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("line", { x1: "9", y1: "18", x2: "19", y2: "18" })
71702
71496
  ]
71703
71497
  }
71704
71498
  );
71705
71499
 
71706
71500
  // source/gui/client/components/IconTimeline.tsx
71707
- var import_jsx_runtime80 = __toESM(require_jsx_runtime(), 1);
71708
- var IconTimeline = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
71501
+ var import_jsx_runtime79 = __toESM(require_jsx_runtime(), 1);
71502
+ var IconTimeline = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)(
71709
71503
  "svg",
71710
71504
  {
71711
71505
  width: size,
@@ -71717,17 +71511,17 @@ var IconTimeline = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime80.j
71717
71511
  strokeLinecap: "round",
71718
71512
  "aria-hidden": "true",
71719
71513
  children: [
71720
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("line", { x1: "3", y1: "8", x2: "21", y2: "8" }),
71721
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("line", { x1: "7", y1: "8", x2: "7", y2: "13" }),
71722
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "17" }),
71723
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("line", { x1: "17", y1: "8", x2: "17", y2: "13" })
71514
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("line", { x1: "3", y1: "8", x2: "21", y2: "8" }),
71515
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("line", { x1: "7", y1: "8", x2: "7", y2: "13" }),
71516
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("line", { x1: "12", y1: "8", x2: "12", y2: "17" }),
71517
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("line", { x1: "17", y1: "8", x2: "17", y2: "13" })
71724
71518
  ]
71725
71519
  }
71726
71520
  );
71727
71521
 
71728
71522
  // source/gui/client/components/IconPlayback.tsx
71729
- var import_jsx_runtime81 = __toESM(require_jsx_runtime(), 1);
71730
- var IconPlay = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
71523
+ var import_jsx_runtime80 = __toESM(require_jsx_runtime(), 1);
71524
+ var IconPlay = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
71731
71525
  "svg",
71732
71526
  {
71733
71527
  width: size,
@@ -71738,10 +71532,10 @@ var IconPlay = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
71738
71532
  strokeWidth: "2",
71739
71533
  strokeLinejoin: "round",
71740
71534
  "aria-hidden": "true",
71741
- children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("path", { d: "M8 5.5 19 12 8 18.5Z" })
71535
+ children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("path", { d: "M8 5.5 19 12 8 18.5Z" })
71742
71536
  }
71743
71537
  );
71744
- var IconPause = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
71538
+ var IconPause = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
71745
71539
  "svg",
71746
71540
  {
71747
71541
  width: size,
@@ -71753,12 +71547,12 @@ var IconPause = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime81.jsxs
71753
71547
  strokeLinecap: "round",
71754
71548
  "aria-hidden": "true",
71755
71549
  children: [
71756
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("line", { x1: "9", y1: "5.5", x2: "9", y2: "18.5" }),
71757
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("line", { x1: "15", y1: "5.5", x2: "15", y2: "18.5" })
71550
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("line", { x1: "9", y1: "5.5", x2: "9", y2: "18.5" }),
71551
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("line", { x1: "15", y1: "5.5", x2: "15", y2: "18.5" })
71758
71552
  ]
71759
71553
  }
71760
71554
  );
71761
- var IconReplay = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
71555
+ var IconReplay = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
71762
71556
  "svg",
71763
71557
  {
71764
71558
  width: size,
@@ -71771,12 +71565,12 @@ var IconReplay = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx
71771
71565
  strokeLinejoin: "round",
71772
71566
  "aria-hidden": "true",
71773
71567
  children: [
71774
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("path", { d: "M20 12a8 8 0 1 1-2.6-5.9" }),
71775
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("polyline", { points: "20 3 20 8 15 8" })
71568
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("path", { d: "M20 12a8 8 0 1 1-2.6-5.9" }),
71569
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("polyline", { points: "20 3 20 8 15 8" })
71776
71570
  ]
71777
71571
  }
71778
71572
  );
71779
- var IconClose = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
71573
+ var IconClose = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
71780
71574
  "svg",
71781
71575
  {
71782
71576
  width: size,
@@ -71788,15 +71582,15 @@ var IconClose = ({ size = 14 }) => /* @__PURE__ */ (0, import_jsx_runtime81.jsxs
71788
71582
  strokeLinecap: "round",
71789
71583
  "aria-hidden": "true",
71790
71584
  children: [
71791
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" }),
71792
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" })
71585
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" }),
71586
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" })
71793
71587
  ]
71794
71588
  }
71795
71589
  );
71796
71590
 
71797
71591
  // source/gui/client/components/IconScatter.tsx
71798
- var import_jsx_runtime82 = __toESM(require_jsx_runtime(), 1);
71799
- var IconScatter = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(
71592
+ var import_jsx_runtime81 = __toESM(require_jsx_runtime(), 1);
71593
+ var IconScatter = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
71800
71594
  "svg",
71801
71595
  {
71802
71596
  width: size,
@@ -71806,18 +71600,18 @@ var IconScatter = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime82.js
71806
71600
  stroke: "none",
71807
71601
  "aria-hidden": "true",
71808
71602
  children: [
71809
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("circle", { cx: "4.5", cy: "8", r: "2.2" }),
71810
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("circle", { cx: "9.5", cy: "17", r: "2.2" }),
71811
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("circle", { cx: "13", cy: "6.5", r: "2.2" }),
71812
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("circle", { cx: "17", cy: "14.5", r: "2.2" }),
71813
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("circle", { cx: "20.5", cy: "8.5", r: "2.2" })
71603
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("circle", { cx: "4.5", cy: "8", r: "2.2" }),
71604
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("circle", { cx: "9.5", cy: "17", r: "2.2" }),
71605
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("circle", { cx: "13", cy: "6.5", r: "2.2" }),
71606
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("circle", { cx: "17", cy: "14.5", r: "2.2" }),
71607
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("circle", { cx: "20.5", cy: "8.5", r: "2.2" })
71814
71608
  ]
71815
71609
  }
71816
71610
  );
71817
71611
 
71818
71612
  // source/gui/client/components/ScrubberSelects.tsx
71819
- var import_react45 = __toESM(require_react(), 1);
71820
- var import_jsx_runtime83 = __toESM(require_jsx_runtime(), 1);
71613
+ var import_react44 = __toESM(require_react(), 1);
71614
+ var import_jsx_runtime82 = __toESM(require_jsx_runtime(), 1);
71821
71615
  var SCOPE_ONLY_LABEL = "Scope only";
71822
71616
  var TICKET_ONLY_LABEL = "Ticket only";
71823
71617
  var mutedStyle = {
@@ -71922,8 +71716,8 @@ var onlyButtonStyle = {
71922
71716
  cursor: "pointer"
71923
71717
  };
71924
71718
  var useDismissOnOutsideClick = (open, onDismiss) => {
71925
- const ref = (0, import_react45.useRef)(null);
71926
- (0, import_react45.useEffect)(() => {
71719
+ const ref = (0, import_react44.useRef)(null);
71720
+ (0, import_react44.useEffect)(() => {
71927
71721
  if (!open) return;
71928
71722
  const onPointerDown = (event) => {
71929
71723
  if (!ref.current?.contains(event.target)) onDismiss();
@@ -71969,14 +71763,14 @@ var BoardSeriesGroup = ({
71969
71763
  const label = sole ? `${VIEW_LABELS[view]}: ${sole.name}` : partial ? `${VIEW_LABELS[view]} (multi)` : elsewhere ? `${VIEW_LABELS[view]} (filtered)` : VIEW_LABELS[view];
71970
71764
  const color2 = sole?.color ?? (partial || elsewhere ? GUI_THEME.dim2 : boardViewColor(view));
71971
71765
  const ref = useDismissOnOutsideClick(expanded, onToggleExpanded);
71972
- return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(
71766
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(
71973
71767
  "div",
71974
71768
  {
71975
71769
  ref,
71976
71770
  style: { position: "relative", display: "flex", flexDirection: "column" },
71977
71771
  children: [
71978
- /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
71979
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
71772
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
71773
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
71980
71774
  Checkbox,
71981
71775
  {
71982
71776
  label: null,
@@ -71987,7 +71781,7 @@ var BoardSeriesGroup = ({
71987
71781
  onChange: onChangeShowIssues
71988
71782
  }
71989
71783
  ),
71990
- /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(
71784
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(
71991
71785
  "button",
71992
71786
  {
71993
71787
  type: "button",
@@ -72001,7 +71795,7 @@ var BoardSeriesGroup = ({
72001
71795
  ...connected ? {} : mutedStyle
72002
71796
  },
72003
71797
  children: [
72004
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
71798
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
72005
71799
  "span",
72006
71800
  {
72007
71801
  style: {
@@ -72012,17 +71806,17 @@ var BoardSeriesGroup = ({
72012
71806
  children: label
72013
71807
  }
72014
71808
  ),
72015
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { style: { display: "inline-flex", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconChevronDown, { size: 12 }) })
71809
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { style: { display: "inline-flex", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(IconChevronDown, { size: 12 }) })
72016
71810
  ]
72017
71811
  }
72018
71812
  )
72019
71813
  ] }),
72020
- expanded && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { role: "group", "aria-label": "Filter the board", style: popoverStyle, children: FILTER_AXES.map((axis) => {
71814
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { role: "group", "aria-label": "Filter the board", style: popoverStyle, children: FILTER_AXES.map((axis) => {
72021
71815
  const option2 = VIEW_FOR_AXIS2[axis];
72022
71816
  const state = axisStates[axis];
72023
71817
  const open = expandedAxis === axis;
72024
71818
  const rowLabel = VIEW_LABELS[option2].toLowerCase();
72025
- return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(
71819
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(
72026
71820
  "div",
72027
71821
  {
72028
71822
  style: {
@@ -72031,8 +71825,8 @@ var BoardSeriesGroup = ({
72031
71825
  gap: 7
72032
71826
  },
72033
71827
  children: [
72034
- /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 3 }, children: [
72035
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
71828
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 3 }, children: [
71829
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
72036
71830
  Checkbox,
72037
71831
  {
72038
71832
  label: VIEW_LABELS[option2],
@@ -72044,7 +71838,7 @@ var BoardSeriesGroup = ({
72044
71838
  onChange: (next) => onToggleAxis(axis, next)
72045
71839
  }
72046
71840
  ),
72047
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
71841
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
72048
71842
  "button",
72049
71843
  {
72050
71844
  type: "button",
@@ -72059,11 +71853,11 @@ var BoardSeriesGroup = ({
72059
71853
  // holding back.
72060
71854
  color: state === "some" ? boardViewColor(option2) : disclosureStyle2.color
72061
71855
  },
72062
- children: open ? /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconChevronDown, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconChevronRight, { size: 12 })
71856
+ children: open ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(IconChevronDown, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(IconChevronRight, { size: 12 })
72063
71857
  }
72064
71858
  )
72065
71859
  ] }),
72066
- open && identitiesByAxis[axis].length > 0 && /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
71860
+ open && identitiesByAxis[axis].length > 0 && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
72067
71861
  "div",
72068
71862
  {
72069
71863
  role: "group",
@@ -72075,7 +71869,7 @@ var BoardSeriesGroup = ({
72075
71869
  maxHeight: 132,
72076
71870
  overflowY: "auto"
72077
71871
  },
72078
- children: identitiesByAxis[axis].map((identity) => /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(
71872
+ children: identitiesByAxis[axis].map((identity) => /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(
72079
71873
  "div",
72080
71874
  {
72081
71875
  style: {
@@ -72085,7 +71879,7 @@ var BoardSeriesGroup = ({
72085
71879
  gap: 10
72086
71880
  },
72087
71881
  children: [
72088
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
71882
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
72089
71883
  Checkbox,
72090
71884
  {
72091
71885
  label: identity.name,
@@ -72095,7 +71889,7 @@ var BoardSeriesGroup = ({
72095
71889
  onChange: (next) => onToggleIdentity(axis, identity.id, next)
72096
71890
  }
72097
71891
  ),
72098
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
71892
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
72099
71893
  "button",
72100
71894
  {
72101
71895
  type: "button",
@@ -72128,13 +71922,13 @@ var ScopeSelect = ({
72128
71922
  connected,
72129
71923
  onChangeScope
72130
71924
  }) => {
72131
- const [open, setOpen] = (0, import_react45.useState)(false);
71925
+ const [open, setOpen] = (0, import_react44.useState)(false);
72132
71926
  const ref = useDismissOnOutsideClick(open, () => setOpen(false));
72133
- (0, import_react45.useEffect)(() => {
71927
+ (0, import_react44.useEffect)(() => {
72134
71928
  if (!connected) setOpen(false);
72135
71929
  }, [connected]);
72136
- return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { ref, style: { position: "relative" }, children: [
72137
- /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(
71930
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { ref, style: { position: "relative" }, children: [
71931
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(
72138
71932
  "button",
72139
71933
  {
72140
71934
  type: "button",
@@ -72149,20 +71943,20 @@ var ScopeSelect = ({
72149
71943
  width: SCOPE_SELECT_WIDTH
72150
71944
  },
72151
71945
  children: [
72152
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { children: zoomed ? "Zoom" : scopeButtonLabel(scope) }),
72153
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { style: { display: "inline-flex", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconChevronDown, { size: 12 }) })
71946
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { children: zoomed ? "Zoom" : scopeButtonLabel(scope) }),
71947
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { style: { display: "inline-flex", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(IconChevronDown, { size: 12 }) })
72154
71948
  ]
72155
71949
  }
72156
71950
  ),
72157
71951
  open && // Narrower than the shared popover's default, which is sized for the
72158
71952
  // series menu's identity lists: a column of period names needs no
72159
71953
  // more than the trigger it drops from.
72160
- /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
71954
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
72161
71955
  "div",
72162
71956
  {
72163
71957
  role: "listbox",
72164
71958
  style: { ...popoverStyle, minWidth: SCOPE_SELECT_WIDTH },
72165
- children: SCOPES.map((option2) => /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
71959
+ children: SCOPES.map((option2) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
72166
71960
  "button",
72167
71961
  {
72168
71962
  type: "button",
@@ -72192,7 +71986,7 @@ var ScopeSelect = ({
72192
71986
  };
72193
71987
 
72194
71988
  // source/gui/client/components/ScrubberControls.tsx
72195
- var import_jsx_runtime84 = __toESM(require_jsx_runtime(), 1);
71989
+ var import_jsx_runtime83 = __toESM(require_jsx_runtime(), 1);
72196
71990
  var toggleButtonStyle = (active) => ({
72197
71991
  background: "transparent",
72198
71992
  border: `1px solid ${active ? GUI_THEME.accent : GUI_THEME.dim}`,
@@ -72278,7 +72072,7 @@ var ScrubberControls = ({
72278
72072
  onSetExpandedAxis
72279
72073
  }) => {
72280
72074
  const everythingInScope = !isPeriodWindow(scope, zoomed);
72281
- return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
72075
+ return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(
72282
72076
  "div",
72283
72077
  {
72284
72078
  style: {
@@ -72288,9 +72082,9 @@ var ScrubberControls = ({
72288
72082
  gap: 12
72289
72083
  },
72290
72084
  children: [
72291
- /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
72292
- (scope !== "all" || zoomed || ticketFocus) && /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 2 }, children: [
72293
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72085
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
72086
+ (scope !== "all" || zoomed || ticketFocus) && /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 2 }, children: [
72087
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72294
72088
  "button",
72295
72089
  {
72296
72090
  title: ticketFocus ? 'The ticket\u2019s own stretch \u2014 untick "Ticket only" to page' : "Earlier",
@@ -72301,10 +72095,10 @@ var ScrubberControls = ({
72301
72095
  ...navButtonStyle,
72302
72096
  ...connected && !ticketFocus ? {} : mutedStyle
72303
72097
  },
72304
- children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconChevronLeft, { size: 12 })
72098
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconChevronLeft, { size: 12 })
72305
72099
  }
72306
72100
  ),
72307
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72101
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72308
72102
  "span",
72309
72103
  {
72310
72104
  style: {
@@ -72326,7 +72120,7 @@ var ScrubberControls = ({
72326
72120
  )
72327
72121
  }
72328
72122
  ),
72329
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72123
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72330
72124
  "button",
72331
72125
  {
72332
72126
  title: "Later",
@@ -72338,11 +72132,11 @@ var ScrubberControls = ({
72338
72132
  opacity: atLatest || ticketFocus ? 0.35 : 1,
72339
72133
  cursor: atLatest || ticketFocus ? "default" : "pointer"
72340
72134
  },
72341
- children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconChevronRight, { size: 12 })
72135
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconChevronRight, { size: 12 })
72342
72136
  }
72343
72137
  )
72344
72138
  ] }),
72345
- narrow ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72139
+ narrow ? /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72346
72140
  ScopeSelect,
72347
72141
  {
72348
72142
  scope,
@@ -72350,8 +72144,8 @@ var ScrubberControls = ({
72350
72144
  connected,
72351
72145
  onChangeScope
72352
72146
  }
72353
- ) : /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { style: { display: "flex", gap: 2 }, children: [
72354
- SCOPES.map((option2) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72147
+ ) : /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { style: { display: "flex", gap: 2 }, children: [
72148
+ SCOPES.map((option2) => /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72355
72149
  "button",
72356
72150
  {
72357
72151
  "aria-pressed": !zoomed && !ticketFocus && scope === option2,
@@ -72367,7 +72161,7 @@ var ScrubberControls = ({
72367
72161
  },
72368
72162
  option2
72369
72163
  )),
72370
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72164
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72371
72165
  "button",
72372
72166
  {
72373
72167
  title: ticketFocus ? 'Held behind the ticket\u2019s own stretch \u2014 untick "Ticket only" to come back to it' : zoomed ? "A window dragged out on the chart \u2014 pick a period to leave it" : "Drag across the chart to zoom the window to a stretch of it",
@@ -72383,8 +72177,8 @@ var ScrubberControls = ({
72383
72177
  )
72384
72178
  ] })
72385
72179
  ] }),
72386
- /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { style: { display: "flex", gap: 2 }, children: [
72387
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72180
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { style: { display: "flex", gap: 2 }, children: [
72181
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72388
72182
  "button",
72389
72183
  {
72390
72184
  title: "Volume \u2014 how much happened, per equal-width period, with no empty gaps for quiet stretches",
@@ -72396,10 +72190,10 @@ var ScrubberControls = ({
72396
72190
  ...iconToggleButtonStyle(layoutMode === "even"),
72397
72191
  ...connected ? {} : mutedStyle
72398
72192
  },
72399
- children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconBars, { size: 13 })
72193
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconBars, { size: 13 })
72400
72194
  }
72401
72195
  ),
72402
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72196
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72403
72197
  "button",
72404
72198
  {
72405
72199
  title: "Events \u2014 individual events by exact moment, x is elapsed time and y is time of day",
@@ -72411,12 +72205,12 @@ var ScrubberControls = ({
72411
72205
  ...iconToggleButtonStyle(layoutMode === "real"),
72412
72206
  ...connected ? {} : mutedStyle
72413
72207
  },
72414
- children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconScatter, { size: 13 })
72208
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconScatter, { size: 13 })
72415
72209
  }
72416
72210
  )
72417
72211
  ] }),
72418
- /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { style: { display: "flex", gap: 12, alignItems: "center" }, children: [
72419
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72212
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { style: { display: "flex", gap: 12, alignItems: "center" }, children: [
72213
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72420
72214
  Checkbox,
72421
72215
  {
72422
72216
  label: "Code",
@@ -72427,7 +72221,7 @@ var ScrubberControls = ({
72427
72221
  onChange: onChangeShowCommits
72428
72222
  }
72429
72223
  ),
72430
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72224
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72431
72225
  BoardSeriesGroup,
72432
72226
  {
72433
72227
  connected,
@@ -72448,7 +72242,7 @@ var ScrubberControls = ({
72448
72242
  onSetExpandedAxis
72449
72243
  }
72450
72244
  ),
72451
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72245
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72452
72246
  Checkbox,
72453
72247
  {
72454
72248
  label: SCOPE_ONLY_LABEL,
@@ -72458,7 +72252,7 @@ var ScrubberControls = ({
72458
72252
  onChange: onChangeWindowOnly
72459
72253
  }
72460
72254
  ),
72461
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72255
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72462
72256
  Checkbox,
72463
72257
  {
72464
72258
  label: TICKET_ONLY_LABEL,
@@ -72469,7 +72263,7 @@ var ScrubberControls = ({
72469
72263
  }
72470
72264
  )
72471
72265
  ] }),
72472
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72266
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72473
72267
  "button",
72474
72268
  {
72475
72269
  onClick: onReturnToLive,
@@ -72497,7 +72291,7 @@ var ScrubberControls = ({
72497
72291
  children: isScrubbing ? "Resume" : ""
72498
72292
  }
72499
72293
  ),
72500
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72294
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72501
72295
  ScrubberPlayButton,
72502
72296
  {
72503
72297
  canPlay,
@@ -72514,7 +72308,7 @@ var ScrubberHeader = ({
72514
72308
  onToggleCollapsed,
72515
72309
  logOpen,
72516
72310
  onChangeLogOpen
72517
- }) => /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
72311
+ }) => /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)(
72518
72312
  "div",
72519
72313
  {
72520
72314
  style: {
@@ -72525,7 +72319,7 @@ var ScrubberHeader = ({
72525
72319
  whiteSpace: "nowrap"
72526
72320
  },
72527
72321
  children: [
72528
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72322
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72529
72323
  "button",
72530
72324
  {
72531
72325
  "data-testid": "log-toggle",
@@ -72537,10 +72331,10 @@ var ScrubberHeader = ({
72537
72331
  ...headerButtonStyle,
72538
72332
  color: logOpen ? GUI_THEME.accent : GUI_THEME.secondary
72539
72333
  },
72540
- children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconLog, { size: 13 })
72334
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconLog, { size: 13 })
72541
72335
  }
72542
72336
  ),
72543
- /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72337
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72544
72338
  "button",
72545
72339
  {
72546
72340
  "data-testid": "timeline-toggle",
@@ -72552,7 +72346,7 @@ var ScrubberHeader = ({
72552
72346
  ...headerButtonStyle,
72553
72347
  color: collapsed ? GUI_THEME.secondary : GUI_THEME.accent
72554
72348
  },
72555
- children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconTimeline, { size: 14 })
72349
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconTimeline, { size: 14 })
72556
72350
  }
72557
72351
  )
72558
72352
  ]
@@ -72562,7 +72356,7 @@ var ScrubberPlayButton = ({
72562
72356
  canPlay,
72563
72357
  playTitle,
72564
72358
  onPlay
72565
- }) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72359
+ }) => /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
72566
72360
  "button",
72567
72361
  {
72568
72362
  "data-testid": "theatre-play",
@@ -72576,19 +72370,19 @@ var ScrubberPlayButton = ({
72576
72370
  cursor: canPlay ? "pointer" : "default",
72577
72371
  opacity: canPlay ? 1 : 0.4
72578
72372
  },
72579
- children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(IconPlay, { size: 13 })
72373
+ children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(IconPlay, { size: 13 })
72580
72374
  }
72581
72375
  );
72582
72376
 
72583
72377
  // source/gui/client/components/ScrubberTrack.tsx
72584
- var import_react46 = __toESM(require_react(), 1);
72585
- var import_jsx_runtime85 = __toESM(require_jsx_runtime(), 1);
72378
+ var import_react45 = __toESM(require_react(), 1);
72379
+ var import_jsx_runtime84 = __toESM(require_jsx_runtime(), 1);
72586
72380
  var SegmentHighlight = ({
72587
72381
  segment: segment2,
72588
72382
  fractionForTime
72589
72383
  }) => {
72590
72384
  const left = fractionForTime(segment2.start);
72591
- return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72385
+ return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72592
72386
  "div",
72593
72387
  {
72594
72388
  style: {
@@ -72619,7 +72413,7 @@ var SegmentHighlight = ({
72619
72413
  };
72620
72414
  var RangeSelection = ({ from, to }) => {
72621
72415
  const left = Math.min(from, to);
72622
- return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72416
+ return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72623
72417
  "div",
72624
72418
  {
72625
72419
  "data-testid": "scrubber-range-selection",
@@ -72644,7 +72438,7 @@ var RangeSelection = ({ from, to }) => {
72644
72438
  var TrackBaseline = ({
72645
72439
  color: color2,
72646
72440
  anchor
72647
- }) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72441
+ }) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72648
72442
  "div",
72649
72443
  {
72650
72444
  style: {
@@ -72662,11 +72456,11 @@ var TrackBaseline = ({
72662
72456
  }
72663
72457
  }
72664
72458
  );
72665
- var HourAxisLabels = () => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(import_jsx_runtime85.Fragment, { children: [
72459
+ var HourAxisLabels = () => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_jsx_runtime84.Fragment, { children: [
72666
72460
  ["00:00", { top: EVENTS_MODE_VERTICAL_PADDING }],
72667
72461
  ["12:00", { top: "50%", transform: "translateY(-50%)" }],
72668
72462
  ["24:00", { bottom: EVENTS_MODE_VERTICAL_PADDING }]
72669
- ].map(([label, position3]) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72463
+ ].map(([label, position3]) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72670
72464
  "span",
72671
72465
  {
72672
72466
  style: {
@@ -72684,7 +72478,7 @@ var HourAxisLabels = () => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(import_
72684
72478
  var SeriesLayer = ({
72685
72479
  animate,
72686
72480
  children
72687
- }) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72481
+ }) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72688
72482
  "div",
72689
72483
  {
72690
72484
  style: {
@@ -72703,7 +72497,7 @@ var SeriesLayer = ({
72703
72497
  var BucketHighlight = ({
72704
72498
  index: index2,
72705
72499
  bucketCount
72706
- }) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72500
+ }) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72707
72501
  "div",
72708
72502
  {
72709
72503
  style: {
@@ -72731,12 +72525,12 @@ var VolumeBarsImpl = ({
72731
72525
  const widthPercent = 100 / bucketCount;
72732
72526
  const barWidth = barWidthCss(bucketCount);
72733
72527
  const growsUp = direction === "up";
72734
- const [fresh, setFresh] = (0, import_react46.useState)(true);
72735
- (0, import_react46.useEffect)(() => {
72528
+ const [fresh, setFresh] = (0, import_react45.useState)(true);
72529
+ (0, import_react45.useEffect)(() => {
72736
72530
  const timeout = setTimeout(() => setFresh(false), BAR_ENTRANCE_TOTAL_MS);
72737
72531
  return () => clearTimeout(timeout);
72738
72532
  }, []);
72739
- return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(import_jsx_runtime85.Fragment, { children: bars.map(({ index: index2, intensity }) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72533
+ return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(import_jsx_runtime84.Fragment, { children: bars.map(({ index: index2, intensity }) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72740
72534
  "div",
72741
72535
  {
72742
72536
  style: {
@@ -72756,19 +72550,19 @@ var VolumeBarsImpl = ({
72756
72550
  index2
72757
72551
  )) });
72758
72552
  };
72759
- var VolumeBars = (0, import_react46.memo)(VolumeBarsImpl);
72553
+ var VolumeBars = (0, import_react45.memo)(VolumeBarsImpl);
72760
72554
  var ScrubberNeedle = ({
72761
72555
  fraction,
72762
72556
  onGrab
72763
72557
  }) => {
72764
- const [hovered, setHovered] = (0, import_react46.useState)(false);
72558
+ const [hovered, setHovered] = (0, import_react45.useState)(false);
72765
72559
  const grip = {
72766
72560
  onMouseEnter: () => setHovered(true),
72767
72561
  onMouseLeave: () => setHovered(false),
72768
72562
  onPointerDown: onGrab
72769
72563
  };
72770
- return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
72771
- /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72564
+ return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
72565
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72772
72566
  "div",
72773
72567
  {
72774
72568
  ...grip,
@@ -72786,7 +72580,7 @@ var ScrubberNeedle = ({
72786
72580
  }
72787
72581
  }
72788
72582
  ),
72789
- /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72583
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72790
72584
  "div",
72791
72585
  {
72792
72586
  style: {
@@ -72804,7 +72598,7 @@ var ScrubberNeedle = ({
72804
72598
  }
72805
72599
  }
72806
72600
  ),
72807
- /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72601
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72808
72602
  "div",
72809
72603
  {
72810
72604
  ...grip,
@@ -72834,7 +72628,7 @@ var ScrubberHoverHint = ({
72834
72628
  fraction,
72835
72629
  trackWidthPx,
72836
72630
  empty: empty3 = false
72837
- }) => /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
72631
+ }) => /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
72838
72632
  "div",
72839
72633
  {
72840
72634
  style: {
@@ -72866,8 +72660,8 @@ var ScrubberHoverHint = ({
72866
72660
  zIndex: 5
72867
72661
  },
72868
72662
  children: [
72869
- segmentLabel && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { style: { fontSize: 10, color: GUI_THEME.dim }, children: segmentLabel }),
72870
- /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72663
+ segmentLabel && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { style: { fontSize: 10, color: GUI_THEME.dim }, children: segmentLabel }),
72664
+ /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72871
72665
  "div",
72872
72666
  {
72873
72667
  style: {
@@ -72880,7 +72674,7 @@ var ScrubberHoverHint = ({
72880
72674
  children: label
72881
72675
  }
72882
72676
  ),
72883
- rows.map((row, index2) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72677
+ rows.map((row, index2) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
72884
72678
  "div",
72885
72679
  {
72886
72680
  style: {
@@ -72898,7 +72692,7 @@ var ScrubberHoverHint = ({
72898
72692
  );
72899
72693
 
72900
72694
  // source/gui/client/components/ScrubberLayout.tsx
72901
- var import_jsx_runtime86 = __toESM(require_jsx_runtime(), 1);
72695
+ var import_jsx_runtime85 = __toESM(require_jsx_runtime(), 1);
72902
72696
  var DAY_MS2 = 24 * 60 * 60 * 1e3;
72903
72697
  var ScrubberLayout = ({
72904
72698
  collapsed,
@@ -72913,7 +72707,7 @@ var ScrubberLayout = ({
72913
72707
  chart
72914
72708
  }) => {
72915
72709
  const { axis, layoutMode, animate, windowKey, on } = chart;
72916
- return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
72710
+ return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
72917
72711
  Panel,
72918
72712
  {
72919
72713
  as: "div",
@@ -72931,8 +72725,8 @@ var ScrubberLayout = ({
72931
72725
  pointerEvents: standDown ? "none" : void 0
72932
72726
  },
72933
72727
  children: [
72934
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("style", { children: SCRUBBER_KEYFRAMES }),
72935
- /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
72728
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("style", { children: SCRUBBER_KEYFRAMES }),
72729
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
72936
72730
  "div",
72937
72731
  {
72938
72732
  style: {
@@ -72941,7 +72735,7 @@ var ScrubberLayout = ({
72941
72735
  gap: collapsed ? 0 : TRACK_HIT_PADDING
72942
72736
  },
72943
72737
  children: [
72944
- /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
72738
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
72945
72739
  "div",
72946
72740
  {
72947
72741
  style: {
@@ -72955,7 +72749,7 @@ var ScrubberLayout = ({
72955
72749
  transition: "opacity 240ms ease"
72956
72750
  },
72957
72751
  children: [
72958
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72752
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72959
72753
  ScrubberHeader,
72960
72754
  {
72961
72755
  collapsed,
@@ -72971,8 +72765,8 @@ var ScrubberLayout = ({
72971
72765
  // scrubber shut, and collapsing it is remembered, so the board
72972
72766
  // must not be left hiding tickets behind a control nobody can
72973
72767
  // see.
72974
- /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
72975
- controls.windowOnly && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72768
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
72769
+ controls.windowOnly && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72976
72770
  Checkbox,
72977
72771
  {
72978
72772
  label: SCOPE_ONLY_LABEL,
@@ -72981,7 +72775,7 @@ var ScrubberLayout = ({
72981
72775
  onChange: controls.onChangeWindowOnly
72982
72776
  }
72983
72777
  ),
72984
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72778
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72985
72779
  ScrubberPlayButton,
72986
72780
  {
72987
72781
  canPlay,
@@ -72990,7 +72784,7 @@ var ScrubberLayout = ({
72990
72784
  }
72991
72785
  )
72992
72786
  ] })
72993
- ) : /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72787
+ ) : /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
72994
72788
  ScrubberControls,
72995
72789
  {
72996
72790
  ...controls,
@@ -73006,7 +72800,7 @@ var ScrubberLayout = ({
73006
72800
  // spanning them and the gap between. Pointer handlers belong here
73007
72801
  // rather than on either chart, so a drag or hover anywhere across
73008
72802
  // the pair — the gap included — counts as one timeline.
73009
- /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
72803
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
73010
72804
  "div",
73011
72805
  {
73012
72806
  "data-testid": "scrubber-track",
@@ -73030,7 +72824,7 @@ var ScrubberLayout = ({
73030
72824
  WebkitUserSelect: "none"
73031
72825
  },
73032
72826
  children: [
73033
- chart.scoped && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72827
+ chart.scoped && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73034
72828
  "div",
73035
72829
  {
73036
72830
  "aria-hidden": true,
@@ -73047,7 +72841,7 @@ var ScrubberLayout = ({
73047
72841
  }
73048
72842
  }
73049
72843
  ),
73050
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72844
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73051
72845
  "div",
73052
72846
  {
73053
72847
  "aria-hidden": true,
@@ -73060,14 +72854,14 @@ var ScrubberLayout = ({
73060
72854
  }
73061
72855
  }
73062
72856
  ),
73063
- chart.hoveredSegment && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72857
+ chart.hoveredSegment && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73064
72858
  SegmentHighlight,
73065
72859
  {
73066
72860
  segment: chart.hoveredSegment,
73067
72861
  fractionForTime: axis.fractionForTime
73068
72862
  }
73069
72863
  ),
73070
- /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
72864
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
73071
72865
  "div",
73072
72866
  {
73073
72867
  ref: chart.trackRef,
@@ -73082,23 +72876,23 @@ var ScrubberLayout = ({
73082
72876
  alignItems: "center"
73083
72877
  },
73084
72878
  children: [
73085
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72879
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73086
72880
  TrackBaseline,
73087
72881
  {
73088
72882
  color: chart.issueSeriesColor,
73089
72883
  anchor: layoutMode === "even" ? "bottom" : "centre"
73090
72884
  }
73091
72885
  ),
73092
- layoutMode === "real" && axis.span >= DAY_MS2 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(HourAxisLabels, {}),
73093
- chart.showIssues && layoutMode === "even" && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(import_jsx_runtime86.Fragment, { children: [
73094
- chart.hoveredBucketIndex !== null && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72886
+ layoutMode === "real" && axis.span >= DAY_MS2 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(HourAxisLabels, {}),
72887
+ chart.showIssues && layoutMode === "even" && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
72888
+ chart.hoveredBucketIndex !== null && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73095
72889
  BucketHighlight,
73096
72890
  {
73097
72891
  index: chart.hoveredBucketIndex,
73098
72892
  bucketCount: axis.bucketCount
73099
72893
  }
73100
72894
  ),
73101
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(SeriesLayer, { animate, children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72895
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(SeriesLayer, { animate, children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73102
72896
  VolumeBars,
73103
72897
  {
73104
72898
  bars: chart.issueBars,
@@ -73111,7 +72905,7 @@ var ScrubberLayout = ({
73111
72905
  }
73112
72906
  ) }, `issues-${windowKey}`)
73113
72907
  ] }),
73114
- layoutMode === "real" && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72908
+ layoutMode === "real" && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73115
72909
  ScatterCanvas,
73116
72910
  {
73117
72911
  layers: chart.scatterLayers,
@@ -73125,7 +72919,7 @@ var ScrubberLayout = ({
73125
72919
  ]
73126
72920
  }
73127
72921
  ),
73128
- chart.showCommits && layoutMode === "even" && chart.commits.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
72922
+ chart.showCommits && layoutMode === "even" && chart.commits.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(
73129
72923
  "div",
73130
72924
  {
73131
72925
  onMouseEnter: on.onCommitTrackMouseEnter,
@@ -73138,15 +72932,15 @@ var ScrubberLayout = ({
73138
72932
  animation: animate ? FADE_IN_ANIMATION : void 0
73139
72933
  },
73140
72934
  children: [
73141
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(TrackBaseline, { color: GUI_THEME.green, anchor: "top" }),
73142
- chart.hoveredCommitBucketIndex !== null && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72935
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(TrackBaseline, { color: GUI_THEME.green, anchor: "top" }),
72936
+ chart.hoveredCommitBucketIndex !== null && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73143
72937
  BucketHighlight,
73144
72938
  {
73145
72939
  index: chart.hoveredCommitBucketIndex,
73146
72940
  bucketCount: axis.bucketCount
73147
72941
  }
73148
72942
  ),
73149
- /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72943
+ /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73150
72944
  VolumeBars,
73151
72945
  {
73152
72946
  bars: chart.commitBars,
@@ -73162,15 +72956,15 @@ var ScrubberLayout = ({
73162
72956
  },
73163
72957
  `commits-${windowKey}`
73164
72958
  ),
73165
- chart.thumbFraction !== null && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72959
+ chart.thumbFraction !== null && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73166
72960
  ScrubberNeedle,
73167
72961
  {
73168
72962
  fraction: chart.thumbFraction,
73169
72963
  onGrab: on.onGrabNeedle
73170
72964
  }
73171
72965
  ),
73172
- chart.rangeSelection && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(RangeSelection, { ...chart.rangeSelection }),
73173
- chart.boardHint && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72966
+ chart.rangeSelection && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(RangeSelection, { ...chart.rangeSelection }),
72967
+ chart.boardHint && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73174
72968
  ScrubberHoverHint,
73175
72969
  {
73176
72970
  ...chart.boardHint,
@@ -73179,7 +72973,7 @@ var ScrubberLayout = ({
73179
72973
  trackWidthPx: chart.trackWidthPx
73180
72974
  }
73181
72975
  ),
73182
- chart.commitHint && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
72976
+ chart.commitHint && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
73183
72977
  ScrubberHoverHint,
73184
72978
  {
73185
72979
  ...chart.commitHint,
@@ -73200,7 +72994,7 @@ var ScrubberLayout = ({
73200
72994
  };
73201
72995
 
73202
72996
  // source/gui/client/components/TimeScrubber.tsx
73203
- var import_jsx_runtime87 = __toESM(require_jsx_runtime(), 1);
72997
+ var import_jsx_runtime86 = __toESM(require_jsx_runtime(), 1);
73204
72998
  var SCRUB_THROTTLE_MS = 120;
73205
72999
  var EMPTY_IDENTITIES2 = [];
73206
73000
  var EMPTY_HIDDEN2 = /* @__PURE__ */ new Set();
@@ -73248,15 +73042,15 @@ var TimeScrubber = ({
73248
73042
  const boardView = plottedView(only);
73249
73043
  const animate = !usePrefersReducedMotion();
73250
73044
  const narrow = useNarrowBar();
73251
- const trackRef = (0, import_react47.useRef)(null);
73252
- const lastDispatchRef = (0, import_react47.useRef)(0);
73253
- const lastTargetRef = (0, import_react47.useRef)(null);
73254
- const [dragFraction, setDragFraction] = (0, import_react47.useState)(null);
73255
- const [rangeDrag, setRangeDrag] = (0, import_react47.useState)(null);
73256
- const dragFractionRef = (0, import_react47.useRef)(null);
73257
- const rangeDragRef = (0, import_react47.useRef)(null);
73258
- const grabbedNeedleRef = (0, import_react47.useRef)(false);
73259
- const pressedCommitRef = (0, import_react47.useRef)(null);
73045
+ const trackRef = (0, import_react46.useRef)(null);
73046
+ const lastDispatchRef = (0, import_react46.useRef)(0);
73047
+ const lastTargetRef = (0, import_react46.useRef)(null);
73048
+ const [dragFraction, setDragFraction] = (0, import_react46.useState)(null);
73049
+ const [rangeDrag, setRangeDrag] = (0, import_react46.useState)(null);
73050
+ const dragFractionRef = (0, import_react46.useRef)(null);
73051
+ const rangeDragRef = (0, import_react46.useRef)(null);
73052
+ const grabbedNeedleRef = (0, import_react46.useRef)(false);
73053
+ const pressedCommitRef = (0, import_react46.useRef)(null);
73260
73054
  const [collapsed, setCollapsed] = usePersistedFlag(
73261
73055
  COLLAPSED_STORAGE_KEY,
73262
73056
  false
@@ -73276,19 +73070,19 @@ var TimeScrubber = ({
73276
73070
  const exitMs = layoutMode === "real" && animate ? DOT_EXIT_TOTAL_MS : 0;
73277
73071
  const issueScatter = useExitTransition(showIssues, exitMs);
73278
73072
  const commitScatter = useExitTransition(showCommits, exitMs);
73279
- const [hoveredEvent, setHoveredEvent] = (0, import_react47.useState)(null);
73280
- const [pointerFraction, setPointerFraction] = (0, import_react47.useState)(null);
73281
- const [hoveredCommit, setHoveredCommit] = (0, import_react47.useState)(null);
73282
- const [hoveredBucketIndex, setHoveredBucketIndex] = (0, import_react47.useState)(
73073
+ const [hoveredEvent, setHoveredEvent] = (0, import_react46.useState)(null);
73074
+ const [pointerFraction, setPointerFraction] = (0, import_react46.useState)(null);
73075
+ const [hoveredCommit, setHoveredCommit] = (0, import_react46.useState)(null);
73076
+ const [hoveredBucketIndex, setHoveredBucketIndex] = (0, import_react46.useState)(
73283
73077
  null
73284
73078
  );
73285
- const [hoveredCommitBucketIndex, setHoveredCommitBucketIndex] = (0, import_react47.useState)(null);
73079
+ const [hoveredCommitBucketIndex, setHoveredCommitBucketIndex] = (0, import_react46.useState)(null);
73286
73080
  const ticketFocus = ticketOnly && selectedIssue !== null;
73287
73081
  const ticketRange = ticketFocus ? { start: selectedIssue.createdAt, end: Date.now() } : null;
73288
73082
  const issueOnly = ticketFocus ? selectedIssue.id : null;
73289
73083
  const ticketWindowKey = ticketFocus ? `${selectedIssue.id}:${selectedIssue.createdAt}` : null;
73290
73084
  const periodRange = ticketRange ?? zoom ?? getPeriodRange(scope, offset);
73291
- (0, import_react47.useEffect)(() => {
73085
+ (0, import_react46.useEffect)(() => {
73292
73086
  if (!connected) return;
73293
73087
  pendingRequestId.current = onRequestHistory(
73294
73088
  periodRange?.start,
@@ -73349,20 +73143,20 @@ var TimeScrubber = ({
73349
73143
  armEntrance();
73350
73144
  setAllBoards(next);
73351
73145
  };
73352
- const filterKey = (0, import_react47.useMemo)(() => {
73146
+ const filterKey = (0, import_react46.useMemo)(() => {
73353
73147
  const plotted = narrowedIds(narrowingFor(only, identityAxisFor(boardView)));
73354
73148
  return JSON.stringify([
73355
73149
  boardView,
73356
73150
  plotted === null ? null : [...plotted].sort()
73357
73151
  ]);
73358
73152
  }, [boardView, only]);
73359
- const entrance = (0, import_react47.useRef)(0);
73360
- const armed = (0, import_react47.useRef)(true);
73153
+ const entrance = (0, import_react46.useRef)(0);
73154
+ const armed = (0, import_react46.useRef)(true);
73361
73155
  const armEntrance = () => {
73362
73156
  armed.current = true;
73363
73157
  };
73364
- const shownRef = (0, import_react47.useRef)({ timeline, commits });
73365
- const pendingRequestId = (0, import_react47.useRef)(null);
73158
+ const shownRef = (0, import_react46.useRef)({ timeline, commits });
73159
+ const pendingRequestId = (0, import_react46.useRef)(null);
73366
73160
  const gestureInFlight = dragFractionRef.current !== null || rangeDragRef.current !== null;
73367
73161
  if (!gestureInFlight && pendingRequestId.current !== null && historyId === pendingRequestId.current) {
73368
73162
  pendingRequestId.current = null;
@@ -73373,9 +73167,9 @@ var TimeScrubber = ({
73373
73167
  }
73374
73168
  }
73375
73169
  const shown = shownRef.current;
73376
- const axis = (0, import_react47.useMemo)(() => buildAxis(shown.timeline, shown.commits), [shown]);
73170
+ const axis = (0, import_react46.useMemo)(() => buildAxis(shown.timeline, shown.commits), [shown]);
73377
73171
  const categoriesFiltered = (timeline?.events.length ?? 0) > 0;
73378
- const identitiesByAxis = (0, import_react47.useMemo)(() => {
73172
+ const identitiesByAxis = (0, import_react46.useMemo)(() => {
73379
73173
  const listed = listIdentitiesByAxis(shown.timeline);
73380
73174
  const lists = {};
73381
73175
  for (const axis2 of FILTER_AXES) {
@@ -73387,12 +73181,12 @@ var TimeScrubber = ({
73387
73181
  }
73388
73182
  return lists;
73389
73183
  }, [shown, only, knownIdentities]);
73390
- const axisStates = (0, import_react47.useMemo)(() => {
73184
+ const axisStates = (0, import_react46.useMemo)(() => {
73391
73185
  const states = {};
73392
73186
  for (const axis2 of FILTER_AXES) states[axis2] = axisState(only, axis2);
73393
73187
  return states;
73394
73188
  }, [only]);
73395
- const hiddenIdsByAxis = (0, import_react47.useMemo)(() => {
73189
+ const hiddenIdsByAxis = (0, import_react46.useMemo)(() => {
73396
73190
  const hidden = {};
73397
73191
  for (const axis2 of FILTER_AXES) {
73398
73192
  hidden[axis2] = hiddenIdsFor(
@@ -73405,11 +73199,11 @@ var TimeScrubber = ({
73405
73199
  const viewAxis = identityAxisFor(boardView);
73406
73200
  const identities = viewAxis === null ? EMPTY_IDENTITIES2 : identitiesByAxis[viewAxis];
73407
73201
  const hiddenIdentityIds = viewAxis === null ? EMPTY_HIDDEN2 : hiddenIdsByAxis[viewAxis];
73408
- const soleIdentity = (0, import_react47.useMemo)(
73202
+ const soleIdentity = (0, import_react46.useMemo)(
73409
73203
  () => soleVisibleIdentity(identities, hiddenIdentityIds),
73410
73204
  [identities, hiddenIdentityIds]
73411
73205
  );
73412
- const issueCounts = (0, import_react47.useMemo)(
73206
+ const issueCounts = (0, import_react46.useMemo)(
73413
73207
  () => bucketIssueCounts(
73414
73208
  axis,
73415
73209
  shown.timeline,
@@ -73419,16 +73213,16 @@ var TimeScrubber = ({
73419
73213
  ),
73420
73214
  [axis, shown, boardView, hiddenIdentityIds, issueOnly]
73421
73215
  );
73422
- const commitStats = (0, import_react47.useMemo)(
73216
+ const commitStats = (0, import_react46.useMemo)(
73423
73217
  () => bucketCommitStats(axis, shown.commits),
73424
73218
  [axis, shown.commits]
73425
73219
  );
73426
- const liveEventDots = (0, import_react47.useMemo)(
73220
+ const liveEventDots = (0, import_react46.useMemo)(
73427
73221
  () => buildEventDots(shown.timeline, boardView, hiddenIdentityIds, issueOnly),
73428
73222
  [shown, boardView, hiddenIdentityIds, issueOnly]
73429
73223
  );
73430
73224
  const dragging = dragFraction !== null || rangeDrag !== null;
73431
- const commitPoints = (0, import_react47.useMemo)(
73225
+ const commitPoints = (0, import_react46.useMemo)(
73432
73226
  () => shown.commits.map((commit) => ({
73433
73227
  key: commit.sha,
73434
73228
  id: null,
@@ -73444,7 +73238,7 @@ var TimeScrubber = ({
73444
73238
  })),
73445
73239
  [shown.commits, axis]
73446
73240
  );
73447
- const issuePoints = (0, import_react47.useMemo)(
73241
+ const issuePoints = (0, import_react46.useMemo)(
73448
73242
  () => liveEventDots.map((dot) => ({
73449
73243
  key: dot.key,
73450
73244
  id: dot.id,
@@ -73459,13 +73253,13 @@ var TimeScrubber = ({
73459
73253
  })),
73460
73254
  [liveEventDots, axis]
73461
73255
  );
73462
- const issueBars = (0, import_react47.useMemo)(() => {
73256
+ const issueBars = (0, import_react46.useMemo)(() => {
73463
73257
  const max = maxOf(issueCounts, 1);
73464
73258
  return issueCounts.flatMap(
73465
73259
  (count, index2) => count > 0 ? [{ index: index2, intensity: count / max }] : []
73466
73260
  );
73467
73261
  }, [issueCounts]);
73468
- const commitBars = (0, import_react47.useMemo)(() => {
73262
+ const commitBars = (0, import_react46.useMemo)(() => {
73469
73263
  const max = maxOf(
73470
73264
  Array.from(commitStats.values(), (stats) => stats.count),
73471
73265
  1
@@ -73475,19 +73269,19 @@ var TimeScrubber = ({
73475
73269
  intensity: stats.count / max
73476
73270
  }));
73477
73271
  }, [commitStats]);
73478
- const issueBarRange = (0, import_react47.useMemo)(() => populatedRange(issueBars), [issueBars]);
73479
- const commitBarRange = (0, import_react47.useMemo)(
73272
+ const issueBarRange = (0, import_react46.useMemo)(() => populatedRange(issueBars), [issueBars]);
73273
+ const commitBarRange = (0, import_react46.useMemo)(
73480
73274
  () => populatedRange(commitBars),
73481
73275
  [commitBars]
73482
73276
  );
73483
- const armedBoardId = (0, import_react47.useRef)(boardId);
73484
- (0, import_react47.useEffect)(() => {
73277
+ const armedBoardId = (0, import_react46.useRef)(boardId);
73278
+ (0, import_react46.useEffect)(() => {
73485
73279
  if (boardId === null || boardId === armedBoardId.current) return;
73486
73280
  armedBoardId.current = boardId;
73487
73281
  armEntrance();
73488
73282
  }, [boardId]);
73489
73283
  const windowKey = `${layoutMode}-${entrance.current}-${filterKey}`;
73490
- const scatterLayers = (0, import_react47.useMemo)(
73284
+ const scatterLayers = (0, import_react46.useMemo)(
73491
73285
  () => [
73492
73286
  ...commitScatter.mounted ? [
73493
73287
  {
@@ -73526,7 +73320,7 @@ var TimeScrubber = ({
73526
73320
  lastTargetRef.current = target;
73527
73321
  onScrub(target);
73528
73322
  };
73529
- (0, import_react47.useEffect)(() => {
73323
+ (0, import_react46.useEffect)(() => {
73530
73324
  if (timeTravel.mode !== "scrub") lastTargetRef.current = null;
73531
73325
  }, [timeTravel.mode]);
73532
73326
  const endDrag = () => {
@@ -73568,7 +73362,7 @@ var TimeScrubber = ({
73568
73362
  );
73569
73363
  const bucketTimeAt = (index2) => index2 !== null && index2 < axis.bucketCount ? axis.bucketTimeAt(index2) : void 0;
73570
73364
  const centreFraction = (index2) => (index2 + 0.5) / axis.bucketCount;
73571
- const onScatterPointEnter = (0, import_react47.useCallback)(
73365
+ const onScatterPointEnter = (0, import_react46.useCallback)(
73572
73366
  (point4) => {
73573
73367
  if (point4.commitSha) {
73574
73368
  const commit = shown.commits.find((c) => c.sha === point4.commitSha);
@@ -73588,7 +73382,7 @@ var TimeScrubber = ({
73588
73382
  },
73589
73383
  [shown.commits]
73590
73384
  );
73591
- const onScatterPointLeave = (0, import_react47.useCallback)(() => {
73385
+ const onScatterPointLeave = (0, import_react46.useCallback)(() => {
73592
73386
  setHoveredEvent(null);
73593
73387
  setHoveredCommit(null);
73594
73388
  }, []);
@@ -73648,7 +73442,7 @@ var TimeScrubber = ({
73648
73442
  // not too little. One event fails `canPlayTimeline` too, and has both.
73649
73443
  timeline && timeline.events.length === 0 && timeline.buckets.length > 0 ? "Too many events in this window to play it \u2014 narrow the window" : "Not enough history in this window to play"
73650
73444
  );
73651
- return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
73445
+ return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
73652
73446
  ScrubberLayout,
73653
73447
  {
73654
73448
  collapsed,
@@ -73794,8 +73588,8 @@ var TimeScrubber = ({
73794
73588
  };
73795
73589
 
73796
73590
  // source/gui/client/components/TheatrePlayer.tsx
73797
- var import_react48 = __toESM(require_react(), 1);
73798
- var import_jsx_runtime88 = __toESM(require_jsx_runtime(), 1);
73591
+ var import_react47 = __toESM(require_react(), 1);
73592
+ var import_jsx_runtime87 = __toESM(require_jsx_runtime(), 1);
73799
73593
  var SEEK_STEP = 0.02;
73800
73594
  var BAR_HEIGHT2 = 2;
73801
73595
  var KNOB_SIZE = 9;
@@ -73821,7 +73615,7 @@ var TheatrePlayer = ({
73821
73615
  onExit
73822
73616
  }) => {
73823
73617
  const animate = !usePrefersReducedMotion();
73824
- const trackRef = (0, import_react48.useRef)(null);
73618
+ const trackRef = (0, import_react47.useRef)(null);
73825
73619
  const {
73826
73620
  progress,
73827
73621
  playing,
@@ -73837,11 +73631,11 @@ var TheatrePlayer = ({
73837
73631
  beginSeek,
73838
73632
  endSeek
73839
73633
  } = playback;
73840
- const onExitRef = (0, import_react48.useRef)(onExit);
73634
+ const onExitRef = (0, import_react47.useRef)(onExit);
73841
73635
  onExitRef.current = onExit;
73842
- const toggleRef = (0, import_react48.useRef)(toggle);
73636
+ const toggleRef = (0, import_react47.useRef)(toggle);
73843
73637
  toggleRef.current = toggle;
73844
- (0, import_react48.useEffect)(() => {
73638
+ (0, import_react47.useEffect)(() => {
73845
73639
  const onKeyDown = (event) => {
73846
73640
  const target = event.target;
73847
73641
  const tag = target?.tagName ?? "";
@@ -73866,9 +73660,9 @@ var TheatrePlayer = ({
73866
73660
  const rect = event.currentTarget.getBoundingClientRect();
73867
73661
  return clamp((event.clientX - rect.left) / Math.max(1, rect.width), 0, 1);
73868
73662
  };
73869
- return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(import_jsx_runtime88.Fragment, { children: [
73870
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("style", { children: THEATRE_KEYFRAMES }),
73871
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
73663
+ return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(import_jsx_runtime87.Fragment, { children: [
73664
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("style", { children: THEATRE_KEYFRAMES }),
73665
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
73872
73666
  "div",
73873
73667
  {
73874
73668
  "data-testid": "theatre-vignette",
@@ -73882,7 +73676,7 @@ var TheatrePlayer = ({
73882
73676
  }
73883
73677
  }
73884
73678
  ),
73885
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(
73679
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(
73886
73680
  "div",
73887
73681
  {
73888
73682
  "data-testid": "theatre-player",
@@ -73905,8 +73699,8 @@ var TheatrePlayer = ({
73905
73699
  animation: animate ? "epiqTheatreRise 260ms ease-out" : void 0
73906
73700
  },
73907
73701
  children: [
73908
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 14 }, children: [
73909
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
73702
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 14 }, children: [
73703
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
73910
73704
  "button",
73911
73705
  {
73912
73706
  type: "button",
@@ -73915,10 +73709,10 @@ var TheatrePlayer = ({
73915
73709
  title: done ? "Play again" : playing ? "Pause" : "Play",
73916
73710
  "aria-label": done ? "Play again" : playing ? "Pause" : "Play",
73917
73711
  style: transportButtonStyle(true),
73918
- children: done ? /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconReplay, { size: 13 }) : playing ? /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconPause, { size: 13 }) : /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconPlay, { size: 13 })
73712
+ children: done ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(IconReplay, { size: 13 }) : playing ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(IconPause, { size: 13 }) : /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(IconPlay, { size: 13 })
73919
73713
  }
73920
73714
  ),
73921
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(
73715
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(
73922
73716
  "div",
73923
73717
  {
73924
73718
  "data-testid": "theatre-progress",
@@ -73961,7 +73755,7 @@ var TheatrePlayer = ({
73961
73755
  touchAction: "none"
73962
73756
  },
73963
73757
  children: [
73964
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
73758
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
73965
73759
  "div",
73966
73760
  {
73967
73761
  style: {
@@ -73974,7 +73768,7 @@ var TheatrePlayer = ({
73974
73768
  }
73975
73769
  }
73976
73770
  ),
73977
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
73771
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
73978
73772
  "div",
73979
73773
  {
73980
73774
  style: {
@@ -73987,7 +73781,7 @@ var TheatrePlayer = ({
73987
73781
  }
73988
73782
  }
73989
73783
  ),
73990
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
73784
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
73991
73785
  "div",
73992
73786
  {
73993
73787
  style: {
@@ -74005,7 +73799,7 @@ var TheatrePlayer = ({
74005
73799
  ]
74006
73800
  }
74007
73801
  ),
74008
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(
73802
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(
74009
73803
  "button",
74010
73804
  {
74011
73805
  type: "button",
@@ -74025,7 +73819,7 @@ var TheatrePlayer = ({
74025
73819
  ]
74026
73820
  }
74027
73821
  ),
74028
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
73822
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
74029
73823
  "button",
74030
73824
  {
74031
73825
  type: "button",
@@ -74034,11 +73828,11 @@ var TheatrePlayer = ({
74034
73828
  title: "Leave the player and follow the board again",
74035
73829
  "aria-label": "Close the history player",
74036
73830
  style: transportButtonStyle(false),
74037
- children: /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(IconClose, { size: 12 })
73831
+ children: /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(IconClose, { size: 12 })
74038
73832
  }
74039
73833
  )
74040
73834
  ] }),
74041
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(
73835
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(
74042
73836
  "div",
74043
73837
  {
74044
73838
  style: {
@@ -74051,7 +73845,7 @@ var TheatrePlayer = ({
74051
73845
  minHeight: 16
74052
73846
  },
74053
73847
  children: [
74054
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
73848
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
74055
73849
  "span",
74056
73850
  {
74057
73851
  "data-testid": "theatre-time",
@@ -74063,7 +73857,7 @@ var TheatrePlayer = ({
74063
73857
  children: formatDateTime(new Date(currentTime))
74064
73858
  }
74065
73859
  ),
74066
- /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(
73860
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)(
74067
73861
  "span",
74068
73862
  {
74069
73863
  "data-testid": "theatre-count",
@@ -74080,7 +73874,7 @@ var TheatrePlayer = ({
74080
73874
  ]
74081
73875
  }
74082
73876
  ),
74083
- /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
73877
+ /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
74084
73878
  "span",
74085
73879
  {
74086
73880
  "data-testid": "theatre-caption",
@@ -74107,11 +73901,11 @@ var TheatrePlayer = ({
74107
73901
  };
74108
73902
 
74109
73903
  // source/gui/client/components/EventLog.tsx
74110
- var import_react49 = __toESM(require_react(), 1);
73904
+ var import_react48 = __toESM(require_react(), 1);
74111
73905
 
74112
73906
  // source/gui/client/components/IconArrowUpRight.tsx
74113
- var import_jsx_runtime89 = __toESM(require_jsx_runtime(), 1);
74114
- var IconArrowUpRight = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
73907
+ var import_jsx_runtime88 = __toESM(require_jsx_runtime(), 1);
73908
+ var IconArrowUpRight = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(
74115
73909
  "svg",
74116
73910
  {
74117
73911
  width: size,
@@ -74124,14 +73918,14 @@ var IconArrowUpRight = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime
74124
73918
  strokeLinejoin: "round",
74125
73919
  "aria-hidden": "true",
74126
73920
  children: [
74127
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("line", { x1: "7", y1: "17", x2: "17", y2: "7" }),
74128
- /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("polyline", { points: "7 7 17 7 17 17" })
73921
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("line", { x1: "7", y1: "17", x2: "17", y2: "7" }),
73922
+ /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("polyline", { points: "7 7 17 7 17 17" })
74129
73923
  ]
74130
73924
  }
74131
73925
  );
74132
73926
 
74133
73927
  // source/gui/client/components/EventLog.tsx
74134
- var import_jsx_runtime90 = __toESM(require_jsx_runtime(), 1);
73928
+ var import_jsx_runtime89 = __toESM(require_jsx_runtime(), 1);
74135
73929
  var LOG_WIDTH = 440;
74136
73930
  var PINNED_SLACK_PX = LOG_ROW_HEIGHT * 2;
74137
73931
  var dividerRuleStyle = {
@@ -74145,7 +73939,7 @@ var DayDivider = ({
74145
73939
  count,
74146
73940
  open,
74147
73941
  onToggle
74148
- }) => /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
73942
+ }) => /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
74149
73943
  "button",
74150
73944
  {
74151
73945
  type: "button",
@@ -74168,17 +73962,17 @@ var DayDivider = ({
74168
73962
  cursor: "pointer"
74169
73963
  },
74170
73964
  children: [
74171
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
73965
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
74172
73966
  "span",
74173
73967
  {
74174
73968
  "aria-hidden": true,
74175
73969
  style: { display: "inline-flex", alignItems: "center", flexShrink: 0 },
74176
- children: open ? /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(IconChevronDown, { size: 11 }) : /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(IconChevronRight, { size: 11 })
73970
+ children: open ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconChevronDown, { size: 11 }) : /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconChevronRight, { size: 11 })
74177
73971
  }
74178
73972
  ),
74179
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { style: { flexShrink: 0 }, children: label }),
74180
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { "aria-hidden": true, style: dividerRuleStyle }),
74181
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
73973
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { style: { flexShrink: 0 }, children: label }),
73974
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { "aria-hidden": true, style: dividerRuleStyle }),
73975
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
74182
73976
  "span",
74183
73977
  {
74184
73978
  style: {
@@ -74192,7 +73986,7 @@ var DayDivider = ({
74192
73986
  ]
74193
73987
  }
74194
73988
  );
74195
- var EventRow = ({ entry }) => /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
73989
+ var EventRow = ({ entry }) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
74196
73990
  "div",
74197
73991
  {
74198
73992
  "data-testid": "log-line",
@@ -74211,23 +74005,23 @@ var EventLogPanel = ({
74211
74005
  onOpen
74212
74006
  }) => {
74213
74007
  const animate = !usePrefersReducedMotion();
74214
- const scrollRef = (0, import_react49.useRef)(null);
74215
- const columnRef = (0, import_react49.useRef)(null);
74216
- const [foldOverrides, setFoldOverrides] = (0, import_react49.useState)(() => /* @__PURE__ */ new Map());
74217
- const days = (0, import_react49.useMemo)(() => groupByDay(entries), [entries]);
74008
+ const scrollRef = (0, import_react48.useRef)(null);
74009
+ const columnRef = (0, import_react48.useRef)(null);
74010
+ const [foldOverrides, setFoldOverrides] = (0, import_react48.useState)(() => /* @__PURE__ */ new Map());
74011
+ const days = (0, import_react48.useMemo)(() => groupByDay(entries), [entries]);
74218
74012
  const newestId = entries[entries.length - 1]?.id ?? null;
74219
- const [paneRows, setPaneRows] = (0, import_react49.useState)(null);
74220
- const openCount = (0, import_react49.useMemo)(
74013
+ const [paneRows, setPaneRows] = (0, import_react48.useState)(null);
74014
+ const openCount = (0, import_react48.useMemo)(
74221
74015
  () => paneRows === null ? Math.min(DEFAULT_OPEN_DAYS, days.length) : daysToOpen(days, paneRows),
74222
74016
  [days, paneRows]
74223
74017
  );
74224
- const pinnedRef = (0, import_react49.useRef)(true);
74018
+ const pinnedRef = (0, import_react48.useRef)(true);
74225
74019
  const onScroll = () => {
74226
74020
  const pane = scrollRef.current;
74227
74021
  if (!pane) return;
74228
74022
  pinnedRef.current = pane.scrollHeight - pane.scrollTop - pane.clientHeight <= PINNED_SLACK_PX;
74229
74023
  };
74230
- (0, import_react49.useLayoutEffect)(() => {
74024
+ (0, import_react48.useLayoutEffect)(() => {
74231
74025
  const pane = scrollRef.current;
74232
74026
  if (!pane) return;
74233
74027
  const measure = () => {
@@ -74239,7 +74033,7 @@ var EventLogPanel = ({
74239
74033
  observer.observe(pane);
74240
74034
  return () => observer.disconnect();
74241
74035
  }, [bottomClearance]);
74242
- const arrowRef = (0, import_react49.useRef)(null);
74036
+ const arrowRef = (0, import_react48.useRef)(null);
74243
74037
  const parkStrayArrow = () => {
74244
74038
  const arrow = arrowRef.current;
74245
74039
  const column = columnRef.current;
@@ -74248,21 +74042,21 @@ var EventLogPanel = ({
74248
74042
  arrow.style.top = "0px";
74249
74043
  arrow.style.opacity = "0";
74250
74044
  };
74251
- (0, import_react49.useLayoutEffect)(() => {
74045
+ (0, import_react48.useLayoutEffect)(() => {
74252
74046
  const pane = scrollRef.current;
74253
74047
  if (!pane || !pinnedRef.current) return;
74254
74048
  parkStrayArrow();
74255
74049
  pane.scrollTop = pane.scrollHeight;
74256
74050
  }, [newestId, days.length, foldOverrides, openCount]);
74257
- (0, import_react49.useLayoutEffect)(() => {
74051
+ (0, import_react48.useLayoutEffect)(() => {
74258
74052
  const pane = scrollRef.current;
74259
74053
  if (!pane) return;
74260
74054
  pinnedRef.current = true;
74261
74055
  parkStrayArrow();
74262
74056
  pane.scrollTop = pane.scrollHeight;
74263
74057
  }, [moment]);
74264
- const shownKeysRef = (0, import_react49.useRef)(/* @__PURE__ */ new Set());
74265
- (0, import_react49.useEffect)(() => {
74058
+ const shownKeysRef = (0, import_react48.useRef)(/* @__PURE__ */ new Set());
74059
+ (0, import_react48.useEffect)(() => {
74266
74060
  const column = columnRef.current;
74267
74061
  const shown = shownKeysRef.current;
74268
74062
  const onScreen = days.flatMap(
@@ -74282,7 +74076,7 @@ var EventLogPanel = ({
74282
74076
  if (row) arrow.style.top = `${row.offsetTop}px`;
74283
74077
  arrow.style.opacity = row ? "1" : "0";
74284
74078
  };
74285
- return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
74079
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
74286
74080
  "aside",
74287
74081
  {
74288
74082
  "data-testid": "event-log",
@@ -74297,8 +74091,8 @@ var EventLogPanel = ({
74297
74091
  background: GUI_THEME.panel
74298
74092
  },
74299
74093
  children: [
74300
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("style", { children: EVENT_LOG_STYLES }),
74301
- /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
74094
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("style", { children: EVENT_LOG_STYLES }),
74095
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
74302
74096
  "div",
74303
74097
  {
74304
74098
  ref: scrollRef,
@@ -74327,20 +74121,20 @@ var EventLogPanel = ({
74327
74121
  padding: `0 ${LOG_PANE_PADDING_X}px ${bottomClearance + LOG_ROW_HEIGHT * 2}px 30px`
74328
74122
  },
74329
74123
  children: [
74330
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
74124
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
74331
74125
  "span",
74332
74126
  {
74333
74127
  ref: arrowRef,
74334
74128
  className: LOG_ARROW_CLASS,
74335
74129
  "data-testid": "log-row-arrow",
74336
74130
  "aria-hidden": "true",
74337
- children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(IconArrowUpRight, { size: 11 })
74131
+ children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(IconArrowUpRight, { size: 11 })
74338
74132
  }
74339
74133
  ),
74340
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { ref: columnRef, style: { marginTop: "auto" }, children: days.map((day, index2) => {
74134
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { ref: columnRef, style: { marginTop: "auto" }, children: days.map((day, index2) => {
74341
74135
  const open = isDayOpen(days, index2, foldOverrides, openCount);
74342
- return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { children: [
74343
- /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
74136
+ return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { children: [
74137
+ /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
74344
74138
  DayDivider,
74345
74139
  {
74346
74140
  label: day.label,
@@ -74353,7 +74147,7 @@ var EventLogPanel = ({
74353
74147
  })
74354
74148
  }
74355
74149
  ),
74356
- open && day.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(EventRow, { entry }, entry.id))
74150
+ open && day.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(EventRow, { entry }, entry.id))
74357
74151
  ] }, day.key);
74358
74152
  }) })
74359
74153
  ]
@@ -74363,14 +74157,14 @@ var EventLogPanel = ({
74363
74157
  }
74364
74158
  );
74365
74159
  };
74366
- var EventLog = (0, import_react49.memo)(EventLogPanel);
74160
+ var EventLog = (0, import_react48.memo)(EventLogPanel);
74367
74161
 
74368
74162
  // source/gui/client/lib/aside-dock.ts
74369
- var import_react50 = __toESM(require_react(), 1);
74163
+ var import_react49 = __toESM(require_react(), 1);
74370
74164
  var DOCK_STORAGE_KEY = "epiq.aside.dock";
74371
74165
  var readStoredAsideDock = () => localStorage.getItem(DOCK_STORAGE_KEY) === "bottom" ? "bottom" : "right";
74372
74166
  var useAsideDock = () => {
74373
- const [dock, setDock] = (0, import_react50.useState)(readStoredAsideDock);
74167
+ const [dock, setDock] = (0, import_react49.useState)(readStoredAsideDock);
74374
74168
  return [
74375
74169
  dock,
74376
74170
  (next) => {
@@ -74381,7 +74175,7 @@ var useAsideDock = () => {
74381
74175
  };
74382
74176
 
74383
74177
  // source/gui/client/components/CommandPalette.tsx
74384
- var import_react51 = __toESM(require_react(), 1);
74178
+ var import_react50 = __toESM(require_react(), 1);
74385
74179
 
74386
74180
  // source/gui/client/lib/commands/command-match.ts
74387
74181
  var subsequenceHits = (text8, query) => {
@@ -74680,12 +74474,12 @@ var buildCommandRegistry = () => [
74680
74474
  var commandRank = (context) => (command) => command.unavailable(context) === null ? 0 : 1;
74681
74475
 
74682
74476
  // source/gui/client/components/CommandPaletteRow.tsx
74683
- var import_jsx_runtime91 = __toESM(require_jsx_runtime(), 1);
74477
+ var import_jsx_runtime90 = __toESM(require_jsx_runtime(), 1);
74684
74478
  var Highlighted = ({ text: text8, hits }) => {
74685
- if (hits.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(import_jsx_runtime91.Fragment, { children: text8 });
74479
+ if (hits.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(import_jsx_runtime90.Fragment, { children: text8 });
74686
74480
  const marked = new Set(hits);
74687
- return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(import_jsx_runtime91.Fragment, { children: [...text8].map(
74688
- (character, index2) => marked.has(index2) ? /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { style: { color: GUI_THEME.accent }, children: character }, index2) : /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { children: character }, index2)
74481
+ return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(import_jsx_runtime90.Fragment, { children: [...text8].map(
74482
+ (character, index2) => marked.has(index2) ? /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { style: { color: GUI_THEME.accent }, children: character }, index2) : /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { children: character }, index2)
74689
74483
  ) });
74690
74484
  };
74691
74485
  var CommandPaletteRow = ({
@@ -74699,7 +74493,7 @@ var CommandPaletteRow = ({
74699
74493
  hasArguments,
74700
74494
  onHover,
74701
74495
  onRun
74702
- }) => /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
74496
+ }) => /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
74703
74497
  "button",
74704
74498
  {
74705
74499
  type: "button",
@@ -74725,7 +74519,7 @@ var CommandPaletteRow = ({
74725
74519
  cursor: reason ? "default" : "pointer"
74726
74520
  },
74727
74521
  children: [
74728
- color2 && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
74522
+ color2 && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
74729
74523
  "span",
74730
74524
  {
74731
74525
  "aria-hidden": true,
@@ -74739,7 +74533,7 @@ var CommandPaletteRow = ({
74739
74533
  }
74740
74534
  }
74741
74535
  ),
74742
- /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
74536
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
74743
74537
  "span",
74744
74538
  {
74745
74539
  style: {
@@ -74749,12 +74543,12 @@ var CommandPaletteRow = ({
74749
74543
  whiteSpace: "nowrap"
74750
74544
  },
74751
74545
  children: [
74752
- /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(Highlighted, { text: title, hits }),
74753
- hasArguments && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { style: { color: GUI_THEME.dim }, children: " \u2026" })
74546
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(Highlighted, { text: title, hits }),
74547
+ hasArguments && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { style: { color: GUI_THEME.dim }, children: " \u2026" })
74754
74548
  ]
74755
74549
  }
74756
74550
  ),
74757
- /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
74551
+ /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
74758
74552
  "span",
74759
74553
  {
74760
74554
  style: {
@@ -74771,7 +74565,7 @@ var CommandPaletteRow = ({
74771
74565
  );
74772
74566
 
74773
74567
  // source/gui/client/components/CommandPalette.tsx
74774
- var import_jsx_runtime92 = __toESM(require_jsx_runtime(), 1);
74568
+ var import_jsx_runtime91 = __toESM(require_jsx_runtime(), 1);
74775
74569
  var MAX_ROWS = 8;
74776
74570
  var MAX_MATCHES = 50;
74777
74571
  var CommandPalette = ({
@@ -74781,12 +74575,12 @@ var CommandPalette = ({
74781
74575
  onRun,
74782
74576
  onClose
74783
74577
  }) => {
74784
- const [query, setQuery] = (0, import_react51.useState)("");
74785
- const [step, setStep] = (0, import_react51.useState)(null);
74786
- const [selected, setSelected] = (0, import_react51.useState)(0);
74787
- const inputRef = (0, import_react51.useRef)(null);
74788
- const listRef = (0, import_react51.useRef)(null);
74789
- const commandMatches = (0, import_react51.useMemo)(
74578
+ const [query, setQuery] = (0, import_react50.useState)("");
74579
+ const [step, setStep] = (0, import_react50.useState)(null);
74580
+ const [selected, setSelected] = (0, import_react50.useState)(0);
74581
+ const inputRef = (0, import_react50.useRef)(null);
74582
+ const listRef = (0, import_react50.useRef)(null);
74583
+ const commandMatches = (0, import_react50.useMemo)(
74790
74584
  () => step ? [] : matchItems(commands, query, {
74791
74585
  recentIds,
74792
74586
  rank: commandRank(context),
@@ -74794,7 +74588,7 @@ var CommandPalette = ({
74794
74588
  }),
74795
74589
  [step, query, commands, recentIds, context]
74796
74590
  );
74797
- const argumentMatches = (0, import_react51.useMemo)(() => {
74591
+ const argumentMatches = (0, import_react50.useMemo)(() => {
74798
74592
  if (!step) return [];
74799
74593
  const found = matchItems(step.options, query, { limit: MAX_MATCHES });
74800
74594
  const fresh = step.command.freeTextArgument?.(query);
@@ -74805,13 +74599,13 @@ var CommandPalette = ({
74805
74599
  }, [step, query]);
74806
74600
  const matches2 = step ? argumentMatches : commandMatches;
74807
74601
  const capped = matches2.length >= MAX_MATCHES;
74808
- (0, import_react51.useEffect)(() => {
74602
+ (0, import_react50.useEffect)(() => {
74809
74603
  setSelected(0);
74810
74604
  }, [query, step]);
74811
- (0, import_react51.useEffect)(() => {
74605
+ (0, import_react50.useEffect)(() => {
74812
74606
  inputRef.current?.focus();
74813
74607
  }, [step]);
74814
- (0, import_react51.useEffect)(() => {
74608
+ (0, import_react50.useEffect)(() => {
74815
74609
  listRef.current?.children[selected]?.scrollIntoView({ block: "nearest" });
74816
74610
  }, [selected]);
74817
74611
  const runMatch = (index2) => {
@@ -74857,7 +74651,7 @@ var CommandPalette = ({
74857
74651
  return setStep(null);
74858
74652
  }
74859
74653
  };
74860
- return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
74654
+ return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
74861
74655
  "div",
74862
74656
  {
74863
74657
  "data-testid": "command-palette",
@@ -74875,7 +74669,7 @@ var CommandPalette = ({
74875
74669
  zIndex: 1100
74876
74670
  },
74877
74671
  onMouseDown: onClose,
74878
- children: /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
74672
+ children: /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
74879
74673
  "div",
74880
74674
  {
74881
74675
  onMouseDown: (event) => event.stopPropagation(),
@@ -74889,7 +74683,7 @@ var CommandPalette = ({
74889
74683
  overflow: "hidden"
74890
74684
  },
74891
74685
  children: [
74892
- /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
74686
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
74893
74687
  "div",
74894
74688
  {
74895
74689
  style: {
@@ -74900,7 +74694,7 @@ var CommandPalette = ({
74900
74694
  borderBottom: `1px solid ${GUI_THEME.line}`
74901
74695
  },
74902
74696
  children: [
74903
- step && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
74697
+ step && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
74904
74698
  "span",
74905
74699
  {
74906
74700
  style: {
@@ -74914,7 +74708,7 @@ var CommandPalette = ({
74914
74708
  children: step.command.title
74915
74709
  }
74916
74710
  ),
74917
- /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
74711
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
74918
74712
  "input",
74919
74713
  {
74920
74714
  ref: inputRef,
@@ -74937,7 +74731,7 @@ var CommandPalette = ({
74937
74731
  ]
74938
74732
  }
74939
74733
  ),
74940
- /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
74734
+ /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
74941
74735
  "div",
74942
74736
  {
74943
74737
  ref: listRef,
@@ -74948,7 +74742,7 @@ var CommandPalette = ({
74948
74742
  padding: "4px 0"
74949
74743
  },
74950
74744
  children: [
74951
- matches2.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
74745
+ matches2.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
74952
74746
  "div",
74953
74747
  {
74954
74748
  style: {
@@ -74966,7 +74760,7 @@ var CommandPalette = ({
74966
74760
  matches2.map((match, index2) => {
74967
74761
  const asCommand = step ? null : match.item;
74968
74762
  const asArgument = step ? match.item : null;
74969
- return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
74763
+ return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
74970
74764
  CommandPaletteRow,
74971
74765
  {
74972
74766
  title: asCommand?.title ?? asArgument?.title ?? "",
@@ -74983,7 +74777,7 @@ var CommandPalette = ({
74983
74777
  match.item.id
74984
74778
  );
74985
74779
  }),
74986
- capped && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
74780
+ capped && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
74987
74781
  "div",
74988
74782
  {
74989
74783
  style: {
@@ -75005,7 +74799,7 @@ var CommandPalette = ({
75005
74799
  };
75006
74800
 
75007
74801
  // source/gui/client/lib/commands/command-recents.ts
75008
- var import_react52 = __toESM(require_react(), 1);
74802
+ var import_react51 = __toESM(require_react(), 1);
75009
74803
  var STORAGE_KEY3 = "epiq.gui.recentCommands";
75010
74804
  var CAP = 6;
75011
74805
  var readRecentCommands = () => {
@@ -75020,7 +74814,7 @@ var readRecentCommands = () => {
75020
74814
  };
75021
74815
  var withCommandRemembered = (recent, id) => [id, ...recent.filter((entry) => entry !== id)].slice(0, CAP);
75022
74816
  var useRecentCommands = () => {
75023
- const [ids, setIds] = (0, import_react52.useState)(readRecentCommands);
74817
+ const [ids, setIds] = (0, import_react51.useState)(readRecentCommands);
75024
74818
  return {
75025
74819
  ids,
75026
74820
  remember: (id) => {
@@ -75037,7 +74831,7 @@ var useRecentCommands = () => {
75037
74831
  };
75038
74832
 
75039
74833
  // source/gui/client/lib/use-command-palette.ts
75040
- var import_react53 = __toESM(require_react(), 1);
74834
+ var import_react52 = __toESM(require_react(), 1);
75041
74835
  var isTypingTarget = (target) => {
75042
74836
  const element4 = target;
75043
74837
  if (!element4) return false;
@@ -75045,8 +74839,8 @@ var isTypingTarget = (target) => {
75045
74839
  return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || element4.isContentEditable;
75046
74840
  };
75047
74841
  var useCommandPalette = () => {
75048
- const [open, setOpen] = (0, import_react53.useState)(false);
75049
- (0, import_react53.useEffect)(() => {
74842
+ const [open, setOpen] = (0, import_react52.useState)(false);
74843
+ (0, import_react52.useEffect)(() => {
75050
74844
  const onKeyDown = (event) => {
75051
74845
  const chord = event.key === "k" && (event.metaKey || event.ctrlKey);
75052
74846
  const colon = event.key === ":" && !event.metaKey && !event.ctrlKey;
@@ -75231,7 +75025,7 @@ var updateIssueInGuiState = (state, issueId, updateIssue) => ({
75231
75025
  });
75232
75026
 
75233
75027
  // source/gui/client/lib/use-event-log.ts
75234
- var import_react54 = __toESM(require_react(), 1);
75028
+ var import_react53 = __toESM(require_react(), 1);
75235
75029
  var NONE = [];
75236
75030
  var momentOnScreen = (playing, playheadTime, timeTravel) => {
75237
75031
  if (playing) return playheadTime ?? -Infinity;
@@ -75255,7 +75049,7 @@ var useEventLog = ({
75255
75049
  const { only, ticketOnly } = selection;
75256
75050
  const view = plottedView(only);
75257
75051
  const issueOnly = ticketOnly && selectedIssueId !== null ? selectedIssueId : null;
75258
- const rows = (0, import_react54.useMemo)(() => {
75052
+ const rows = (0, import_react53.useMemo)(() => {
75259
75053
  if (!open) return NONE;
75260
75054
  const events = timeline?.events ?? [];
75261
75055
  const axis = identityAxisFor(view);
@@ -75269,23 +75063,23 @@ var useEventLog = ({
75269
75063
  );
75270
75064
  }, [open, timeline, commits, view, only, issueOnly, showIssues, showCommits]);
75271
75065
  const moment = momentOnScreen(playing, playheadTime, timeTravel);
75272
- const entries = (0, import_react54.useMemo)(() => logEntriesUpTo(rows, moment), [rows, moment]);
75273
- return (0, import_react54.useMemo)(() => ({ entries, moment }), [entries, moment]);
75066
+ const entries = (0, import_react53.useMemo)(() => logEntriesUpTo(rows, moment), [rows, moment]);
75067
+ return (0, import_react53.useMemo)(() => ({ entries, moment }), [entries, moment]);
75274
75068
  };
75275
75069
 
75276
75070
  // source/gui/client/lib/use-board-selection.ts
75277
- var import_react55 = __toESM(require_react(), 1);
75071
+ var import_react54 = __toESM(require_react(), 1);
75278
75072
  var useBoardSelection = () => {
75279
75073
  const [searchParams, setSearchParams] = useSearchParams();
75280
75074
  const fromUrl = hasSelectionParams(searchParams);
75281
- const carried = (0, import_react55.useRef)(DEFAULT_CARRY);
75075
+ const carried = (0, import_react54.useRef)(DEFAULT_CARRY);
75282
75076
  const query = searchParams.toString();
75283
- const selection = (0, import_react55.useMemo)(() => {
75077
+ const selection = (0, import_react54.useMemo)(() => {
75284
75078
  const fromParams = readSelectionParams(searchParams);
75285
75079
  return fromParams ?? { ...readStoredSelection(), ...carried.current.values };
75286
75080
  }, [searchParams]);
75287
75081
  carried.current = carryRender(carried.current, query, selection);
75288
- (0, import_react55.useEffect)(() => {
75082
+ (0, import_react54.useEffect)(() => {
75289
75083
  if (fromUrl) {
75290
75084
  storeSelection(selection);
75291
75085
  return;
@@ -75300,7 +75094,7 @@ var useBoardSelection = () => {
75300
75094
  { replace: true }
75301
75095
  );
75302
75096
  }, [searchParams]);
75303
- const change = (0, import_react55.useCallback)(
75097
+ const change = (0, import_react54.useCallback)(
75304
75098
  (patch2) => {
75305
75099
  const next = applySelectionPatch(selection, patch2);
75306
75100
  storeSelection(next);
@@ -75320,7 +75114,7 @@ var useBoardSelection = () => {
75320
75114
  };
75321
75115
 
75322
75116
  // source/gui/client/lib/use-board-socket.ts
75323
- var import_react56 = __toESM(require_react(), 1);
75117
+ var import_react55 = __toESM(require_react(), 1);
75324
75118
 
75325
75119
  // source/gui/client/lib/gui-mutations.ts
75326
75120
  var MUTATING_MESSAGE_TYPES = /* @__PURE__ */ new Set([
@@ -75408,44 +75202,44 @@ var useBoardSocket = ({
75408
75202
  boardId,
75409
75203
  onMessage
75410
75204
  }) => {
75411
- const socketRef = (0, import_react56.useRef)(null);
75412
- const [connected, setConnected] = (0, import_react56.useState)(false);
75413
- const [socketEpoch, setSocketEpoch] = (0, import_react56.useState)(0);
75414
- const [reconnectTick, setReconnectTick] = (0, import_react56.useState)(0);
75415
- const [reconnectExhausted, setReconnectExhausted] = (0, import_react56.useState)(false);
75416
- const reconnectAttempts = (0, import_react56.useRef)(0);
75417
- const reconnectTimer = (0, import_react56.useRef)(null);
75418
- const [gate] = (0, import_react56.useState)(createMutationGate);
75419
- const onMessageRef = (0, import_react56.useRef)(onMessage);
75205
+ const socketRef = (0, import_react55.useRef)(null);
75206
+ const [connected, setConnected] = (0, import_react55.useState)(false);
75207
+ const [socketEpoch, setSocketEpoch] = (0, import_react55.useState)(0);
75208
+ const [reconnectTick, setReconnectTick] = (0, import_react55.useState)(0);
75209
+ const [reconnectExhausted, setReconnectExhausted] = (0, import_react55.useState)(false);
75210
+ const reconnectAttempts = (0, import_react55.useRef)(0);
75211
+ const reconnectTimer = (0, import_react55.useRef)(null);
75212
+ const [gate] = (0, import_react55.useState)(createMutationGate);
75213
+ const onMessageRef = (0, import_react55.useRef)(onMessage);
75420
75214
  onMessageRef.current = onMessage;
75421
- const sendRaw = (0, import_react56.useCallback)((message) => {
75215
+ const sendRaw = (0, import_react55.useCallback)((message) => {
75422
75216
  sendSocketJson(socketRef.current, message);
75423
75217
  }, []);
75424
- const send = (0, import_react56.useCallback)(
75218
+ const send = (0, import_react55.useCallback)(
75425
75219
  (type, payload) => {
75426
75220
  gate.sent(type);
75427
75221
  sendSocketJson(socketRef.current, { type, payload });
75428
75222
  },
75429
75223
  [gate]
75430
75224
  );
75431
- const requestState = (0, import_react56.useCallback)(
75225
+ const requestState = (0, import_react55.useCallback)(
75432
75226
  () => sendRaw({ type: "state:get" }),
75433
75227
  [sendRaw]
75434
75228
  );
75435
- const holdsState = (0, import_react56.useCallback)(() => gate.holdsState(), [gate]);
75436
- const actionsRef = (0, import_react56.useRef)({
75229
+ const holdsState = (0, import_react55.useCallback)(() => gate.holdsState(), [gate]);
75230
+ const actionsRef = (0, import_react55.useRef)({
75437
75231
  send,
75438
75232
  sendRaw,
75439
75233
  requestState,
75440
75234
  holdsState
75441
75235
  });
75442
75236
  actionsRef.current = { send, sendRaw, requestState, holdsState };
75443
- const reconnectNow = (0, import_react56.useCallback)(() => {
75237
+ const reconnectNow = (0, import_react55.useCallback)(() => {
75444
75238
  reconnectAttempts.current = 0;
75445
75239
  setReconnectExhausted(false);
75446
75240
  setReconnectTick((tick) => tick + 1);
75447
75241
  }, []);
75448
- (0, import_react56.useEffect)(() => {
75242
+ (0, import_react55.useEffect)(() => {
75449
75243
  const socket = new WebSocket(
75450
75244
  `ws://${window.location.host}/ws${boardId ? `?boardId=${boardId}` : ""}`
75451
75245
  );
@@ -75507,7 +75301,7 @@ var useBoardSocket = ({
75507
75301
  };
75508
75302
 
75509
75303
  // source/gui/client/lib/use-issue-detail.ts
75510
- var import_react57 = __toESM(require_react(), 1);
75304
+ var import_react56 = __toESM(require_react(), 1);
75511
75305
  var needsStats = (held, issueId, signature) => held === null || held.issueId !== issueId || held.signature !== signature || held.error !== null;
75512
75306
  var useIssueDetail = ({
75513
75307
  issueId,
@@ -75515,10 +75309,10 @@ var useIssueDetail = ({
75515
75309
  paused,
75516
75310
  sendRaw
75517
75311
  }) => {
75518
- const [detail, setDetail] = (0, import_react57.useState)(null);
75519
- const [commits, setCommits] = (0, import_react57.useState)(null);
75520
- const [commitDiffs, setCommitDiffs] = (0, import_react57.useState)({});
75521
- (0, import_react57.useEffect)(() => {
75312
+ const [detail, setDetail] = (0, import_react56.useState)(null);
75313
+ const [commits, setCommits] = (0, import_react56.useState)(null);
75314
+ const [commitDiffs, setCommitDiffs] = (0, import_react56.useState)({});
75315
+ (0, import_react56.useEffect)(() => {
75522
75316
  if (!issueId) {
75523
75317
  setDetail(null);
75524
75318
  return;
@@ -75526,7 +75320,7 @@ var useIssueDetail = ({
75526
75320
  if (paused) return;
75527
75321
  sendRaw({ type: "issue:get", payload: { issueId } });
75528
75322
  }, [issueId, boardState, paused, sendRaw]);
75529
- (0, import_react57.useEffect)(() => {
75323
+ (0, import_react56.useEffect)(() => {
75530
75324
  if (!issueId) {
75531
75325
  setCommits(null);
75532
75326
  return;
@@ -75534,11 +75328,11 @@ var useIssueDetail = ({
75534
75328
  setCommits({ issueId, loading: true, error: null, commits: [] });
75535
75329
  sendRaw({ type: "issue:commits:get", payload: { issueId } });
75536
75330
  }, [issueId, sendRaw]);
75537
- const [stats, setStats] = (0, import_react57.useState)(null);
75538
- (0, import_react57.useEffect)(() => {
75331
+ const [stats, setStats] = (0, import_react56.useState)(null);
75332
+ (0, import_react56.useEffect)(() => {
75539
75333
  setStats(null);
75540
75334
  }, [issueId]);
75541
- const loadStats = (0, import_react57.useCallback)((id, signature) => {
75335
+ const loadStats = (0, import_react56.useCallback)((id, signature) => {
75542
75336
  setStats(
75543
75337
  (prev) => needsStats(prev, id, signature) ? {
75544
75338
  issueId: id,
@@ -75549,11 +75343,11 @@ var useIssueDetail = ({
75549
75343
  } : prev
75550
75344
  );
75551
75345
  }, []);
75552
- (0, import_react57.useEffect)(() => {
75346
+ (0, import_react56.useEffect)(() => {
75553
75347
  if (!stats?.loading) return;
75554
75348
  sendRaw({ type: "issue:stats:get", payload: { issueId: stats.issueId } });
75555
75349
  }, [stats?.issueId, stats?.signature, stats?.loading, sendRaw]);
75556
- const loadCommitDiff = (0, import_react57.useCallback)(
75350
+ const loadCommitDiff = (0, import_react56.useCallback)(
75557
75351
  (sha) => {
75558
75352
  setCommitDiffs((prev) => ({
75559
75353
  ...prev,
@@ -75563,7 +75357,7 @@ var useIssueDetail = ({
75563
75357
  },
75564
75358
  [sendRaw]
75565
75359
  );
75566
- const updateComments = (0, import_react57.useCallback)(
75360
+ const updateComments = (0, import_react56.useCallback)(
75567
75361
  (id, update) => {
75568
75362
  setDetail(
75569
75363
  (prev) => prev && prev.issueId === id ? { ...prev, comments: update(prev.comments) } : prev
@@ -75571,7 +75365,7 @@ var useIssueDetail = ({
75571
75365
  },
75572
75366
  []
75573
75367
  );
75574
- const onMessage = (0, import_react57.useCallback)((message) => {
75368
+ const onMessage = (0, import_react56.useCallback)((message) => {
75575
75369
  if (message.type === "issue") {
75576
75370
  const next = getResultValue(message.payload);
75577
75371
  if (next) setDetail(next);
@@ -75648,13 +75442,13 @@ var useIssueDetail = ({
75648
75442
  };
75649
75443
 
75650
75444
  // source/gui/client/lib/use-swimlane-stats.ts
75651
- var import_react58 = __toESM(require_react(), 1);
75445
+ var import_react57 = __toESM(require_react(), 1);
75652
75446
  var useSwimlaneStats = ({
75653
75447
  swimlaneId,
75654
75448
  sendRaw
75655
75449
  }) => {
75656
- const [stats, setStats] = (0, import_react58.useState)(null);
75657
- (0, import_react58.useEffect)(() => {
75450
+ const [stats, setStats] = (0, import_react57.useState)(null);
75451
+ (0, import_react57.useEffect)(() => {
75658
75452
  if (!swimlaneId) {
75659
75453
  setStats(null);
75660
75454
  return;
@@ -75662,7 +75456,7 @@ var useSwimlaneStats = ({
75662
75456
  setStats({ swimlaneId, loading: true, error: null, stats: null });
75663
75457
  sendRaw({ type: "swimlane:stats:get", payload: { swimlaneId } });
75664
75458
  }, [swimlaneId, sendRaw]);
75665
- const onMessage = (0, import_react58.useCallback)((message) => {
75459
+ const onMessage = (0, import_react57.useCallback)((message) => {
75666
75460
  if (message.type !== "swimlane:stats:result") return;
75667
75461
  const { swimlaneId: forLane, result } = message.payload;
75668
75462
  if (result?.status === "fail") {
@@ -75681,28 +75475,8 @@ var useSwimlaneStats = ({
75681
75475
  return { stats, onMessage };
75682
75476
  };
75683
75477
 
75684
- // source/gui/client/lib/use-board-stay-trends.ts
75685
- var import_react59 = __toESM(require_react(), 1);
75686
- var useBoardStayTrends = ({
75687
- boardId,
75688
- socketEpoch,
75689
- sendRaw
75690
- }) => {
75691
- const [trends, setTrends] = (0, import_react59.useState)({});
75692
- (0, import_react59.useEffect)(() => {
75693
- if (!boardId) return;
75694
- sendRaw({ type: "board:stay-trends:get" });
75695
- }, [boardId, socketEpoch, sendRaw]);
75696
- const onMessage = (0, import_react59.useCallback)((message) => {
75697
- if (message.type !== "board:stay-trends:result") return;
75698
- const next = getResultValue(message.payload);
75699
- if (next) setTrends(next);
75700
- }, []);
75701
- return { trends, onMessage };
75702
- };
75703
-
75704
75478
  // source/gui/client/lib/use-issue-mutations.ts
75705
- var import_react60 = __toESM(require_react(), 1);
75479
+ var import_react58 = __toESM(require_react(), 1);
75706
75480
 
75707
75481
  // source/gui/client/lib/compress-image.ts
75708
75482
  var MAX_LONG_EDGE = 1600;
@@ -75776,7 +75550,7 @@ var useIssueMutations = ({
75776
75550
  updateComments,
75777
75551
  attachmentMaxKb
75778
75552
  }) => {
75779
- const [attachmentUploadStatus, setAttachmentUploadStatus] = (0, import_react60.useState)({ state: "idle" });
75553
+ const [attachmentUploadStatus, setAttachmentUploadStatus] = (0, import_react58.useState)({ state: "idle" });
75780
75554
  const editIssueTitle = (issueId, title) => {
75781
75555
  setState((prev) => {
75782
75556
  if (!prev) return prev;
@@ -76025,18 +75799,18 @@ var useIssueMutations = ({
76025
75799
  };
76026
75800
 
76027
75801
  // source/gui/client/lib/use-swimlane-editing.ts
76028
- var import_react61 = __toESM(require_react(), 1);
75802
+ var import_react59 = __toESM(require_react(), 1);
76029
75803
  var useSwimlaneEditing = ({
76030
75804
  send,
76031
75805
  setState,
76032
75806
  selectedBoard,
76033
75807
  visibleSwimlanes
76034
75808
  }) => {
76035
- const [createSwimlaneTitle, setCreateSwimlaneTitle] = (0, import_react61.useState)(
75809
+ const [createSwimlaneTitle, setCreateSwimlaneTitle] = (0, import_react59.useState)(
76036
75810
  null
76037
75811
  );
76038
- const [renameSwimlane, setRenameSwimlane] = (0, import_react61.useState)(null);
76039
- const [deleteSwimlaneId, setDeleteSwimlaneId] = (0, import_react61.useState)(null);
75812
+ const [renameSwimlane, setRenameSwimlane] = (0, import_react59.useState)(null);
75813
+ const [deleteSwimlaneId, setDeleteSwimlaneId] = (0, import_react59.useState)(null);
76040
75814
  const createSwimlane = () => {
76041
75815
  if (createSwimlaneTitle === null || !selectedBoard) return;
76042
75816
  const title = createSwimlaneTitle.trim() || "New swimlane";
@@ -76130,7 +75904,7 @@ var createHistoryBuffer = (publish) => {
76130
75904
  };
76131
75905
 
76132
75906
  // source/gui/client/App.tsx
76133
- var import_jsx_runtime93 = __toESM(require_jsx_runtime(), 1);
75907
+ var import_jsx_runtime92 = __toESM(require_jsx_runtime(), 1);
76134
75908
  var EMPTY_COMMENTS = {};
76135
75909
  var BOARD_GUTTER = 30;
76136
75910
  var LOG_REFRESH_QUIET_MS = 400;
@@ -76143,7 +75917,7 @@ var DIMMED_WHILE_PLAYING = {
76143
75917
  pointerEvents: "none",
76144
75918
  transition: "opacity 240ms ease"
76145
75919
  };
76146
- var DropIndicator = () => /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
75920
+ var DropIndicator = () => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
76147
75921
  "div",
76148
75922
  {
76149
75923
  "data-testid": "ticket-drop-indicator",
@@ -76163,7 +75937,7 @@ var App = () => {
76163
75937
  const issueId = issueMatch?.params.issueId ?? legacyIssueMatch?.params.issueId;
76164
75938
  const [searchParams, setSearchParams] = useSearchParams();
76165
75939
  const [selection, changeSelection] = useBoardSelection();
76166
- const socketMessageRef = (0, import_react62.useRef)(() => {
75940
+ const socketMessageRef = (0, import_react60.useRef)(() => {
76167
75941
  });
76168
75942
  const {
76169
75943
  connected,
@@ -76177,17 +75951,17 @@ var App = () => {
76177
75951
  boardId,
76178
75952
  onMessage: (message, socket) => socketMessageRef.current(message, socket)
76179
75953
  });
76180
- const [syncStatus, setSyncStatus] = (0, import_react62.useState)({
75954
+ const [syncStatus, setSyncStatus] = (0, import_react60.useState)({
76181
75955
  status: "synced",
76182
75956
  msg: "idle"
76183
75957
  });
76184
- const [state, setState] = (0, import_react62.useState)(null);
76185
- const [noProject, setNoProject] = (0, import_react62.useState)(null);
76186
- const [contributors, setContributors] = (0, import_react62.useState)([]);
76187
- const [history, setHistory] = (0, import_react62.useState)({ requestId: 0, timeline: null, commits: [] });
76188
- const [historyBuffer] = (0, import_react62.useState)(() => createHistoryBuffer(setHistory));
76189
- const [theatre, setTheatre] = (0, import_react62.useState)(null);
76190
- const [scrubAck, setScrubAck] = (0, import_react62.useState)(0);
75958
+ const [state, setState] = (0, import_react60.useState)(null);
75959
+ const [noProject, setNoProject] = (0, import_react60.useState)(null);
75960
+ const [contributors, setContributors] = (0, import_react60.useState)([]);
75961
+ const [history, setHistory] = (0, import_react60.useState)({ requestId: 0, timeline: null, commits: [] });
75962
+ const [historyBuffer] = (0, import_react60.useState)(() => createHistoryBuffer(setHistory));
75963
+ const [theatre, setTheatre] = (0, import_react60.useState)(null);
75964
+ const [scrubAck, setScrubAck] = (0, import_react60.useState)(0);
76191
75965
  const [logOpen, setLogOpen] = usePersistedFlag(LOG_STORAGE_KEY, false);
76192
75966
  const [showIssues, setShowIssues] = usePersistedFlag(
76193
75967
  SHOW_ISSUES_STORAGE_KEY,
@@ -76197,37 +75971,37 @@ var App = () => {
76197
75971
  SHOW_COMMITS_STORAGE_KEY,
76198
75972
  true
76199
75973
  );
76200
- const [commitDiff, setCommitDiff] = (0, import_react62.useState)(null);
76201
- const [commitDiffPanelWidth, setCommitDiffPanelWidth] = (0, import_react62.useState)(readStoredAsideWidth);
75974
+ const [commitDiff, setCommitDiff] = (0, import_react60.useState)(null);
75975
+ const [commitDiffPanelWidth, setCommitDiffPanelWidth] = (0, import_react60.useState)(readStoredAsideWidth);
76202
75976
  const [asideDock, setAsideDock] = useAsideDock();
76203
- const [removeError, setRemoveError] = (0, import_react62.useState)(null);
76204
- const [actionError, setActionError] = (0, import_react62.useState)(null);
76205
- const [dragOverSwimlaneId, setDragOverSwimlaneId] = (0, import_react62.useState)(
75977
+ const [removeError, setRemoveError] = (0, import_react60.useState)(null);
75978
+ const [actionError, setActionError] = (0, import_react60.useState)(null);
75979
+ const [dragOverSwimlaneId, setDragOverSwimlaneId] = (0, import_react60.useState)(
76206
75980
  null
76207
75981
  );
76208
- const [dropTarget, setDropTarget] = (0, import_react62.useState)(null);
76209
- const [pickedIssueIds, setPickedIssueIds] = (0, import_react62.useState)([]);
76210
- const [boardMenuOpen, setBoardMenuOpen] = (0, import_react62.useState)(false);
76211
- const [createIssueModal, setCreateIssueModal] = (0, import_react62.useState)(null);
76212
- const [hoveredLogEventId, setHoveredLogEventId] = (0, import_react62.useState)(
75982
+ const [dropTarget, setDropTarget] = (0, import_react60.useState)(null);
75983
+ const [pickedIssueIds, setPickedIssueIds] = (0, import_react60.useState)([]);
75984
+ const [boardMenuOpen, setBoardMenuOpen] = (0, import_react60.useState)(false);
75985
+ const [createIssueModal, setCreateIssueModal] = (0, import_react60.useState)(null);
75986
+ const [hoveredLogEventId, setHoveredLogEventId] = (0, import_react60.useState)(
76213
75987
  null
76214
75988
  );
76215
- const [swimlaneDropEdge, setSwimlaneDropEdge] = (0, import_react62.useState)(null);
76216
- const boardMenuRef = (0, import_react62.useRef)(null);
76217
- const pendingFileTicketOrigin = (0, import_react62.useRef)(null);
75989
+ const [swimlaneDropEdge, setSwimlaneDropEdge] = (0, import_react60.useState)(null);
75990
+ const boardMenuRef = (0, import_react60.useRef)(null);
75991
+ const pendingFileTicketOrigin = (0, import_react60.useRef)(null);
76218
75992
  const tabParam = searchParams.get("tab");
76219
75993
  const selectedTab = tabParam === "comments" || tabParam === "history" || tabParam === "code" || tabParam === "stats" ? tabParam : "overview";
76220
75994
  const diffFocus = readDiffLocationParams(searchParams) ?? readCommitFocusParam(searchParams);
76221
75995
  const navigate = useNavigate();
76222
75996
  const selectedBoard = (state && boardId ? findBoard(state, boardId) : null) ?? state?.boards?.[0] ?? null;
76223
75997
  const selectedBoardId = selectedBoard?.id ?? null;
76224
- const selectedBoardIdRef = (0, import_react62.useRef)(selectedBoardId);
75998
+ const selectedBoardIdRef = (0, import_react60.useRef)(selectedBoardId);
76225
75999
  selectedBoardIdRef.current = selectedBoardId;
76226
- const navigateRef = (0, import_react62.useRef)(navigate);
76000
+ const navigateRef = (0, import_react60.useRef)(navigate);
76227
76001
  navigateRef.current = navigate;
76228
76002
  const boardSlug = selectedBoard?.ref ?? boardId;
76229
76003
  const selectedIssue = state && issueId ? findIssue(state, issueId) : null;
76230
- (0, import_react62.useEffect)(() => {
76004
+ (0, import_react60.useEffect)(() => {
76231
76005
  const onPaste = (event) => {
76232
76006
  if (!selectedIssue || selectedIssue.readonly) return;
76233
76007
  const target = event.target;
@@ -76246,7 +76020,7 @@ var App = () => {
76246
76020
  if (!boardSlug) return;
76247
76021
  void navigate(`/board/${boardSlug}`);
76248
76022
  };
76249
- const [statsSwimlaneId, setStatsSwimlaneId] = (0, import_react62.useState)(null);
76023
+ const [statsSwimlaneId, setStatsSwimlaneId] = (0, import_react60.useState)(null);
76250
76024
  const commentsByIssueId = state?.commentsByIssueId ?? EMPTY_COMMENTS;
76251
76025
  const {
76252
76026
  detail: issueDetail,
@@ -76266,13 +76040,12 @@ var App = () => {
76266
76040
  sendRaw
76267
76041
  });
76268
76042
  const { stats: swimlaneStats, onMessage: onSwimlaneStatsMessage } = useSwimlaneStats({ swimlaneId: statsSwimlaneId, sendRaw });
76269
- const { trends: stayTrends, onMessage: onStayTrendsMessage } = useBoardStayTrends({ boardId: boardId ?? null, socketEpoch, sendRaw });
76270
76043
  const statsSignature = issueCommits?.issueId === selectedIssue?.id ? issueCommits?.commits[0]?.sha ?? "" : "";
76271
- (0, import_react62.useEffect)(() => {
76044
+ (0, import_react60.useEffect)(() => {
76272
76045
  if (selectedTab !== "stats" || !selectedIssue) return;
76273
76046
  loadIssueStats(selectedIssue.id, statsSignature);
76274
76047
  }, [selectedTab, selectedIssue?.id, statsSignature, loadIssueStats]);
76275
- const boardStats = (0, import_react62.useMemo)(() => {
76048
+ const boardStats = (0, import_react60.useMemo)(() => {
76276
76049
  if (!selectedIssue || !state) return null;
76277
76050
  const board = state.boards.find(
76278
76051
  (candidate) => candidate.swimlanes.some(
@@ -76292,18 +76065,18 @@ var App = () => {
76292
76065
  currentLaneId: lane.id
76293
76066
  });
76294
76067
  }, [selectedIssue?.id, state, issueDetail]);
76295
- const [textFilter, setTextFilter] = (0, import_react62.useState)("");
76296
- const boardFilter = (0, import_react62.useMemo)(
76068
+ const [textFilter, setTextFilter] = (0, import_react60.useState)("");
76069
+ const boardFilter = (0, import_react60.useMemo)(
76297
76070
  () => buildBoardFilter(selection.only),
76298
76071
  [selection.only]
76299
76072
  );
76300
76073
  const narrowsByActor = selection.only.actor !== void 0;
76301
- const eventActorIds = (0, import_react62.useMemo)(
76074
+ const eventActorIds = (0, import_react60.useMemo)(
76302
76075
  () => narrowsByActor ? actorIdsByIssue(history.timeline) : null,
76303
76076
  [narrowsByActor, history.timeline]
76304
76077
  );
76305
76078
  const zoomed = selection.zoom !== null;
76306
- const windowIds = (0, import_react62.useMemo)(
76079
+ const windowIds = (0, import_react60.useMemo)(
76307
76080
  () => selection.windowOnly && isPeriodWindow(selection.scope, zoomed) ? windowIssueIds(history.timeline) : null,
76308
76081
  [selection.windowOnly, selection.scope, zoomed, history.timeline]
76309
76082
  );
@@ -76317,7 +76090,7 @@ var App = () => {
76317
76090
  isolateOnly(tagOnly, tagId) ?? void 0
76318
76091
  )
76319
76092
  });
76320
- const knownIdentities = (0, import_react62.useMemo)(() => {
76093
+ const knownIdentities = (0, import_react60.useMemo)(() => {
76321
76094
  const people = /* @__PURE__ */ new Map();
76322
76095
  for (const person of [...state?.contributors ?? [], ...contributors]) {
76323
76096
  if (!people.has(person.id)) people.set(person.id, person);
@@ -76330,7 +76103,7 @@ var App = () => {
76330
76103
  actor: users
76331
76104
  };
76332
76105
  }, [state?.tags, state?.contributors, contributors]);
76333
- const { visibleSwimlanes, hiddenIssueCount } = (0, import_react62.useMemo)(() => {
76106
+ const { visibleSwimlanes, hiddenIssueCount } = (0, import_react60.useMemo)(() => {
76334
76107
  const swimlanes = selectedBoard?.swimlanes ?? [];
76335
76108
  const query = textFilter.trim();
76336
76109
  if (boardFilter.length === 0 && !query && windowIds === null && !isolatedIssueId)
@@ -76366,7 +76139,6 @@ var App = () => {
76366
76139
  const onSocketMessage = (message, socket) => {
76367
76140
  onIssueDetailMessage(message);
76368
76141
  onSwimlaneStatsMessage(message);
76369
- onStayTrendsMessage(message);
76370
76142
  if (message.type === "state" && !socket.holdsState()) {
76371
76143
  const nextState = getResultValue(message.payload);
76372
76144
  if (nextState) {
@@ -76475,13 +76247,13 @@ var App = () => {
76475
76247
  }
76476
76248
  };
76477
76249
  socketMessageRef.current = onSocketMessage;
76478
- (0, import_react62.useEffect)(() => {
76250
+ (0, import_react60.useEffect)(() => {
76479
76251
  const first = state?.boards?.[0];
76480
76252
  if (!boardId && first) {
76481
76253
  void navigate(`/board/${first.ref}`, { replace: true });
76482
76254
  }
76483
76255
  }, [boardId, state, navigate]);
76484
- (0, import_react62.useEffect)(() => {
76256
+ (0, import_react60.useEffect)(() => {
76485
76257
  const close = (event) => {
76486
76258
  if (boardMenuRef.current && !boardMenuRef.current.contains(event.target)) {
76487
76259
  setBoardMenuOpen(false);
@@ -76500,8 +76272,8 @@ var App = () => {
76500
76272
  );
76501
76273
  };
76502
76274
  const clearPicked = () => setPickedIssueIds([]);
76503
- const [bulkTagName, setBulkTagName] = (0, import_react62.useState)("");
76504
- const [bulkAssigneeName, setBulkAssigneeName] = (0, import_react62.useState)("");
76275
+ const [bulkTagName, setBulkTagName] = (0, import_react60.useState)("");
76276
+ const [bulkAssigneeName, setBulkAssigneeName] = (0, import_react60.useState)("");
76505
76277
  const pickedIssues = (state?.boards ?? []).flatMap((board) => board.swimlanes).flatMap((swimlane) => swimlane.issues).filter((issue) => pickedIssueIds.includes(issue.id));
76506
76278
  const forPicked = (act) => {
76507
76279
  for (const issue of pickedIssues) act(issue.id);
@@ -76522,7 +76294,7 @@ var App = () => {
76522
76294
  closeIssueDetails();
76523
76295
  setStatsSwimlaneId((current) => current === swimlaneId ? null : swimlaneId);
76524
76296
  };
76525
- const knownTicketRefs = (0, import_react62.useMemo)(
76297
+ const knownTicketRefs = (0, import_react60.useMemo)(
76526
76298
  () => new Set(
76527
76299
  (state?.boards ?? []).flatMap(
76528
76300
  (board) => board.swimlanes.flatMap(
@@ -76532,7 +76304,7 @@ var App = () => {
76532
76304
  ),
76533
76305
  [state]
76534
76306
  );
76535
- const ticketRefLinks = (0, import_react62.useMemo)(
76307
+ const ticketRefLinks = (0, import_react60.useMemo)(
76536
76308
  () => ({
76537
76309
  isKnownRef: (ref) => knownTicketRefs.has(ref),
76538
76310
  // findIssue resolves a ref across every board, so opening by ref works
@@ -76637,8 +76409,8 @@ var App = () => {
76637
76409
  ack: scrubAck,
76638
76410
  onSeek: scrubToTime
76639
76411
  });
76640
- const [historyTick, setHistoryTick] = (0, import_react62.useState)(0);
76641
- (0, import_react62.useEffect)(() => {
76412
+ const [historyTick, setHistoryTick] = (0, import_react60.useState)(0);
76413
+ (0, import_react60.useEffect)(() => {
76642
76414
  if (theatre) return;
76643
76415
  const bump = () => setHistoryTick((tick) => tick + 1);
76644
76416
  if (selection.windowOnly) {
@@ -76661,10 +76433,10 @@ var App = () => {
76661
76433
  playheadTime: playback.current?.t ?? null,
76662
76434
  timeTravel: state?.timeTravel
76663
76435
  });
76664
- (0, import_react62.useEffect)(() => {
76436
+ (0, import_react60.useEffect)(() => {
76665
76437
  if (!connected) setTheatre(null);
76666
76438
  }, [connected]);
76667
- const requestBoardHistory = (0, import_react62.useCallback)(
76439
+ const requestBoardHistory = (0, import_react60.useCallback)(
76668
76440
  (start2, end, allBoards) => {
76669
76441
  const window2 = start2 !== void 0 ? { start: start2, end } : void 0;
76670
76442
  const requestId = historyBuffer.open();
@@ -76684,17 +76456,17 @@ var App = () => {
76684
76456
  },
76685
76457
  [selectedBoardId]
76686
76458
  );
76687
- const requestContributors = (0, import_react62.useCallback)(() => {
76459
+ const requestContributors = (0, import_react60.useCallback)(() => {
76688
76460
  sendRaw({
76689
76461
  type: "contributors:get",
76690
76462
  payload: { boardId: selectedBoardIdRef.current }
76691
76463
  });
76692
76464
  }, []);
76693
- (0, import_react62.useEffect)(() => {
76465
+ (0, import_react60.useEffect)(() => {
76694
76466
  setContributors([]);
76695
76467
  setPickedIssueIds([]);
76696
76468
  }, [selectedBoardId]);
76697
- const openCommitDiff = (0, import_react62.useCallback)(
76469
+ const openCommitDiff = (0, import_react60.useCallback)(
76698
76470
  (sha) => {
76699
76471
  const subject = history.commits.find((commit) => commit.sha === sha)?.subject ?? "";
76700
76472
  const ref = commitTicketRef(subject, knownTicketRefs);
@@ -76713,16 +76485,16 @@ var App = () => {
76713
76485
  },
76714
76486
  [history.commits, knownTicketRefs, boardSlug, navigate]
76715
76487
  );
76716
- const closeCommitDiff = (0, import_react62.useCallback)(() => setCommitDiff(null), []);
76717
- (0, import_react62.useEffect)(() => {
76488
+ const closeCommitDiff = (0, import_react60.useCallback)(() => setCommitDiff(null), []);
76489
+ (0, import_react60.useEffect)(() => {
76718
76490
  setCommitDiff(null);
76719
76491
  }, [boardId, issueId]);
76720
- (0, import_react62.useEffect)(() => {
76492
+ (0, import_react60.useEffect)(() => {
76721
76493
  if (!removeError) return;
76722
76494
  const timeout = setTimeout(() => setRemoveError(null), 8e3);
76723
76495
  return () => clearTimeout(timeout);
76724
76496
  }, [removeError]);
76725
- (0, import_react62.useEffect)(() => {
76497
+ (0, import_react60.useEffect)(() => {
76726
76498
  if (!actionError) return;
76727
76499
  const timeout = setTimeout(() => setActionError(null), 8e3);
76728
76500
  return () => clearTimeout(timeout);
@@ -76760,7 +76532,7 @@ var App = () => {
76760
76532
  submitRenameSwimlane,
76761
76533
  confirmDeleteSwimlane
76762
76534
  } = useSwimlaneEditing({ send, setState, selectedBoard, visibleSwimlanes });
76763
- const searchableTickets = (0, import_react62.useMemo)(
76535
+ const searchableTickets = (0, import_react60.useMemo)(
76764
76536
  () => (state?.boards ?? []).flatMap(
76765
76537
  (board) => board.swimlanes.flatMap(
76766
76538
  (swimlane) => swimlane.issues.map((issue) => ({
@@ -76776,7 +76548,7 @@ var App = () => {
76776
76548
  );
76777
76549
  const commandPalette = useCommandPalette();
76778
76550
  const recentCommands = useRecentCommands();
76779
- const commands = (0, import_react62.useMemo)(() => buildCommandRegistry(), []);
76551
+ const commands = (0, import_react60.useMemo)(() => buildCommandRegistry(), []);
76780
76552
  const commandContext = {
76781
76553
  connected,
76782
76554
  scrubbing: state?.timeTravel?.mode === "scrub",
@@ -76810,7 +76582,7 @@ var App = () => {
76810
76582
  }
76811
76583
  };
76812
76584
  const offline = !connected && state !== null;
76813
- const shownSwimlanes = (0, import_react62.useMemo)(
76585
+ const shownSwimlanes = (0, import_react60.useMemo)(
76814
76586
  () => offline ? visibleSwimlanes.map((swimlane) => ({
76815
76587
  ...swimlane,
76816
76588
  readonly: true,
@@ -76863,7 +76635,7 @@ var App = () => {
76863
76635
  });
76864
76636
  };
76865
76637
  if (noProject) {
76866
- return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76638
+ return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
76867
76639
  InitProjectScreen,
76868
76640
  {
76869
76641
  repoRoot: noProject.repoRoot,
@@ -76874,7 +76646,7 @@ var App = () => {
76874
76646
  }
76875
76647
  );
76876
76648
  }
76877
- return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(TicketRefLinksProvider, { value: ticketRefLinks, children: /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
76649
+ return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(TicketRefLinksProvider, { value: ticketRefLinks, children: /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
76878
76650
  "div",
76879
76651
  {
76880
76652
  style: {
@@ -76886,23 +76658,23 @@ var App = () => {
76886
76658
  flexDirection: "column"
76887
76659
  },
76888
76660
  children: [
76889
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(GlobalScrollbarStyles, {}),
76890
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(TooltipLayer, {}),
76891
- removeError && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76661
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(GlobalScrollbarStyles, {}),
76662
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(TooltipLayer, {}),
76663
+ removeError && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
76892
76664
  ErrorToast,
76893
76665
  {
76894
76666
  message: removeError,
76895
76667
  onDismiss: () => setRemoveError(null)
76896
76668
  }
76897
76669
  ),
76898
- actionError && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76670
+ actionError && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
76899
76671
  ErrorToast,
76900
76672
  {
76901
76673
  message: actionError,
76902
76674
  onDismiss: () => setActionError(null)
76903
76675
  }
76904
76676
  ),
76905
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { style: theatre ? DIMMED_WHILE_PLAYING : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76677
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { style: theatre ? DIMMED_WHILE_PLAYING : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
76906
76678
  Header,
76907
76679
  {
76908
76680
  state,
@@ -76913,7 +76685,7 @@ var App = () => {
76913
76685
  onOpenCommands: () => commandPalette.setOpen(true)
76914
76686
  }
76915
76687
  ) }),
76916
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76688
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
76917
76689
  TimeScrubber,
76918
76690
  {
76919
76691
  timeline: history.timeline,
@@ -76943,7 +76715,7 @@ var App = () => {
76943
76715
  refreshOn: historyTick
76944
76716
  }
76945
76717
  ),
76946
- /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
76718
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
76947
76719
  "div",
76948
76720
  {
76949
76721
  style: {
@@ -76957,7 +76729,7 @@ var App = () => {
76957
76729
  transition: "opacity 160ms ease"
76958
76730
  },
76959
76731
  children: [
76960
- /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
76732
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
76961
76733
  "div",
76962
76734
  {
76963
76735
  style: {
@@ -76968,7 +76740,7 @@ var App = () => {
76968
76740
  overflow: "hidden"
76969
76741
  },
76970
76742
  children: [
76971
- logOpen && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76743
+ logOpen && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
76972
76744
  EventLog,
76973
76745
  {
76974
76746
  entries: logEntries,
@@ -76977,7 +76749,7 @@ var App = () => {
76977
76749
  onOpen: openLogDestination
76978
76750
  }
76979
76751
  ),
76980
- /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
76752
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
76981
76753
  "main",
76982
76754
  {
76983
76755
  onClick: () => {
@@ -76996,7 +76768,7 @@ var App = () => {
76996
76768
  overflow: "hidden"
76997
76769
  },
76998
76770
  children: [
76999
- /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
76771
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
77000
76772
  "div",
77001
76773
  {
77002
76774
  style: {
@@ -77007,7 +76779,7 @@ var App = () => {
77007
76779
  ...theatre ? DIMMED_WHILE_PLAYING : {}
77008
76780
  },
77009
76781
  children: [
77010
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76782
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77011
76783
  Dropdown,
77012
76784
  {
77013
76785
  testId: "board-switcher",
@@ -77024,7 +76796,7 @@ var App = () => {
77024
76796
  onSelect: selectBoard
77025
76797
  }
77026
76798
  ),
77027
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76799
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77028
76800
  Input,
77029
76801
  {
77030
76802
  "data-testid": "text-filter",
@@ -77055,7 +76827,7 @@ var App = () => {
77055
76827
  ]
77056
76828
  }
77057
76829
  ),
77058
- /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(
76830
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
77059
76831
  "div",
77060
76832
  {
77061
76833
  style: {
@@ -77077,13 +76849,12 @@ var App = () => {
77077
76849
  transition: "padding-bottom 240ms ease"
77078
76850
  },
77079
76851
  children: [
77080
- shownSwimlanes.map((swimlane) => /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76852
+ shownSwimlanes.map((swimlane) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77081
76853
  SwimlaneColumn,
77082
76854
  {
77083
76855
  swimlane,
77084
76856
  live: state?.timeTravel?.mode !== "scrub",
77085
76857
  statsOpen: statsSwimlaneId === swimlane.id,
77086
- trend: stayTrends[swimlane.id] ?? [],
77087
76858
  onOpenStats: openSwimlaneStats,
77088
76859
  selected: false,
77089
76860
  selectedIssueId: selectedIssue?.id ?? null,
@@ -77121,19 +76892,19 @@ var App = () => {
77121
76892
  },
77122
76893
  swimlane.id
77123
76894
  )),
77124
- selectedBoard && !selectedBoard.readonly && !offline && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76895
+ selectedBoard && !selectedBoard.readonly && !offline && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77125
76896
  AddSwimlaneColumn,
77126
76897
  {
77127
76898
  onClick: () => setCreateSwimlaneTitle("")
77128
76899
  }
77129
76900
  ),
77130
- asideDock === "right" && (theatre || !commitDiff && !(selectedIssue && state?.user)) && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76901
+ asideDock === "right" && (theatre || !commitDiff && !(selectedIssue && state?.user)) && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77131
76902
  "div",
77132
76903
  {
77133
76904
  style: { width: readStoredAsideWidth(), flexShrink: 0 }
77134
76905
  }
77135
76906
  ),
77136
- /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("div", { style: { width: BOARD_GUTTER, flexShrink: 0 } })
76907
+ /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { style: { width: BOARD_GUTTER, flexShrink: 0 } })
77137
76908
  ]
77138
76909
  }
77139
76910
  )
@@ -77143,7 +76914,7 @@ var App = () => {
77143
76914
  ]
77144
76915
  }
77145
76916
  ),
77146
- !theatre && commitDiff && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(Aside, { dock: asideDock, onWidthChange: setCommitDiffPanelWidth, children: ({ isFullscreen, toggleFullscreen }) => /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76917
+ !theatre && commitDiff && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(Aside, { dock: asideDock, onWidthChange: setCommitDiffPanelWidth, children: ({ isFullscreen, toggleFullscreen }) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77147
76918
  DiffPanel,
77148
76919
  {
77149
76920
  sha: commitDiff.sha,
@@ -77158,7 +76929,7 @@ var App = () => {
77158
76929
  onDock: setAsideDock
77159
76930
  }
77160
76931
  ) }),
77161
- !theatre && !commitDiff && statsSwimlane && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76932
+ !theatre && !commitDiff && statsSwimlane && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77162
76933
  SwimlaneStats,
77163
76934
  {
77164
76935
  dock: asideDock,
@@ -77167,7 +76938,7 @@ var App = () => {
77167
76938
  onClose: () => setStatsSwimlaneId(null)
77168
76939
  }
77169
76940
  ),
77170
- !theatre && !commitDiff && !statsSwimlane && pickedIssues.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76941
+ !theatre && !commitDiff && !statsSwimlane && pickedIssues.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77171
76942
  BulkDetails,
77172
76943
  {
77173
76944
  dock: asideDock,
@@ -77200,7 +76971,7 @@ var App = () => {
77200
76971
  onClear: clearPicked
77201
76972
  }
77202
76973
  ),
77203
- !theatre && !commitDiff && !statsSwimlane && pickedIssues.length <= 1 && selectedIssue && state?.user && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
76974
+ !theatre && !commitDiff && !statsSwimlane && pickedIssues.length <= 1 && selectedIssue && state?.user && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77204
76975
  IssueDetails,
77205
76976
  {
77206
76977
  dock: asideDock,
@@ -77256,7 +77027,7 @@ var App = () => {
77256
77027
  ]
77257
77028
  }
77258
77029
  ),
77259
- theatre && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
77030
+ theatre && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77260
77031
  TheatrePlayer,
77261
77032
  {
77262
77033
  plan: theatre,
@@ -77264,7 +77035,7 @@ var App = () => {
77264
77035
  onExit: exitTheatre
77265
77036
  }
77266
77037
  ),
77267
- createIssueModal && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
77038
+ createIssueModal && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77268
77039
  CreateNodeModal,
77269
77040
  {
77270
77041
  eyebrow: "New issue",
@@ -77276,7 +77047,7 @@ var App = () => {
77276
77047
  onClose: () => setCreateIssueModal(null)
77277
77048
  }
77278
77049
  ),
77279
- renameSwimlane && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
77050
+ renameSwimlane && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77280
77051
  CreateNodeModal,
77281
77052
  {
77282
77053
  eyebrow: "Rename swimlane",
@@ -77289,7 +77060,7 @@ var App = () => {
77289
77060
  onClose: () => setRenameSwimlane(null)
77290
77061
  }
77291
77062
  ),
77292
- deletingSwimlane && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
77063
+ deletingSwimlane && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77293
77064
  ConfirmModal,
77294
77065
  {
77295
77066
  eyebrow: "Delete swimlane",
@@ -77300,7 +77071,7 @@ var App = () => {
77300
77071
  onClose: () => setDeleteSwimlaneId(null)
77301
77072
  }
77302
77073
  ),
77303
- createSwimlaneTitle !== null && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
77074
+ createSwimlaneTitle !== null && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77304
77075
  CreateNodeModal,
77305
77076
  {
77306
77077
  eyebrow: "New swimlane",
@@ -77312,7 +77083,7 @@ var App = () => {
77312
77083
  onClose: () => setCreateSwimlaneTitle(null)
77313
77084
  }
77314
77085
  ),
77315
- commandPalette.open && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
77086
+ commandPalette.open && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
77316
77087
  CommandPalette,
77317
77088
  {
77318
77089
  commands,
@@ -77328,12 +77099,12 @@ var App = () => {
77328
77099
  };
77329
77100
 
77330
77101
  // source/gui/client/main.tsx
77331
- var import_jsx_runtime94 = __toESM(require_jsx_runtime(), 1);
77102
+ var import_jsx_runtime93 = __toESM(require_jsx_runtime(), 1);
77332
77103
  (0, import_client.createRoot)(document.getElementById("root")).render(
77333
- /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(BrowserRouter, { children: /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)(Routes, { children: [
77334
- /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(App, {}) }),
77335
- /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(Route, { path: "/board/:boardId/*", element: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(App, {}) }),
77336
- /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(Navigate, { to: "/", replace: true }) })
77104
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(BrowserRouter, { children: /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)(Routes, { children: [
77105
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(Route, { path: "/", element: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(App, {}) }),
77106
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(Route, { path: "/board/:boardId/*", element: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(App, {}) }),
77107
+ /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(Route, { path: "*", element: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(Navigate, { to: "/", replace: true }) })
77337
77108
  ] }) })
77338
77109
  );
77339
77110
  /*! Bundled license information: